HDFS前世今生之HA(三)

HDFS上路第三篇接着之前的集群部署, 加入核心功能HA(高可用机制), 因为HDFS的主节点状态很多, 所以需要比较复杂的模块来单独实现

0x00. 基本概念

HDFS HA我理解这里面的单故障点就是Master节点(NameNode), 所以我觉得可以直接类似K8s一样, 说Master HA就挺直观了, 当然这里其实也有两个方案, 旧的方案基于NFS(这里先不多说了). 先看使用QJM(Quorum Journal Manager)的正式方案, 这里先说一下一些缩写含义:

  • ZK: 全名Zookeeper, 类似K8s中使用的etcd, 是一个分布式服务感知 + 配置共享的组件. (历史最为悠久/结构复杂)

  • ZKFC: 全名是ZKFailoverController, 它是一个独立进程, 相当于一个ZK客户端, 并且同时具有监控 + 管理Master节点的状态功能, 一般来说每台Master节点都有一个与之唯一对应的ZKFC, 负责和ZK集群通信, 下面是一张简单的”ZK + ZKFC +NN” 结构图:

    hdfsHA000

  • ANN 和 SNN: 就是ActiveNamenode和 StandbyNamenode的缩写, 也就是主和主备, 数据节点同时会跟所有master通信, 一般主接受Client请求然后处理, 并写下操作日志(editLog), 然后发给JN集群. 其他主备节点会去读取同步. (每个NN有一个单独的ID标识)

  • JN: JournalNode, 可以理解为日志节点, 是一个独立的进程, 用来共享管理EditLog, 简单说就是同步多个Master节点间的数据, Master节点读写请求一般需要多数的JN返回成功才认为有效, 一般有3~5个

这是整体来看HDFS-HA后结构图:

hdfsHA01

上面的理解之后, 再就可以看看实际生产环境中, 把”Yarn + HDFS” 同时部署的时候, 整个Hadoop集群HA的结构图(虚线框代表单台机器):

hadoopHA00

到这差不多简单的HA原理和结构就了解了, 但是这还没有涉及任何的细节和衍生的思考, 详细的文章可以参考文尾的2, 3篇文章, 写的挺不错, 后续看到HA相关的我再单独学习.

0x01. 实际部署

JN和ZK一般复用一台节点, 至少取3台, 那我们可以在之前的基础上, 再补充4台机器 (Yarn相关的进程我们就不再启动了, 去掉Manager相关). 当然如果机器不够, 也可以把JN或ZK放在数据节点, 或者和主节点(NN)共用. 为了清晰和符合生产环境, 就采用相对分离的做法.

节点IP 功能(进程) 备注
10.162.94.85 NameNode1, ZKFK 主节点
10.162.94.75 NameNode2, ZKFK 备用主节点
10.162.94.86 DataNode 数据节点1
10.162.94.87 DataNode 数据节点2
10.162.98.38 Zookeeper, JournalNode HA节点1
10.162.98.39 Zookeeper, JournalNode HA节点2
10.162.98.40 Zookeeper, JournalNode HA节点3

A. HDFS配置文件

