JAVA API连接HA(High Available) Hadoop集群

使用JAVA API连接HDFS时我们需要使用NameNode的地址,开启HA后,两个NameNode可能会主备切换,如果连接的那台主机NameNode挂掉了,连接就会失败. HDFS提供了nameservices的方式进行访问,这样只要有一个NameNode活着,都可以正常访问.

HDFS NameNode HA

在没有HA的环境中,通常使用NameNode hostname访问HDFS的URL.

hdfs://ochadoop111.jcloud.local:8020

为了保证HDFS服务的高可用,生产环境是必须要开启NameNode HA的,此时应该用nameservices作为统一的logical name连接HDFS.

使用Ambari Enable NameNode HA之后,我的集群在ochadoop112.jcloud.local上增加了一个NameNode, HA相关的配置会自动产生.

首先在Ambari UI上查看custom hdfs-site配置. 注意端口号要配成rpc的端口号,而不能是http/https的.

dfs.nameservices=mycluster
dfs.namenode.rpc-address.mycluster.nn1=ochadoop111.jcloud.local:8020
dfs.namenode.rpc-address.mycluster.nn2=ochadoop112.jcloud.local:8020
dfs.ha.namenodes.mycluster=nn1,nn2

使用nameservices访问HDFS的URL:

hdfs://mycluster:8020

JAVA API连接HDFS HA代码如下:

Configuration conf=new Configuration(false);
String nameservices = "mycluster";
String[] namenodesAddr = {"ochadoop111.jcloud.local:8020","ochadoop112.jcloud.local:8020"};
String[] namenodes = {"nn1","nn2"};
conf.set("fs.defaultFS", "hdfs://" + nameservices);
conf.set("dfs.nameservices",nameservices);
conf.set("dfs.ha.namenodes." + nameservices, namenodes[0]+","+namenodes[1]);
conf.set("dfs.namenode.rpc-address." + nameservices + "." + namenodes[0], namenodesAddr[0]);
conf.set("dfs.namenode.rpc-address." + nameservices + "." + namenodes[1], namenodesAddr[1]);
conf.set("dfs.client.failover.proxy.provider." + nameservices,"org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");
String hdfsRPCUrl = "hdfs://" + nameservices + ":" + 8020;
DistributedFileSystem dfs = new DistributedFileSystem();
try {
    dfs.initialize(URI.create(hdfsRPCUrl),conf);
    Path tmpPath2 = new Path("/tmp2");
    dfs.mkdir(tmpPath2,new FsPermission("777"));
    FileStatus[] list = dfs.listStatus(new Path("/"));
    for (FileStatus file : list) {
        System.out.println(file.getPath());
    }
    dfs.setQuota(tmpPath2,100,1000);
} catch (IOException e) {
    e.printStackTrace();
} finally{
    try {
        dfs.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

WebHDFS

通过WebHDFS访问HA集群时,就没有rpc方式那么方便了,有四种解决方法,我觉得第4个方法最简单, YARN的ResourceManager HA我就是按这个思路处理的.

  1. 使用httpfs,这个是CDH的产品,需要额外安装
  2. 使用knox安全网关,这样访问的接口就都被knox统一了
  3. 每次访问之前都从zookeeper中拿当前Active NameNode的地址
  4. 每次访问轮询两个namenode

YARN ResourceManager HA

ResourceManager HA存在与NameNode HA类似的问题,能否通过统一的logical name访问RM的REST API呢? 答案是暂时不支持.

目前YARN只能支持standy RM把请求重定向到Active RM上. 也就是说假如主备RM都活着,当客户端向standby RM发HTTP请求时,standby RM会重定向到active RM上,但是如果standby RM不幸挂掉了,而Active RM还正常工作,此时请求就会失败.

解决方法其实也很简单,就是在调用RM REST API时轮询两个RM.

参考:

JAVA API 访问hadoop HA

你可能感兴趣的:(JAVA API连接HA(High Available) Hadoop集群)