namenode ha

zzwlnbp8  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(336)

使用hdfs或hftp uri方案(例如。 hdfs://namenode/path/to/file )我可以访问hdfs集群,而不需要它们的xml配置文件。它在运行shell命令时非常方便,比如 hdfs dfs -get , hadoop distcp 或者从spark那里读取文件 sc.hadoopFile() ,因为我不必将所有相关hdfs集群的xml文件复制和管理到这些代码可能运行的所有节点。
这种方法的一个缺点是我必须使用活动namenode的主机名,否则hadoop会抛出一个异常,抱怨nn是备用的。
通常的解决方法是,如果捕获到任何异常,先尝试一个,然后再尝试另一个,或者直接连接到zookeeper并使用protobuf解析二进制数据。
这两种方法都很麻烦,例如,与mysql的loadbalance uri或zookeeper的连接字符串相比,我只需用逗号分隔uri中的所有主机,驱动程序就会自动找到一个节点进行对话。
假设我有活动和备用namenode主机 nn1 以及 nn2 . 引用hdfs特定路径的最简单方法是什么,即:
可以在命令行工具中使用,如 hdfs , hadoop 可以在hadoopjavaapi中使用(因此也可以使用spark等依赖于它的工具),只需最少的配置
无论哪个namenode当前处于活动状态,都可以工作。

toiithl6

toiithl61#

在这种情况下,我们应该使用nameservice,而不是检查活动namenode主机和端口组合,nameservice将自动将客户端请求传输到活动namenode。
名称服务就像namenodes之间的代理,它总是将hdfs请求转移到活动namenode
例子: hdfs://nameservice_id/file/path/in/hdfs ###创建nameservice的示例步骤
在hdfs-site.xml文件中
通过添加一个id来创建nameservice(这里nameservice\u id是mycluster)

<property>
  <name>dfs.nameservices</name>
  <value>mycluster</value>
  <description>Logical name for this new nameservice</description>
</property>

现在指定namenode id来确定集群中的namenodes
dfs.ha.namenodes。[$nameservice id]:

<property>
  <name>dfs.ha.namenodes.mycluster</name>
  <value>nn1,nn2</value>
  <description>Unique identifiers for each NameNode in the nameservice</description>
</property>

然后将namenode id与namenode主机链接
dfs.namenode.rpc地址。[$nameservice id].[$name node id]

<property>
  <name>dfs.namenode.rpc-address.mycluster.nn1</name>
  <value>machine1.example.com:8020</value>
</property>
<property>
  <name>dfs.namenode.rpc-address.mycluster.nn2</name>
  <value>machine2.example.com:8020</value>
</property>

要用nameservice正确配置namenodeha,需要用到很多属性
使用此设置,文件的hdfs url如下所示

hdfs://mycluster/file/location/in/hdfs/wo/namenode/host

编辑:

在java代码中应用属性

Configuration conf = new Configuration(false);
conf.set("dfs.nameservices","mycluster");
conf.set("dfs.ha.namenodes.mycluster","nn1,nn2");
conf.set("dfs.namenode.rpc-address.mycluster.nn1","machine1.example.com:8020");
conf.set("dfs.namenode.rpc-address.mycluster.nn2","machine2.example.com:8020");

FileSystem fsObj =  FileSystem.get("relative/path/of/file/or/dir", conf);

// now use fsObj to perform HDFS shell like operations
fsObj ...

相关问题