然后主要是来在原有基础上修改之前的配置文件, 不必要的配置暂时不设置:

  1. core-site.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <property>
    <name>fs.defaultFS</name>
    <!--名字与hdfs.site中的nameservices一致-->
    <value>hdfs://HAcluster</value>
    </property>
    <!--配置ZK地址-->
    <property>
    <name>ha.zookeeper.quorum</name>
    <value>10.162.98.38:2181,10.162.98.39:2181,10.162.98.40:2181</value>
    </property>
  2. hdfs-site.xml (主要)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
      <!--HA-Start--> 
    <property>
    <name>dfs.nameservices</name>
    <!--名字可以随意取, 但是要保证后面配置一致,默认是mycluster-->
    <value>HAcluster</value>
    </property>
    <property>
    <!--HA集群的别名和通信端口-->
    <name>dfs.ha.namenodes.HAcluster</name>
    <value>nn1,nn2</value>
    </property>
    <property>
    <name>dfs.namenode.rpc-address.HAcluster.nn1</name>
    <value>10.162.94.85:8020</value>
    </property>
    <property>
    <name>dfs.namenode.rpc-address.HAcluster.nn2</name>
    <value>10.162.94.75:8020</value>
    </property>
    <property>
    <name>dfs.namenode.http-address.HAcluster.nn1</name>
    <value>10.162.94.85:9870</value>
    </property>
    <property>
    <name>dfs.namenode.http-address.HAcluster.nn2</name>
    <value>10.162.94.75:9870</value>
    </property>


    <property>
    <!--配置3个JN的地址-->
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://10.162.98.38:8485;10.162.98.39:8485;10.162.98.40:8485/HAcluster</value>
    </property>
    <property>
    <name>dfs.client.failover.proxy.provider.HAcluster</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <property>
    <name>dfs.ha.fencing.methods</name>
    <!-- 配置隔离机制,ssh到当前master并杀死它防止脑裂(多主)-->
    <value>sshfence</value>
    </property>
    <property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/home/${user.name}/.ssh/id_rsa</value>
    </property>
    <property>
    <name>dfs.journalnode.edits.dir</name>
    <value>/home/${user.name}/hadoop/journal</value>
    </property>
    <property>
    <name>dfs.ha.automatic-failover.enabled</name>
    <value>true</value>
    2</property>
    <!--HA-End-->

然后把修改后的hadoop3.1.2 包分发到新的Master02机和三台HA机器.

B. Zookeeper

这里主要就是安装启动ZK(3.5.5最新稳定版), 步骤简单, 3步就搞定了 (尽量多用批量分发)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1.下载解压
wget http://apache.claz.org/zookeeper/current/apache-zookeeper-3.5.5-bin.tar.gz && \
tar xzvf apache-zookeeper-3.5.5-bin.tar.gz && rm *.gz

# 2.修改两个配置项
cd apache-zookeeper-3.5.5-bin/conf && mv zoo_sample.cfg zoo.cfg && vi zoo.cfg
# 修改数据地址
dataDir=/data01/zk_test
# 增加HA节点
server.1=10.162.98.38:2888:3888
server.2=10.162.98.39:2888:3888
server.3=10.162.98.40:2888:3888

# 3.设置每个节点对应id
mkdir /data01/zk_test && echo 1 > /data01/zk_test/myid # 其它节点对应2,3

# 每个节点都启动(Xshell批量分发)
~/apache-zookeeper-3.5.5-bin/bin/zkServer.sh start
~/apache-zookeeper-3.5.5-bin/bin/zkServer.sh status # 会发现1个leader,2个follow
# jps里看叫这个名字..
QuorumPeerMain

C. 启动HA

这里我们需要先在三个HA节点启动JN, 然后再新的master备用节点使用standby指令

1
2
3
4
5
6
7
8
9
10
# HA三台机器分别
~/hadoop-3.1.2/bin/hdfs --daemon start journalnode

# master02机器以主备方式启动NN
~/hadoop-3.1.2/bin/hdfs namenode -bootstrapStandby

# 任选一台主节点初始化zkfc
~/hadoop-3.1.2/bin/hdfs zkfc -formatZK
# 每台主启动zkfc与NN对应
~/hadoop-3.1.2/sbin/hadoop-daemon.sh start zkfc

这样如果顺利的话, HDFS的HA就完成了, 其实过程上看起来是比较简单的, 如果分发得当(配置hostname/ssh免密)会更快. 关键还是在于理解HA的结构和背后的考量, 以后再细看了.


参考资料:
  1. HDFS-HA官方文档
  2. IBM-HDFS-HA实现解析
  3. HDFS HA Using QJM原理解析