微信搜索lxw1234bigdata | 邀请体验:数阅–数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

HDFS-HA集群中客户端如何找到Active NameNode

Hadoop lxw1234@qq.com 19765℃ 0评论

Hadoop2.0中,HDFS实现了HA,具体实现及原理请网上搜索。其中HDFS的配置包含以下几个必须参数:

<property>
<name>dfs.nameservices</name>
<value>cdh5</value>
<description>指定HDFS的命名服务,一般和fs.defaultFS中的authority一致。</description>
</property>

<property>
<name>dfs.ha.namenodes.cdh5</name>
<value>nn1,nn2</value>
<description>指定HDFS集群中的NameNode(ID)。</description>
</property>

<property>
<name>dfs.namenode.rpc-address.cdh5.nn1</name>
<value>hadoop10:9000</value>
<description>第一个NameNode ID对应的host和端口号</description>
</property>

<property>
<name>dfs.namenode.rpc-address.cdh5.nn2</name>
<value>hadoop20:9000</value>
<description>第二个NameNode ID对应的host和端口号</description>
</property>

之前觉得当客户端需要连接NN时候,会从ZK中获取到处于Active状态的NN进行连接,但最近在做调试的时候发现并非如此,无论哪个NN处于Active状态,客户端总是先尝试连接nn2,当nn2处于Standby状态时候,便会抛出下面的错误:
Operation category READ is not supported in state standby. Visit https://s.apache.org/sbnn-error
错误原因很明显,就是尝试连接standby状态的nn进行数据读取。
尝试连接失败之后,接着才去连接nn1,成功。
问题是,明明我的Active NN是nn1,为何先要去连一下nn2?

通过网上搜索,找到了原因《HA集群中如何判断ActiveNN》。

http://jxy.me/2015/04/09/hadoop-ha-active-nn/

原来,客户端并不是连接到ZK去获取Active NN的,而是去尝试上面配置的两个NN。
既然是尝试所有NN,那么就有顺序的问题,上面的文章中通过分析源码找到的最终的答案,就是把nn1和nn2的host和端口放入HashMap,然后通过values()方法拿到一个”顺序”的NN来依次尝试。

类似下面的代码:

HashMap<String, String> map = new HashMap<String, String>();
map.put(“nn2″, “hadoop20:9000″);
map.put(“nn1″, “hadoop10:9000″);
for (String x : map.values()) {
System.out.println(x);
}

而HashMap的values()方法,是不保证顺序的,但经过尝试,上面的代码,在java7中运行,输出的顺序总是”hadoop10:9000,hadoop20:9000”,而在java8中运行,输出的顺序总是” hadoop20:9000, hadoop10:9000”,我的环境中使用了java8,因此一直是先尝试连接nn2.

这种寻找Active NN的策略,是通过参数dfs.client.failover.proxy.provider. [nameservice ID]
配置的,默认为:org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider

比较合适的做法,其实是自己实现一个代理类,去ZK中获取Active状态的NN,然后配置在这个参数值中。这个后续再研究。

如果觉得本博客对您有帮助,请 赞助作者

转载请注明:lxw的大数据田地 » HDFS-HA集群中客户端如何找到Active NameNode

喜欢 (27)
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址