searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

HBase热点问题和规避策略

2024-10-10 02:06:16
15
0

用户侧策略:

在之前的会议中,建议应用侧优化row设计和预分区,下面具体说明:

1rowkey的设计建议使用哈希、加盐、反转的方式使请求均匀的分布到每个节点上。

        1.1、加盐。对某些业务来说,rowkey并不具有前缀散列性,如果以时间戳为前缀,就会导致短时间内写入的rowkey都在同一个region,造成数据热点。这个时候,我们一般会加一个前缀prefix,与原有rowkey拼接成新的rowkey读取的时候,比如我要读Row0这个rowkey,那么就需要在读取00-Row001-Row002-Row003-Row004-Row0这五个rowkey,并且把结果归并起来。如图:


        加盐的缺点,由于前缀是随机生成的,因而如果想要按照字典顺序找到这些行,则需要做更多的工作。从这个角度上看,salting增加了写操作的吞吐量,却也增大了读操作的开销。

        1.2、哈希。加盐策略在get的时候,开销比较大,如果场景是即席查询为主,可以考虑使用hashing,在避免读写热点的同时,加快get操作的效率。确定性Hash(比如md5后取前4位做前缀)能让客户端重建完整的RowKey,可以使用get操作直接get想要的行。读取的时候,比如我要读Row0这个rowkey,通过hash函数可以直接计算出真实rowkey,从而直接get到结果。  如图:


        哈希的缺点,虽然可以一定程度打散整个数据集,但是不利于ScanScan的时候取到的连续数据行没有前后联系。

1.3、反转,

有些类型的应用,rowkey带手机号,时间戳等,通过反转就可以有效的起到散列的效果。从某种程度上看,反转的效果类似于hash,对scan类查询不友好。不过对于时间戳或者手机号等特定类型的问题,反转可以做到较好地优化。一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为 rowkey 的一部分对这个问题十分有用,可以用 Long.Max_Value - timestamp 追加到 key 的末尾,例  [key][reverse_timestamp] , [key] 的最新值可以通过 scan [key]获得[key]的第一条记录,因为 HBase  rowkey 是有序的,第一条记录是最后录入的数据。比如需要保存一个用户的操 作记录,按照操作时间倒序排序,在设计 rowkey 的时候,可以这样设计 [userId 反转][Long.Max_Value - timestamp],在查询用户的所有操作记录数据的时候,直接指定反转后的 userId startRow  [userId 反转 ][000000000000],stopRow  [userId  ][Long.Max_Value - timestamp]

