笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值不仅仅只体现在企业中,个人也可以体会到数据的魅力,用技术力量探索行为密码,让大数据助跑每一个人,欢迎直筒们关注我的公众号,大家一起讨论数据中的那些有趣的事情。
我的公众号为:livandata
前言:正式引入HA机制是从hadoop2.0开始,之前的版本中没有HA机制。
(1)hadoop-HA集群运作机制介绍
所谓HA,即高可用(7*24小时不中断服务)
实现高可用最关键的是消除单点故障
hadoop-ha严格来说应该分成各个组件的HA机制——HDFS的HA、YARN的HA
(2)HDFS的HA机制详解
通过双namenode消除单点故障
双namenode协调工作的要点:
A、元数据管理方式需要改变:
内存中各自保存一份元数据
Edits日志只能有一份,只有Active状态的namenode节点可以做写操作
两个namenode都可以读取edits
共享的edits放在一个共享存储中管理(qjournal和NFS两个主流实现)
B、需要一个状态管理功能模块
实现了一个zkfailover,常驻在每一个namenode所在的节点
每一个zkfailover负责监控自己所在namenode节点,利用zk进行状态标识
当需要进行状态切换时,由zkfailover来负责切换
切换时需要防止brain split现象的发生
1.2 HDFS-HA图解:
常用的架构为:
Fsnamesystem:内存结构,主要用来进行数据运算;
Fsimage:用于持久化存储的空间;
Edits:更新操作;
1)当客户端要做数据操作时,导致原数据要发生变化,此时这些操作会先记录在日志里面,操作成功了再进入到内存中;
2)此时,edits中的内容与fsimage中的内容便不一致,此时snn就会出场,他隔一段时间 就会将nn中的edits与fsimage下载下来,然后合并成一个文件,再形成一个全面的fsimage文件,然后替换掉nn中的fsimage;
此时存在一个问题,一旦nn宕机,便不会对外提供服务了,可用性比较低;
如何做成高可用:
需要将nn复制一个出来,做成双活机制,然后用keepalived做监视;
服务器通过将自身的IP,绑定到可用的服务器的网卡上,以实现服务器的可用性,对外提供同一的IP,对内不停的更换,保证有持续的服务器可用;
但有个问题,这样的操作,很难实现多个服务器的状态同步的问题,因为多个服务器之间没有数据同步;
因此需要更好的方法来实现:
即使用一个第三方来进行协调:
Nn的操作流程是先到edits中,记录操作日志,然后再在内存中按照edits中的操作步骤实现一步步的操作,然后存储在fsimage中:
Edits是一些小文件,因此,可以将一些edits拿出来放在一个第三方中,然后多个nn到第三方去取,snn从第三方中取下来进行同步操作,此时,多个服务器之间只差一条记录,即正在写的那条记录;
但如果这个第三方挂掉,也会存在问题,此时需要第三方也是高可用,因此需要第三方也是一个多台服务器的集群,每台服务器都保留edits内容,
有公司为这个系统开发了一个qjournal系统,专门进行高可用的第三方系统,即zookeeper的集群,挂掉其中一台也没有影响,此时可用性很高,但是数据一致性变差了;
其功能即为edits日志管理;
分布式数据库中存在一个三角形:
可用性、可靠性和数据一致性三者未必能够统一,会存在一定的处理;
Zookeeper中是协调用的,主要是对不同的服务器进行处理,但是不存储服务器中的内容,上面的edits日志管理部署时需要有个zookeeper集群,用zk来进行分布式管理,edits不会存在zk中,zk只是作为机器协调、分布式锁、上下线动态感知等功能;
步骤:
1) 当客户端进行数据操作时,通过一个线程池,同步存储操作步骤到本地的edits和远端的edits中,在远端由于需要多台服务器同时写入,因此只要多数台写入成功就可以;
2) edits与standby的状态需要一个人来管理,谁是主,谁是从,谁出了问题,谁来切换,感知这些的进程,每一台nn中写一个程序,这个程序专门来进行状态管理,这个程序叫zkfc,是做失败切换的,这个zkfc也是用zk的,主要是用rpc的接口去掉用服务器,如果调用不返回则表示nn死了,返回表示正常;
3) 一旦zkfc发现nn死了,他就会通知zk,zk会删掉nn的节点,另外一个zkfc在监控这个节点,这个节点删除后,snn上的zkfc就会启动snn,让snn成为active状态,如果切换成功,standby就会变成active,同时在zk中建立一个锁,进行监控;
4) 有时服务器中会存在炸死,即nn有可能暂时死掉,一段时间后又活过来了,就会存在两个active,为防止这种情况发生,zkfc会在启动snn之前会丢出一个命令,干死nn;
5) Zkfc为了让对方死透,如果第四步中丢出命令,长时间没有返回值,可以自定义一个脚本,脚本返回一个值给zkfc,则表示已经杀死了,zkfc放心开始切换。
上面即为hdfs的高可用,接下来有yarn的高可用:
Yarn如果死了,可以直接重启,高可用不是那么迫切:
1) 主要是在zk中注册一把锁,各注册一个节点,如果其中一个死了,则可以直接启动后面的yarn;
当数据量比较大,文件较多时,nn中的内存有可能不够用,此时需要一个新的机制:
Namenode容量的水平扩展,即同时多个对外提供服务,而且两个持有不同的数据:
此时具体的步骤为:
1) 分目录:第一个服务器中为/janpan/;第二个服务器中为/art-x/,如果没有则报错;此时的nn就会变成federation(联邦),这两个服务器也存在主备之分;
此时客户端访问时该访问谁:此时两个nn会有一个逻辑名称,叫名称服务nameservice,一对nn有一个逻辑名称,叫ns1,这个逻辑名称下包含两个nn,客户端api可以通过配置文件知道这个名字下有娜两台namenode,并且通过查看zk,可以知道哪台是active;
此时在访问nn时,就可以找到对应的ns1名称:
假设hdfs://ns 1和hdfs://ns2为内存组的名称,可以将他们作为各个内存组的名称,然后再在他们的上级,即根目录的位置设立访问路径:
Viewfs://japanese即访问hdfs://ns1;
Viewfs://art-x即访问hdfs://ns2;
Datanode没比较分开,可以实现公用,在联邦机制下,两个namenode的clusterID必须一样,这样可以共享DataNode,dn中每台机器就会有两个block块的目录,一个目录为ns1,另一个目录为ns2;
当存在active和standby只有,就没有snn这个结构了;
Namenode的safemode是什么?
一个集群刚起时经常看到,namenode中记录了元数据,即块的信息(块的ID、副本数量等信息),但是他的镜像(fsimage)中只记录了blockID,而block真正的业务信息都在datanode中,他们持有block块,刚启动集群的时候namenode中是没有块信息的,启动时,datanode就会向namenode汇报,汇报自身有哪些数据块,当有些datanode还没有汇报完成的时候,namenode就会进入到safemode模式,等所有datanode汇报结束后,再结束safemode模式;
如何调用HA的机制:
集群部署节点角色的规划(10节点):
server01 namenode zkfc > start-dfs.sh server02 namenode zkfc
server03 resourcemanager > start-yarn.sh server04 resourcemanager
server05 datanode nodemanager server06 datanode nodemanager server07 datanode nodemanager
server08 journal node zookeeper server09 journal node zookeeper server10 journal node zookeeper |
集群部署节点角色的规划(3节点)
server01 namenode resourcemanager zkfc nodemanager datanode zookeeper journal node server02 namenode resourcemanager zkfc nodemanager datanode zookeeper journal node server05 datanode nodemanager zookeeper journal node |
1、环境准备
a/linux系统准备
ip地址配置
hostname配置
hosts映射配置
防火墙关闭
init启动级别修改
sudoers加入hadoop用户
ssh免密登陆配置
b/java环境的配置
上传jdk,解压,修改/etc/profile
c/zookeeper集群的部署
core-site.xml
|
hdfs-site.xml
configuration> sshfence shell(/bin/true)
/configuration> |
1.2.4 集群运维测试
1、Datanode动态上下线
Datanode动态上下线很简单,步骤如下:
a) 准备一台服务器,设置好环境
b) 部署hadoop的安装包,并同步集群配置
c) 联网上线,新datanode会自动加入集群
d) 如果是一次增加大批datanode,还应该做集群负载重均衡
2、Namenode状态切换管理
使用的命令上hdfs haadmin
可用 hdfs haadmin –help查看所有帮助信息
可以看到,状态操作的命令示例:
查看namenode工作状态
hdfs haadmin -getServiceState nn1 |
将standby状态namenode切换到active
hdfs haadmin –transitionToActive nn1 |
将active状态namenode切换到standby
hdfs haadmin –transitionToStandby nn2 |
3、数据块的balance
启动balancer的命令:
start-balancer.sh-threshold 8
运行之后,会有Balancer进程出现:
上述命令设置了Threshold为8%,那么执行balancer命令的时候,首先统计所有DataNode的磁盘利用率的均值,然后判断如果某一个DataNode的磁盘利用率超过这个均值Threshold,那么将会把这个DataNode的block转移到磁盘利用率低的DataNode,这对于新节点的加入来说十分有用。Threshold的值为1到100之间,不显示的进行参数设置的话,默认是10。
1.2.5 HA下hdfs-api变化
客户端需要nameservice的配置信息,其他不变
/** * 如果访问的是一个ha机制的集群 * 则一定要把core-site.xml和hdfs-site.xml配置文件放在客户端程序的classpath下 * 以让客户端能够理解hdfs://ns1/中 “ns1”是一个ha机制中的namenode对——nameservice * 以及知道ns1下具体的namenode通信地址 * @author * */ public class UploadFile { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://ns1/"); FileSystem fs = FileSystem.get(new URI("hdfs://ns1/"),conf,"hadoop"); fs.copyFromLocalFile(new Path("g:/eclipse-jee-luna-SR1-linux-gtk.tar.gz"), new Path("hdfs://ns1/")); fs.close(); } } |
Federation下 mr程序运行的staging提交目录问题