序言
随着时间的推移,海量的数据都被积累起来,人人都是数据的产生者,产生各种各样的结构化数据,半结构化数据,非结构化数据,原来的关系型数据库搭建的数仓已经不能满足需求了,从而可以使用分布式存储hdfs来进行存储海量的数据。
hdfs为hadoop distributed filesystem,是分布式文件系统,用来存储海量的数据。
hdfs
整体集群的规划如下图所示:
在测试环境中,只要使用三台虚拟机就可以搭建一个高可用的hdfs集群,将各种组件进行混部即可(namenode占用内存较多,datanode主要磁盘容量要大)。
此处的高可用集群,主要是有两个namenode节点,一个是active状态,一个则是standby状态,也就是随时热备的形式。
对于namenode本身来说,主要是用来保存相关的元数据信息,为了保证性能,从而将metadata的数据保存在内存中,对于数据的快照是使用fsimage来进行保存,这个时候可能是重启了namenode进程,从而对edit的数据和fsimage进行了一次合并,而对于内存中的数据操作则是已追加的形式保存在editlog中(下图中表示edits的文件以81后缀为最新的edit文件)。
zk集群本身是高可用模式,主要的作用是提供分布式协调服务,用来监控主备namenode是否挂掉,当挂掉之后,会有standby的机器DFSZKFailoverControl使用ssh登录到相应的namenode机器上杀掉namenode进程,从而在安装namenode的机器上也要进行部署DFSZKFailoverControl服务,而没有的机器上则不部署。
对于原active的zkfc进程来说,主要是不停的探测namenode的端口是否存在。
对于journal集群来说,主要是为了保证edit文件的一致性,active的namenode写入edit,而standby的namenode则来进行同步edit文件,从而保证两者数据的最终一致性。当刚启动namenode来说,会进行同步相关的edit数据,在web界面上可以看到如下信息:
从界面上也可以看到同步了哪些信息,如下所示:
搭建的是高可用集群,关闭一个数据节点会出现如下情况:
可以查看到具体的datanode的信息:
当初始化zk连接的时候,可能出现如下错误:
hdfs zkfc -formatZK
21/02/09 20:13:16 INFO tools.DFSZKFailoverController:
Failover controller configured for NameNode
NameNode at KEL/192.168.1.10:9000
21/02/09 20:13:16 FATAL ha.ZKFailoverController:
Automatic failover is not enabled for NameNode at
KEL/192.168.1.10:9000. Please ensure that automatic
failover is enabled in the configuration before
running the ZK failover controller.
需要检查配置文件如下选项:
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
看看是不是true写成了ture,报错很明显,但是没有具体的配置项
在进行测试namenode高可用的时候,可能出现切换不成功,只有等待关闭的namenode启动才会切换,日志报错如下:
2021-02-09 21:31:22,878 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Next authentication method: publickey
2021-02-09 21:31:22,892 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Authentication succeeded (publickey).
2021-02-09 21:31:22,892 INFO org.apache.hadoop.ha.SshFenceByTcpPort: Connected to KEL1
2021-02-09 21:31:22,892 INFO org.apache.hadoop.ha.SshFenceByTcpPort: Looking for process running on port 9000
2021-02-09 21:31:22,974 WARN org.apache.hadoop.ha.SshFenceByTcpPort: PATH=$PATH:/sbin:/usr/sbin fuser -v -k -n tcp 9000 via ssh: bash: fuser: command not found
2021-02-09 21:31:22,974 INFO org.apache.hadoop.ha.SshFenceByTcpPort: rc: 127
2021-02-09 21:31:22,974 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Disconnecting from KEL1 port 22
2021-02-09 21:31:22,974 WARN org.apache.hadoop.ha.NodeFencer: Fencing method org.apache.hadoop.ha.SshFenceByTcpPort(null) was unsuccessful.
2021-02-09 21:31:22,974 ERROR org.apache.hadoop.ha.NodeFencer: Unable to fence service by any configured method.
2021-02-09 21:31:22,974 WARN org.apache.hadoop.ha.ActiveStandbyElector: Exception handling the winning of election
java.lang.RuntimeException: Unable to fence NameNode at KEL1/192.168.1.99:9000
at org.apache.hadoop.ha.ZKFailoverController.doFence(ZKFailoverController.java:533)
at org.apache.hadoop.ha.ZKFailoverController.fenceOldActive(ZKFailoverController.java:505)
at org.apache.hadoop.ha.ZKFailoverController.access$1100(ZKFailoverController.java:61)
at org.apache.hadoop.ha.ZKFailoverController$ElectorCallbacks.fenceOldActive(ZKFailoverController.java:892)
at org.apache.hadoop.ha.ActiveStandbyElector.fenceOldActive(ActiveStandbyElector.java:910)
at org.apache.hadoop.ha.ActiveStandbyElector.becomeActive(ActiveStandbyElector.java:809)
at org.apache.hadoop.ha.ActiveStandbyElector.processResult(ActiveStandbyElector.java:418)
at org.apache.zookeeper.ClientCnxn$EventThread.processEvent(ClientCnxn.java:599)
at org.apache.zookeeper.ClientCnxn$EventThread.run(ClientCnxn.java:498)
2021-02-09 21:31:22,974 INFO org.apache.hadoop.ha.ActiveStandbyElector: Trying to re-establish ZK session
2021-02-09 21:31:22,975 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Caught an exception, leaving main loop due to Socket closed
2021-02-09 21:31:22,982 INFO org.apache.zookeeper.ZooKeeper: Session: 0x10003a70835005e closed
主要看上面的报错信息:
ssh: bash: fuser: command not found
需要安装如下一个依赖包psmisc。
[root@KEL logs]# yum install psmisc -y
当界面上出现datanode的信息和实际不符合的时候,如下:
需要检查主机名称是否设置,是否和slaves的内容相同(可能会忘记设置主机名称)。
[root@KEL hadoop]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.10 KEL
192.168.1.99 KEL1
192.168.1.199 KEL2
[root@KEL hadoop]# cat slaves
KEL
KEL1
KEL2
当出现web端口访问不通的时候,查看防火墙是否关闭。
[root@KEL hadoop]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Tue 2021-02-09 02:02:06 CST; 1 day 3h ago
Process: 865 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
Main PID: 865 (code=exited, status=0/SUCCESS)
Feb 09 02:01:18 KEL systemd[1]: Starting firewalld - dynamic firewall daemon...
Feb 09 02:01:18 KEL systemd[1]: Started firewalld - dynamic firewall daemon.
Feb 09 02:02:06 KEL systemd[1]: Stopping firewalld - dynamic firewall daemon...
Feb 09 02:02:06 KEL systemd[1]: Stopped firewalld - dynamic firewall daemon.
[root@KEL hadoop]# systemctl disable firewalld
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
由于zkfs需要互相登录进行检测namenode进程,从而需要互相配置免密登录。
[root@KEL2 hadoop-2.7.2]# ssh-keygen
[root@KEL2 hadoop-2.7.2]# ssh-copy-id kel
当启动namenode和datanode的时候,发现只能存在一个进程,那么表示两者使用的集群id不同,可能是多次格式化了namenode,导致集群号发生了变化。
[root@KEL dfs]# cat data/current/VERSION
#Wed Feb 10 05:35:53 CST 2021
storageID=DS-ff23d5a7-fe98-404b-a5b9-5d449e3b31d2
clusterID=CID-073cc3af-78f6-4716-993b-92a0b398291a
cTime=0
datanodeUuid=1d523f5f-200f-4597-8388-3fbfe50e448a
storageType=DATA_NODE
layoutVersion=-56
[root@KEL dfs]# cat name/current/VERSION
#Tue Feb 09 20:32:36 CST 2021
namespaceID=325659150
clusterID=CID-073cc3af-78f6-4716-993b-92a0b398291a
cTime=0
storageType=NAME_NODE
blockpoolID=BP-184102405-192.168.1.10-1612873956948
layoutVersion=-63
[root@KEL dfs]# pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs
检查clusterID是否相同,否则删除相应的目录,重新进行格式化启动。
规划之后的相关的分布如下:
zk的配置文件如下:
[root@KEL1 zkdata]# ./../bin/zkServer.sh status /opt/module/zookeeper-3.4.12/zkdata/zoo.cfg
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.12/zkdata/zoo.cfg
Mode: leader
[root@KEL1 zkdata]# cat zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/module/zookeeper-3.4.12/zkdata
clientPort=4001
server.1=KEL:3002:3003
server.2=KEL1:4002:4003
server.3=KEL2:5002:5003
[root@KEL1 zkdata]# cat myid
2
[root@KEL1 zkdata]# cat zookeeper_server.pid
9241[root@KEL1 zkdata]# netstat -ntlp|grep 9241
tcp6 0 0 :::54106 :::* LISTEN 9241/java
tcp6 0 0 :::4001 :::* LISTEN 9241/java
tcp6 0 0 192.168.1.99:4002 :::* LISTEN 9241/java
tcp6 0 0 192.168.1.99:4003 :::* LISTEN 9241/java
4002表示为同步数据的端口,只有leader这个角色才会监听这个端口
hdfs的core-site.xml的配置文件:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>KEL:3001,KEL1:4001,KEL2:5001</value>
</property>
</configuration>
hdfs的hdfs-site.xml配置文件:
<configuration>
<property>
<name>dfs.nameservices</name>
<value>ns</value>
</property>
<property>
<name>dfs.ha.namenodes.ns</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns.nn1</name>
<value>KEL:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns.nn1</name>
<value>KEL:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns.nn2</name>
<value>KEL1:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.ns.nn2</name>
<value>KEL1:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://KEL:8485;KEL1:8485;KEL2:8485/ns</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/module/hadoop-2.7.2/journal</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.ns</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
</configuration>
参数参考链接:
https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html