这是我参与「第四届青训营」笔记创作活动的第十二天。
HBase数据模型
HBase以列族(column family)组织数据,以行键(rowkey)索弓|数据。
列族需要在使用前预先创建,列名( column qualifier )不需要预先声明,因此支持半结构化数据模型。
支持保留多个版本的数据,(行键+列族+列名+版本号)定位一一个具体的值。
行式存储 vs. 列式存储
每个版本的数据都携带全部行列信息。
同一行,同一列族的数据物理上连续有序存储。 同列族内的KeyValue按rowkey字典序升序, column qualifier 升序, version 降序排列。
不同列族的数据存储在相互独立的物理文件,列族间 不保证数据全局有序。 同列族下不同物理文件间不保证数据全局有序。 仅单个物理文件内有序。
重要概念
使用场景
- 海量数据
- 写密集型、高吞吐、可接受一定时延抖动
- 字典序主键索引、批量扫描
- 半结构化数据、行列稀疏、动态增减列名
- 敏捷平滑地扩展
实际应用
- 电商订单
- 用户交互:IM、Email、点赞、搜索
HBase架构
HMaster
元数据管理、集群调度、保活;管理RS实例生命周期、协调错误恢复;负载均衡。
- ActiveMasterManager :管理HMaster的active/backup状态
- ServerManager :管理集群内RegionServer的状态
- AssignmentManager :管理数据分片( region )的状态
- SplitWalManager :负责故障数据恢复的WAL拆分工作
- LoadBalancer :定期巡检、调整集群负载状态
- RegionNormalizer :定期巡检并拆分热点、整合碎片
- CatalogJanitor :定期巡检、清理元数据
- Cleaners :定期清理废弃的HFile / WAL等文件
- MasterFileSystem :封装访问HDFS的客户端SDK
RegionServer
提供rowkey区间数据读写服务,每个实例负责若干个互不重叠的rowkey区间内的数据。
若负责存储meta表,则向客户端SDK提供rowkey位置信息
认领HMaster发布的故障恢复任务帮助加速数据恢复过程
处理HMaster下达的元数据操作,如region打开/关闭/分裂/合并操作等
外部依赖ZooKeeper
- HMaster登记信息,对active/backup分工达成共识
- RegionServer登记信息,失联时HMaster保活处理
- 登记meta表位置信息,供SDK查询读写位置信息
- 供HMaster和RegionServer协作处理分布式任务
ThriftServer
提供Thrift API读写的代理层。
- 实现HBase定义的Thrift API,作为代理层向用户提供RPC读写服务
- 用户可根据IDL自行生成客户端实现
- 独立于RegionServer水平扩展,用户可访问任意ThriftServer实例(scan操作较特殊,需要同实例维护scan状态)
HBase重要机制
热点切分
不搬迁实际数据,切分产生的新region 数据目录下生成一个以原region文件信息命名的文件,内容是切分点对应的rowkey ,以及标识新region是上下半部分的数据。
切分点的选取:选择最大的Region中的最大的Column Family的最大的HFile的中间位置的Data Block的第一条KeyValue的rowkey作为切分点
状态机实现
碎片合并
合并相邻的碎片化的Region
同样的,不搬迁实际数据,通过reference file 定位原region的文件直到下次 compaction 时实际处理数据。
负载均衡
- SimpleLoadBalancer:尽量靠近平均region数上下的sloppy区间
- StochasticLoadBalancer:随机尝试region放置策略,类似CBO
- FavoredLoadBalancer:为region指定几个优选RS,依次使用,充分利用本地读写HDFS文件
HMaster故障恢复
自身恢复
1.监听到/hbase/active-master临时节点被删除的事件,触发选主逻辑; 2.选主成功后执行HMaster启动流程,从持久化存储读取未完成的procedures从之前状态继续执行; 3.故障HMaster实例恢复后发现主节点已存在,继续监听/hbase/active-master;
调度RS恢复
- AssignmentManager从procedure列表中找出Region-In-Transition 状态的region 继续调度过程;
- RegionServer Tracker从Zookeeper梳理online状态的RegionServer列表,结合ServerCrashProcedure列表、HDFS中WAL目录里alive / splitting状态的RegionServer记录,获取掉线RegionServer的列表,分别创建ServerCrashProcedure执行恢复流程。
RegionServer故障恢复
每个RegionServer实例启动时都会往Zookeeper的/hbase/rs路径下创建对应的临时节点。 HMaster通过监听RegionServer在Zookeeper的临时节点状态,监控数据读写服务的可用性, 及时调度恢复不可用的regions。 RegionServer的故障恢复需要将内存中丢失的数据从WAL中恢复HMaster 利用Zookeeper 配合所有 RegionServer实例,分布式地处理WAL数据,提升恢复速度。
启动流程:
- 启动时去Zookeeper登记自身信息,告知主HMaster实例有新RS实例接入集群
- 接收和执行来自HMaster的region调度命令
- 打开region前先从HDFS读取该region的recovered.edits目录下的WAL记录,回放恢复数据
- 恢复完成,认领Zookeeper.上发布的分布式任务(如WAL切分)帮助其他数据恢复
Distributed Log Split
- RegionServer故障, Zookeeper检测到心跳超时或连接断开,删除对应的临时节点并通知监听该节点的客户端
- active HMaster监听到RS临时节点删除事件,从HDFS梳理出该RS负责的WAL文件列表
- HMaster 为每个WAL文件发布一个log split task到ZK 4.其他在线的RS监听到新任务,分别认领 5.将WAL entries按region拆分,分别写入HDFS上该region的recovered.edits目录
- HMaster监听到log split任务完成,调度region到其他RS
- RS打开region前在HDFS找到先回放recovered.edits目录下的WAL文件将数据恢复到Memstore里,再打开region恢复读写服务
Distributed Log Replay
- HMaster先将故障RegionServer.上的所有region以Recovering状态调度分配到其他正常RS上;
- 再进行类似Distributed Log Split的WAL日志按region维度切分;
- 切分后不写入HDFS,而是直接回放,通过SDK写流程将WAL记录写到对应的新RS ;
- Recovering状态的region接受写请求但不提供读服务,直到WAL回放数据恢复完成。
HBase调优
不需要顺序扫描批量连续rowkey:对原始rowkey做hash
需要的:首先用grouplD/applD/userID前缀避免数据热点,然后加上定义顺序的信息(如时间戳等)
rowkey尽量端,减少冗余
避免使用时间戳直接作为rowkey前缀,否则会使新数据集中在一台RS上,造成热点瓶颈。