浅谈ZooKeeper在HBase集群中的作用

前言

连续关注了很多天新型冠状病毒肺炎的消息,心情非常复杂。希望疫情快些过去,所有人都平平安安的。

之前做的春节期间不断更的承诺没能实现,惭愧惭愧。今天大年初五,是时候开工了。

ZooKeeper作为分布式协调组件,在大数据领域的其他分布式组件中往往扮演着重要的辅助角色,因此我们就算不单独去研究ZooKeeper,也短不了要接触它。本文就以最典型的HBase为例,简要介绍ZooKeeper为HBase提供了哪些功能。

下图示出一个完整HBase集群的架构,其中包含ZK节点。

本文所有配图均来自MapR官网博客:https://mapr.com/blog/in-depth-look-hbase-architecture/

HMaster、RegionServer容错

当HBase集群启动成功后,会在ZK注册如下znode:

  • /hbase/master,其中包含当前活动(即赢得选举)的HMaster信息;
  • /hbase/backup-masters/[host-name],每个子znode包含当前作为热备的HMaster信息;
  • /hbase/rs/[host-name],每个子znode包含各RegionServer的信息。

所有znode都是临时(ephemeral)节点,HMaster和RegionServer通过心跳维护这些znode。活动HMaster对/hbase/rs路径下的znode注册监听,当有RegionServer失败时,心跳信号消失,超时过后其对应的znode被删除,HMaster即可感知到RegionServer下线,并将该RegionServer持有的Region重新路由到其他服务器上去。同理,所有热备HMaster都对/hbase/master节点注册监听,当前HMaster挂掉后,该znode被删除,即可触发重新选举HMaster。如下图所示。

Log Split管理

当RegionServer宕机时,除了重新路由Region之外,还得从宕机的RegionServer的WAL(即HLog)中恢复尚未持久化到HFile的数据。为了保证尽快完成failover过程,HBase会将HLog按Region切分成多个分片,并分配给对应的存活RegionServer再完成重放(replay)过程。如下图所示。

显然,Log Split的信息需要有一个中心组件来统一协调。HMaster会在ZK上注册/hbase/splitlog临时节点,其中存放有存活RegionServer与其应该处理的Region HLog的映射关系。各个RegionServer从该节点得到分配的Region,重放HLog,并将结果写回该节点,以通知HMaster进行后续操作。

.META.表位置维护

HBase中有一个特殊的表.META.(在0.98版本之前还有一个-ROOT-表,现已废弃,不再介绍),其中以类似B树的结构记录了集群内所有Region的位置信息,且该表不会split。而ZK通过永久(persistent)节点/hbase/meta-region-server来记录.META.表保存在哪个RegionServer上。

当客户端初次与HBase集群建立连接时,它首先查询上述ZK节点,再从持有.META.表的RegionServer获取到RowKey对应的Region位置信息并缓存起来,最后获取到对应的行做读写操作。如下图所示。

如果Region被移动,或客户端缓存失效,甚至.META.表所在的服务器故障,客户端总能通过ZK维护的路径获得正确的Region位置,不会造成不一致。

Replication管理

HBase的Replication是比较高级的功能,用于主集群和从集群之间的数据同步,从而支持容灾和备份。开启Replication之后,主集群会将数据实时地推送给各个从集群(可以是异步、同步或串行的),且保证数据的最终一致性。整个Replication的状态信息都储存在ZK的/hbase/replication这个znode下,主要有以下三个:

  • /hbase/replication/state:布尔值,表示Replication是否被启用;
  • /hbase/replication/peers:当前进行Replication的从集群对及其状态。每个peer会分配一个唯一ID;
  • /hbase/replication/rs:包含主集群上所有有效的RegionServer、 HLog文件的索引,以及HLog读取的偏移量。

主集群HMaster每次将新增的数据推送给从集群之后,就会更新ZK上记录的这些信息,以协调Replication的进度。

The End

最后多嘴一句,多个HBase集群是可以共用一个ZK集群的。只需要修改HBase的zookeeper.znode.parent参数,对不同集群指定不同的ZK根路径即可,例如/hbase-cluster1/hbase-cluster2,etc.

民那晚安。祝身体健康,百毒不侵。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容