HDFS HA策略(HighAvailability With QJM)
每个NameNode启动时,由其ZKFC向Zookeeper注册(创建唯一的Znode);当某个NameNode崩溃后,其ZKFC向Zookeeper报告,由Zookeeper删除对应的Znode,然后通过Watch消息原子广播到其他的standby的ZKFC,standby之间开始选取新的active节点作为新的NameNode,然后加载Journal Node节点中的fsimage和edit log从而恢复第一关系
Fsimage和edit log保存在Journal Node,FailoverController监视NameNode的工作状态(Active或者StandBy),且FailoverController需要周期性的向Zookeeper发送心跳信息,当检测到主NameNode故障后,采用投票策略(竞争锁)产生新的主NameNode。读写DataNode后,DataNode会上报其块信息至NameNode,NameNode将新的元数据保存在Journal Node中
Zookeeper和Journal Node的数量为奇数
HDFS Federation
可根据业务需求水平扩展NameNode,每个NameNode上仅保存部分元数据,但所有的NameNode均共享DataNode资源
对文本内容进行分词
1. Zookeeper概述
Zookeeper的适用场景:
ZookeeperWeb UI—node-zk-browser
客户端发送请求->Leader节点接收请求->原子广播请求至其他服务器节点->读写数据至轻量级的内存数据库
路径唯一确定一个节点,可携带数据,结构类似目录树
Zookeeper应用场景:
Client->Slave->Leader顺序性决定于Client请求到达Leader的时间戳
Zookeeper节点角色:
Observer用于转发客户端请求至Leader,但是不参加投票过程
Zookeeper数据流图:
Zookeeper判定更新成功的依据是有超过半数的节点更新成功
Zookeeper选举leader也需要超过半数的节点投票通过
Zookeeper节点数一般是3,5,7,9
大致流程:client->follow->leader,由leader发送proposal命令,所有的follow会向leader报告其更新状态,当leader检测到有超过半数的节点完成更新,则向follow发送commit命令,follow则可以提交更新结果,并向client发送反馈
Zookeeper客户端常用命令
Get命令的返回参数解析:
cZxid:创建ID
ctime:创建时间
mZxid:修改ID,一旦leader改变,mZxid前32位改变,后32位从0开始计数
mtime:修改时间
dataVersion:数据版本
numChildren:子节点个数
Zookeeper与KeepAlive区别:
1) 前者支持负载均衡
2) KeepAlive更简单
3) 前者可以存储一定数据
Zookeeper Java API:
Zookeeper实现分布式锁:所谓的分布式锁可以保证一个集群中某一时刻只有一个任务可以占有全部资源并执行
1) 向Zookeeper注册服务器,即创建Znode节点(临时节点),进入队列
2) 判断自己ID是不是队列的第一个,如果是则获得分布式锁,否则监控自己前一个节点(Watch)
3) 判断前一个目录节点是否存在(exists),如果不存在则2)
CountDownLatch.await();//等待指定数量的线程执行完
Zookeeper实现分布式锁的流程图:
Watcher仅通知一次
Zookeeper实现分布式配置管理
Client首先注册Watcher监视/Configuration Znode,当Znode的内容发生改变即create,delete,setData时,会通知Client并执行其process方法修改本地的配置文件
2. ProtocolBuf使用
ProtocolBuf用于结构化数据的序列化,即按照.proto文件规范书写相关属性生成对应的.java文件(可序列化的JavaBeen)
/usr/local/bin/protoc --java_out=.java文件的目录 .proto文件的路径 //编译.proto文件
序列化过程:即对象->字节数组
Put.add(“cf1”.getBytes()),“detail”.getBytes(),detail.build().toByteArray());”//往Hbase中插入cf1:detail=detail(字节数组,即序列化过程)
反序列化过程:字节数组->对象
Cellcell = rs.getColumnLatestCell(“cf1”.getBytes(),”detail”.getBytes());
Phone.pdetail detail=Phone.pdetail.parseFrom(CellUtil.cloneValue(cell));