【Hbase优化_1】HBase 行键设计优化:解决数据倾斜问题
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/design/hbase-region-data-skew.html
这次分享/记录如何通过优化行键设计来解决 HBase 中的数据倾斜问题
在大数据场景下,我们的系统使用 HBase 存储了大量的巴枪信息。其中巴枪信息分布在两个表中,分别是巴枪索引表和巴枪主表。
生产中经常会出现Hbase超时问题,用户也经常反馈原始路由查询、巴枪扫描数据导出等功能查询时间过长、超时等问题。经过分析,发现这些问题的根本原因是 HBase 数据倾斜问题。
1. 巴枪信息表结构
1.1 巴枪索引表
表结构
- rowKey: [3位0~499分区号][5位网点编码]|[4位巴枪码]|[操作14位时间字符串]|操作号
- value: 巴枪主表的rowkey
示例
- rowKey: 2700755W|0030|202204060000129|031801088694
1.2 巴枪主表
表结构
- rowKey: [3位0~499分区号][12位运单号]|[4位巴枪码]|[14位时间字符串]|[操作号]
- value: 巴枪数据JSON字符串
示例
- rowKey: 330SF1352340043135|0021|20220404213004|SF1352340043135
2. HBase 数据倾斜问题
由于运单号生成规则问题,运单号的前几位具有很高的相似度。HBase 在数据写入 Region 时,根据 rowKey 进行字符串排序
。在 Region 达到阈值分裂后,会出现“数据倾斜”现象,即部分 Region 数据量很大,部分 Region 数据量很小。这会导致大量小 Region 出现,严重消耗 HBase 存储资源、查询资源,同时降低查询效率。
具体点就是:
- Hbase根据分区把数据写入Region后,其数据根据RowKey进行字符串排序,分裂的时候会根据字符串顺序,从大到小切分一半数据到两个Region内,如原Region数据为SF00000-SF99999,切分后可能就是SF00000-SF49999,SF50000-SF99999两个分区
- 因为运单号生成规则问题,前几位相似度很高,因此可见巴枪主表rowKey,除去分区号后,其前几位区分度很低,所以如果hbase Region达到阈值分裂之后,新数据写入会出现『数据倾斜』现象,一些Region很大,一些Region极小,长期写入数据后,会出现大量的小region
3. 优化方案
3.1 新的巴枪主表 rowKey 规则
新的 rowKey 结构
- rowKey: [3位0~499分区号][运单逆序hash取模3位][先逆序运单号]|[4位巴枪码]|[14位时间字符串]
3.2 对比
方案 | 总 Region 数量 | 最大 Region 存储数 | 最小 Region 存储数 | 分区量 | 数据倾斜度 |
---|---|---|---|---|---|
现有方案 | 5129 | 113277 | 1 | 多 | 大 |
新方案 | 2500 | 26461 | 25380 | 少 | 小 |
结论
新的 rowKey 设计方案可以大幅减少 Region 数量,
数据倾斜度极小,从而有效解决数据倾斜问题
。
3.3 生产切换方案
生产上分为实时库与历史库,分别存3+1个月与1年。因为实施方案一样,这里只介绍实时库:
- 上线后3+1个月内读取方式不变,写库时改为新方案双写,以新规则写入新库同时也以旧的规则写入旧库
- 等3+1个月后,读取时只读取新库,写库时只写入新库
- 以上两步做一个开关,一键切换
- 半年后,删除旧库
4. 总结
优化效果因为需要时间沉淀,所以暂无数据对比结果;
通过优化 HBase 行键设计,我们可以解决数据倾斜问题,提高查询效率,降低存储和查询资源消耗。
在实际应用中,根据具体场景和需求,我们需要灵活调整行键设计策略,以实现更高效的数据存储和查询
附录(自己看)
【Hbase优化_1】HBase 行键设计优化:解决数据倾斜问题