HADOOP docker(二):HDFS 高可用原理
2.QJM HA简述
2.1为什么要做HDFS HA?
2.2 HDFS HA的方式
2.2 HSFS HA的结构
2.3 机器要求
3.部署HDFS HA
3.1 详细配置
3.2 部署HDFS HA
4. HDFS HA的管理
5.自动切换
5.1 使用zookeeper实现HA原理
5. 部署hdfs自动切换
5.1 关闭集群
5.2 添加HA配置
5.3 在zookeeper中初始化HA状态
5.4 开启集群
5.5 使用zookeeper时的安全机制
6.FAQ
7.做了HA后HDFS的升级、回滚
7.1 升级
7.2 finalize
7.3 回滚
1.环境简述
上从在docker上装完hadoop集群后,发现有很多问题,又重新建了一个,如下:
主机名 | IP | 角色 |
---|---|---|
hadoop1 | 172.18.0.11 | NN1 ZK RM |
hadoop2 | 172.18.0.12 | NN2 ZK RM JOBHISTORY |
hadoop3 | 172.18.0.13 | DN ZK ND |
hadoop4 | 172.18.0.14 | DN QJM1 ND |
hadoop5 | 172.18.0.15 | DN QJM2 ND |
hadoop6 | 172.18.0.16 | DN QJM3 ND |
目前已经安装了hdfs yarn zookeeper
2.QJM HA简述
2.1为什么要做HDFS HA?
在hadoop2.0之前,集群中只能有一个namenode,如果这个namenode宕机或者需要对namenode进行升级,那么整个集群的服务将不可用。因此要做HA。
2.2 HDFS HA的方式
目前支持两种HA方式:
- NFS
namenode和standby namenode共享一个NFS磁盘,所以namenode的元数据变更立即同步到standby中。缺点是如果namenode或者standby namenode与NFS磁盘之间的网络出了问题,HA即失效,即把namenode单独故障转移到了NFS上,NFS同样存在单点故障问题。 - QJM
namenode和standby namenode分别连接到一组Journal节点中,如果namenode出了故障,可以把standby namenode切换到activer状态,不影响集群使用。本方式配合zookeeper可以实现自动切换。
2.2 HSFS HA的结构
以上是QJM HA的典型的结构图。集群中共有两个namenode(简称NN),其中只有一个是active状态,另一个是standby状态。active 的NN负责响应DN(datanode)的请求,为了最快的切换为active状态,standby状态的NN同样也连接到所有的datenode上获取最新的块信息(blockmap)。
active NN会把元数据的修改(edit log)发送到多数的journal节点上(2n+1个journal节点,至少写到n+1个上),standby NN从journal节点上读取edit log,并实时的合并到自己的namespace中。另外standby NN连接所有DN,实时的获取最新的blockmap。这样,一旦active的NN出现故障,standby NN可以立即切换为active NN.
注意:同一时刻只能有一个NAMENODE写edit log,否则将hdfs 元数据将会"脑裂"
2.3 机器要求
- 两个配置完全一样的namenode节点
- 2n+1个 journal节点,journal节点不需要很好的配置,可以与集群中的其它角色一起。
3.部署HDFS HA
3.1 详细配置
HDFS HA中用,nameserivce ID来标识一个HDFS服务,为了标识每个NN,还要加上namenode id。
在hdfs-site.xml中:
1.设置集群的标识dfs.nameservice
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
这里修改为dockercluster
2.设置namenode名称 dfs.ha.namenodes.[nameservice ID]
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
nn1 nn2为namenode的标识。
注意:当前只支持两个namenode的HA
3.设置namenode对外提供服务的RPC地址 dfs.namenode.rpc-address.[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>
这个RPC地址实际就是 dfs.defaultFS地址
4.设置HDFS web页面地址 dfs.namenode.http-address.[nameservice ID].[name node ID]
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>machine1.example.com:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>machine2.example.com:50070</value>
</property>
如果启用的hdfs的安全机制,要设置 https-address
5.设置journal上edit log共享目录 dfs.namenode.shared.edits.dir
格式是:qjournal://host1:port1;host2:port2;host3:port3/journalId 所有节点上路径要保持一致
<property>
<name>dfs.namenode.shared.edits.dir</name><value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster</value>
</property>
这里我们改成: qjournal://hadoop4:8485;hadoop5:8485;hadoop6:8485/dockercluster
6.设置实现集群HA的类 dfs.client.failover.proxy.provider.[nameservice ID]
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
当前仅支持这个类
7.设置切换时执行的程序 dfs.ha.fencing.methods
当namenode发生切换时,原来active的NN可能依然在写edit log,这时如果standby 也开始写edit log,元数据会"脑裂"。为了防止"脑裂",必须要切换之前杀掉原来active 的NN,这个脚本就是实现这个目的。当前支持两中fencing.method:shell 和 sshfence。另外,可能自定义org.apache.hadoop.ha.NodeFence来实现自己的保护程序。
7.1.sshfence(默认)
通过SSH登录到原来active的NN,并使用fuser命令KILL掉NN进程。要使用SSH,必须配置rsa-key参数:dfs.ha.fencing.ssh.private-key-files
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hdfs/.ssh/id_rsa</value>
</property>
也可以用其它用户登录,同样可以配置超时参数:
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence([[username][:port]])</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
7.2.shell
自定义一个shell脚本业杀死NAMENODE
<property>
<name>dfs.ha.fencing.methods</name>
<value>shell(/path/to/my/script.sh arg1 arg2 ...)</value>
</property>
shell脚本可以读取到当前已经配置的HDFS变量,将"."替换为"_" 即可。对于某些共用的条目,如dfs_namenode_rpc-address可以自动的指向特定节点如dfs.namenode.rpc-address.ns1.nn1。以下变量也可以使用:
$target_host |
$target_port |
$target_address |
$target_namenodeid |
示例:
<property>
<name>dfs.ha.fencing.methods</name>
<value>shell(/path/to/my/script.sh --nameservice=$target_nameserviceid $target_host:$target_port)</value>
</property>
如果shell返回0,表示执行成功。如果不为0,则继续执行其它的fencing.method.shell方式没有timeout.
这时里,我们也用ssh方式,比较简单,只需要生成key就行了.在NN1 NN2上执行:
[hdfs@hadoop1 ~]$ ssh-keygen -t rsa
Generatingpublic/private rsa key pair.
Enter file in which to save the key (/home/hdfs/.ssh/id_rsa):
Enter passphrase (empty forno passphrase):
Enter same passphrase again:
Your identification has been saved in/home/hdfs/.ssh/id_rsa.
Yourpublic key has been saved in/home/hdfs/.ssh/id_rsa.pub.
The key fingerprint is:
6b:de:13:b7:55:ba:43:1c:28:ef:2e:b8:b7:0a:e0:15 hdfs@hadoop1
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| E . |
8.在core-site.xml中设置hdfs 服务 fs.defaultFS
一旦使用了HDFS HA,那么fs.defaultFS就不能写成host:port文件,而要写成服务方式,写上nameservice id:
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
这里改成hdfs://dockercluster
9.journal节点守护进程自己的数据目录 dfs.journalnode.edits.dir
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/path/to/journal/node/local/data</value>
</property>
3.2 部署HDFS HA
1.启动所有journal节点hadoop-daemon.sh start journalnode
2.如果是新建的集群,在其中一个NN上执行hdfs format命令hdfs namenode -format
3.如果从非HA集群升级为HA集群,或者是已经执行过hdfs format命令,把已经formatted的NN上的元数据拷贝到没有formatted的NN上,然后在没有formatted的NN上执行hdfs namenode -bootstrapStandby
,该命令会让journal节点做好连接两个namenode的准备。
4.如果将非HA的NN切换为HA,执行hdfs namenode -initializeSharedEdits
将本地的edit log初始化到journal中。
执行完以上后,像平时一样启动每个NN。
在每个NN的web页面中,将会显示NN的状态是active或者standby
————————————————-更改—————————————–
后续更新:
在做实验时发现,官网这个步骤有问题!
正确的步骤是:
1.启动所有journal节点hadoop-daemon.sh start journalnode
2.执行journal 节点初始化hdfs namenode -initializeSharedEdits
3.启动原来的namenode $HADOOP_HOME/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start namenode
4.初始化standby hdfs namenode -bootstrapStandby
,
5.启动standby $HADOOP_HOME/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR --script hdfs start namenode
————————————————-更改—————————————–
.
4. HDFS HA的管理
HDFS HA的管理主要靠hdfs haadmin命令实现:
[hdfs@hadoop1 ~]$ hdfs haadmin
Usage: haadmin
[-transitionToActive [--forceactive]<serviceId>]
[-transitionToStandby <serviceId>]
[-failover [--forcefence][--forceactive]<serviceId><serviceId>]
[-getServiceState <serviceId>]
[-checkHealth <serviceId>]
[-help <command>]
Generic options supported are
-conf <configuration file> specify an application configuration file
-D <property=value>use value for given property
-fs <local|namenode:port> specify a namenode
-jt <local|resourcemanager:port> specify a ResourceManager
-files <comma separated list of files> specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars> specify comma separated jar files to include in the classpath.
-archives <comma separated list of archives> specify comma separated archives to be unarchived on the compute machines.
The general command line syntax is
bin/hadoop command [genericOptions][commandOptions]
- transitionToActive 和 transitionToStandby
切换为active或者standby。注意:不会使用任务fencing措施,因此一般不使用这两个命令,用hdfs haadmin -failover
- failover
对hdfs做一次主备切换。在切换前,如果原来active的NN现在是standby状态,那么会直接把原来standby的NN切换为active状态。如果原来active状态的NN还是acitve状态,则会先将该NN切换为standby状态,如果切换为standby失败,则会调用dfs.ha.fencing.methods
里指定的fencing方式来确保原来的acitve NN被干掉。如果没有定义fencing方式,或者fencing执行失败,则会抛出异常,同时不会切换原来的standby 为acitve - getServiceState
获取指定NN的状态是active还是standby - checkHealth
检查指定NN的状态。NN会对自己的服务做检查,返回0表示正常,0之外的为异常。注意:当前这个功能还没有实现(形同虚设),只要不停机就会返回0
5.自动切换
以上讲了如何手动切换HA,现在来说说实在切换HA
5.1 使用zookeeper实现HA原理
自动切换的HA需要用到zookeeper中的两个组件ZooKeeper quorum和ZKFailoverController process (ZKFC)。
zoookeeper会做以下两件事:
- Failure detection 失效检测
每个namenode都会在zookeeper里保存一个持久会话,一旦某个namenode挂了,zookeeper中的会话就会过期,zookeeper检测机制会通知另外一个namenode需要做failover了 - Active NameNode election 选择新的acitve namenode
zookeeper可以通过简单的机制来选出唯一一个acitve的namdenode.当active的namenode挂了后,另外一个namenode会在zookeeper中保存一个独占锁来标明自己将会是下一个active的namenode.
ZKFC是同namenode在同一台机器上的zookeeper客户端。ZKFC负责以下事情: - Health monitoring 健康检测
ZKFC使用health-check命令定时去pingnamenode,如果在超时时间内得到了响应并且状态是健康的(当前不是只能返回0吗?),就认为namenode是健康的,如果超过时间没有响应,则认为namenode宕机。 - ZooKeeper session management 会话管理
当namenode是健康的时间,ZKFC会和zookeeper保持一个会话,对于acitve的namenode节点,还会在zookeeper上创建一个临时的znode(如/hdfs/active.lock),如果会话过期,则znode会被自动删除 - ZooKeeper session management
在active的节点上ZKFC会在zookeeper里创建一个临时的znode并创建文件(如果/hdfs/acitve.lock),这时其它的namenode节点就不能创建同样一个znode,那么其它节点就会监控这个znode,一旦原来active的namenode宕机,则znode被删除,原来standby的namenode上的ZKFC就可以创建znode并切换standby namenode为acitve
5. 部署hdfs自动切换
5.1 关闭集群
将手动的HA切换为自动的HA必须先关闭集群
5.2 添加HA配置
1.修改hdfs-site.xml
添加:
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
2.修改core-site.xml
添加zookeer的server列表:
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
</property>
这里我修改为 hadoop1 hadoop2 hadoop3
注意,如果使用了hdfs federation,需要加上nameservice-id,如dfs.ha.automatic-failover.enabled.my-nameservice-id.
5.3 在zookeeper中初始化HA状态
在其中一台namenode上执行:
[hdfs]HADOOP_PREFIX/bin/hdfs zkfc -formatZK
5.4 开启集群
- 使用start-dfs.sh启动集群
如果配置了SSH,使用start-dfs.sh启动集群,该脚本会自动启动ZKFC,然后ZKFC选择出一个active的namenode - 手动启动集群
在每个namenode机器上执行:[hdfs]HADOOP_PREFIX/sbin/hadoop-daemon.sh - -script $HADOOP_PREFIX/bin/hdfs start zkfc
5.5 使用zookeeper时的安全机制
略,有兴趣的自己上官网看吧。
6.FAQ
1.ZKFC和NAMENODE有没有特定的启动顺序
2.需要对ZKFC进程做监控,某些时候自动切换失效是因为ZKFC挂了
3.如果zookeeper挂了,则自动failover失效,但不会到HDFS服务有影响。当zookeeper启动后,自动failover功能恢复正常
4.当前并不技能人为的设置某个namenode为primary或者preferred
5.在自动HA的情况下,可以人为的切换namenode,执行hdfs hadmin命令。
7.做了HA后HDFS的升级、回滚
注意**在升级、回滚、finalization中必须保持所有journal节点是开启的(至关重要!)
7.1 升级
1.停止所有的namenode,并安装新的软件
2.开启所有的journal节点,注意在升级、回滚、finalization中必须保持所有journal节点是开启的(至关重要!)
3.以-upgrade方式启动一台namenode
4.启动后,一般该namenode会直接进入active状态,然后执行本地元数据和JNs上edit log的升级
5.另外一台要namenode如果使用-upgrade启动会报错,正确方式是重新初始化-bootstrapStandby
7.2 finalize
注意:如果做回滚或者finalization,则以正常方式重启所有的namenode(不带其它参数)
在active的namenode上执行hdfs dfsadmin -finalizeUpgrade
,这里active的NN将会定稿edit log并在本地上目录中删除旧版本的元数据
7.3 回滚
注意:如果做回滚或者finalization,则以正常方式重启所有的namenode(不带其它参数)
关闭所有的NN,在其中一台namenode上执行roll back命令,然后启动这个NN。在另外一个NN上执行-bootstrapStandby
命令来同步状态
HADOOP docker(二):HDFS 高可用原理的更多相关文章
- HADOOP docker(三):HDFS高可用实验
前言1.机器环境2.配置HA2.1 修改hdfs-site.xml2.2 设置core-site.xml3.配置手动HA3.1 关闭YARN.HDFS3.2 启动HDFS HA4.配置自动HA4. ...
- Hadoop框架:HDFS高可用环境配置
本文源码:GitHub·点这里 || GitEE·点这里 一.HDFS高可用 1.基础描述 在单点或者少数节点故障的情况下,集群还可以正常的提供服务,HDFS高可用机制可以通过配置Active/Sta ...
- hadoop学习(二)----HDFS简介及原理
前面简单介绍了hadoop生态圈,大致了解hadoop是什么.能做什么.带着这些目的我们深入的去学习他.今天一起看一下hadoop的基石--文件存储.因为hadoop是运行与集群之上,处于分布式环境之 ...
- hadoop HA+Federation(高可用联邦)搭建配置(二)
hadoop HA+Federation(高可用联邦)搭建配置(二) 标签(空格分隔): hadoop core-site.xml <?xml version="1.0" e ...
- hadoop 集群HA高可用搭建以及问题解决方案
hadoop 集群HA高可用搭建 目录大纲 1. hadoop HA原理 2. hadoop HA特点 3. Zookeeper 配置 4. 安装Hadoop集群 5. Hadoop HA配置 搭建环 ...
- RabbitMQ(四):使用Docker构建RabbitMQ高可用负载均衡集群
本文使用Docker搭建RabbitMQ集群,然后使用HAProxy做负载均衡,最后使用KeepAlived实现集群高可用,从而搭建起来一个完成了RabbitMQ高可用负载均衡集群.受限于自身条件,本 ...
- hadoop+zookeeper集群高可用搭建
hadoop+zookeeper集群高可用搭建 Senerity 发布于 2 ...
- hadoop 2.7.1 高可用安装部署
hadoop集群规划 目标:创建2个NameNode,做高可用,一个NameNode挂掉,另一个能够启动:一个运行Yarn,3台DataNode,3台Zookeeper集群,做高可用. 在hadoop ...
- 【转载】Hadoop分布式文件系统HDFS的工作原理详述
转载请注明来自36大数据(36dsj.com):36大数据 » Hadoop分布式文件系统HDFS的工作原理详述 转注:读了这篇文章以后,觉得内容比较易懂,所以分享过来支持一下. Hadoop分布式文 ...
随机推荐
- chromium之message_pump_win之一
写了22篇博文,终于到这里了———— MessagePumpWin!!! MessagePumpWin这个类还是挺复杂的,可以分成好几部分.接下来分块分析 从介绍看,MessagePumpWin 是M ...
- 让 shell(bash) 命令行显示当前 git 的分支名称
早上测试脚本的时候,偶然在这篇文章<Git – setting up a remote repository and doing an initial push>看到一个关于 git 的好 ...
- CentOS7.5二进制安装MySQL-5.6.40
安装依赖 yum install -y gcc gcc-c++ automake autoconf yum -y install cmake bison-devel ncurses-devel lib ...
- URL参数获取/转码
JS中对URL进行转码与解码 1.escape 和 unescape escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值. 采用unicode字符集对指定的字符串 ...
- vue2.0 移动端,下拉刷新,上拉加载更多插件,修改版
在[实现丰盛]的插件基础修改[vue2.0 移动端,下拉刷新,上拉加载更多 插件], 1.修改加载到尾页面,返回顶部刷新数据,无法继续加重下一页 2.修改加载完成文字提示 原文链接:http://ww ...
- Windows 聚焦(锁屏背景)不更新的解决方法
在 Windows Store 搜索 Dynamic theme 安装后可对桌面背景.锁屏界面等进行设置,非常好用!
- scala 实现日期运算
在scala程序中,有时我们需要对日期进行运算,比如一天之前,两天之前,一个月之前等等,本博文给出了简单的实现方式 val cal = Calendar.getInstance cal.add(Cal ...
- 选择排序,C语言实现
选择排序是不稳定排序,时间复杂度为O(n^2). 选择排序类似插入排序,把数组分为两部分,一部分已经排好序,一部分未排序. 刚开始的时候所有的元素都未排序,已排序的部分为空.就好像你手里有十张牌,左手 ...
- RMI入门HelloWorld
java RMI(Remote Method Invocation)是一种基于java远程调用技术,是对RPC的java实现,可以在不同主机上进行通信与方法调用.PRC通信原理如图: 方法调用从客户对 ...
- Dinic算法最大流入门
例题传送门 Dinic算法是网络流最大流的优化算法之一,每一步对原图进行分层,然后用DFS求增广路.时间复杂度是O(n^2*m),Dinic算法最多被分为n个阶段,每个阶段包括建层次网络和寻找增广路两 ...