如果需要查询某段时间的操作记录, startRow [user 反转][Long.Max_Value - 起始时间] stopRow [userId 反转][Long.Max_Value - 结束时间,这样范围查询的性能也不受影响。


       

2、预分区

Hbase中的表会被划分为nRegion,然后存放在多个RegionServer中,每个RegionStartKeyEndKey,表示这个Region维护的RowKey范围,而第一个Region没有StartKey,最后一个Region没有EndKey。需要读写数据时,RowKey会落在某个范围内,就会定位到目标的Region以及所在的RegionServer

应用的表大部分表都是50个分区,每个分区的最大大小为10G,当1个分区达到最大后,会分裂成2个分区,并且分裂点由服务端自动选择,分裂后也很容易出现热点问题,建议应用根据表大小来评估预分区的数量。

预分区有手动和自动两种方法。其中系统支持的自动预分区有UniformSplitDecimalStringSplitHexStringSplit算法。UniformSplit00FF对应的随机字符中选取预分区点,后面两种分别在00000000 99999999.00000000 FFFFFFFF中选取预分区点。

2.1、手动指定预分区断点:

hbase>create 't1','f1',SPLITS => ['\x10\x00', '\x20\x00', '\x30\x00', '\x40\x00']

2.2、使用随机字符指定4个预分区断点,分成5个预分区

hbase>create 't2','f1', { NUMREGIONS => 4 , SPLITALGO => 'UniformSplit' }

2.3、使用16进制字符指定5个预分区断点,分成6个预分区

create 't3','f1', { NUMREGIONS => 5, SPLITALGO => 'HexStringSplit' }

集群运维策略:

在实际使用过程中,不同表的冷热分布不均是很常见的行为,因为这个因素导致的region server热点问题,有时需要集群侧运维来进行调整。

1、 监控集群负载高的regionserver

HBase shell

status detailed


2、 迁移热点region至负载低的regionserver

确定了热点 Region 和负载高的 Region Server 后,我们可以将热点 Region 迁移至负载低的 Region Server 上,以实现负载均衡。

HBase shell

move 'region_name','target_region_server'

3、 监控负载均衡情况,并根据需要重复步骤12

最后,我们需要持续监控负载均衡情况,并根据需要重复执行步骤23。在迁移了热点 Region 后,集群的负载情况可能发生变化,可能出现新的热点 Region 或者负载高的 Region Server。因此,我们需要不断地进行监控和调整,以实现持续的负载均衡。

 

0条评论
0 / 1000
陈****赜
3文章数
0粉丝数
陈****赜
3 文章 | 0 粉丝
陈****赜
3文章数
0粉丝数
陈****赜
3 文章 | 0 粉丝
原创

HBase热点问题和规避策略

2024-10-10 02:06:16
15
0

用户侧策略:

在之前的会议中,建议应用侧优化row设计和预分区,下面具体说明:

1rowkey的设计建议使用哈希、加盐、反转的方式使请求均匀的分布到每个节点上。

        1.1、加盐。对某些业务来说,rowkey并不具有前缀散列性,如果以时间戳为前缀,就会导致短时间内写入的rowkey都在同一个region,造成数据热点。这个时候,我们一般会加一个前缀prefix,与原有rowkey拼接成新的rowkey读取的时候,比如我要读Row0这个rowkey,那么就需要在读取00-Row001-Row002-Row003-Row004-Row0这五个rowkey,并且把结果归并起来。如图:


        加盐的缺点,由于前缀是随机生成的,因而如果想要按照字典顺序找到这些行,则需要做更多的工作。从这个角度上看,salting增加了写操作的吞吐量,却也增大了读操作的开销。

        1.2、哈希。加盐策略在get的时候,开销比较大,如果场景是即席查询为主,可以考虑使用hashing,在避免读写热点的同时,加快get操作的效率。确定性Hash(比如md5后取前4位做前缀)能让客户端重建完整的RowKey,可以使用get操作直接get想要的行。读取的时候,比如我要读Row0这个rowkey,通过hash函数可以直接计算出真实rowkey,从而直接get到结果。  如图:


        哈希的缺点,虽然可以一定程度打散整个数据集,但是不利于ScanScan的时候取到的连续数据行没有前后联系。

1.3、反转,

有些类型的应用,rowkey带手机号,时间戳等,通过反转就可以有效的起到散列的效果。从某种程度上看,反转的效果类似于hash,对scan类查询不友好。不过对于时间戳或者手机号等特定类型的问题,反转可以做到较好地优化。一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为 rowkey 的一部分对这个问题十分有用,可以用 Long.Max_Value - timestamp 追加到 key 的末尾,例  [key][reverse_timestamp] , [key] 的最新值可以通过 scan [key]获得[key]的第一条记录,因为 HBase  rowkey 是有序的,第一条记录是最后录入的数据。比如需要保存一个用户的操 作记录,按照操作时间倒序排序,在设计 rowkey 的时候,可以这样设计 [userId 反转][Long.Max_Value - timestamp],在查询用户的所有操作记录数据的时候,直接指定反转后的 userId startRow  [userId 反转 ][000000000000],stopRow  [userId  ][Long.Max_Value - timestamp]

如果需要查询某段时间的操作记录, startRow [user 反转][Long.Max_Value - 起始时间] stopRow [userId 反转][Long.Max_Value - 结束时间,这样范围查询的性能也不受影响。


       

2、预分区

Hbase中的表会被划分为nRegion,然后存放在多个RegionServer中,每个RegionStartKeyEndKey,表示这个Region维护的RowKey范围,而第一个Region没有StartKey,最后一个Region没有EndKey。需要读写数据时,RowKey会落在某个范围内,就会定位到目标的Region以及所在的RegionServer

应用的表大部分表都是50个分区,每个分区的最大大小为10G,当1个分区达到最大后,会分裂成2个分区,并且分裂点由服务端自动选择,分裂后也很容易出现热点问题,建议应用根据表大小来评估预分区的数量。

预分区有手动和自动两种方法。其中系统支持的自动预分区有UniformSplitDecimalStringSplitHexStringSplit算法。UniformSplit00FF对应的随机字符中选取预分区点,后面两种分别在00000000 99999999.00000000 FFFFFFFF中选取预分区点。

2.1、手动指定预分区断点:

hbase>create 't1','f1',SPLITS => ['\x10\x00', '\x20\x00', '\x30\x00', '\x40\x00']

2.2、使用随机字符指定4个预分区断点,分成5个预分区

hbase>create 't2','f1', { NUMREGIONS => 4 , SPLITALGO => 'UniformSplit' }

2.3、使用16进制字符指定5个预分区断点,分成6个预分区

create 't3','f1', { NUMREGIONS => 5, SPLITALGO => 'HexStringSplit' }

集群运维策略:

在实际使用过程中,不同表的冷热分布不均是很常见的行为,因为这个因素导致的region server热点问题,有时需要集群侧运维来进行调整。

1、 监控集群负载高的regionserver

HBase shell

status detailed


2、 迁移热点region至负载低的regionserver

确定了热点 Region 和负载高的 Region Server 后,我们可以将热点 Region 迁移至负载低的 Region Server 上,以实现负载均衡。

HBase shell

move 'region_name','target_region_server'

3、 监控负载均衡情况,并根据需要重复步骤12

最后,我们需要持续监控负载均衡情况,并根据需要重复执行步骤23。在迁移了热点 Region 后,集群的负载情况可能发生变化,可能出现新的热点 Region 或者负载高的 Region Server。因此,我们需要不断地进行监控和调整,以实现持续的负载均衡。

 

文章来自个人专栏
技术调研
3 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0