深度研究hbase的热点问题,和hbase 表rk的设计 和手动分区region

2019/2/20 星期三

深度研究hbase的热点问题,和hbase 表rk的设计 和手动分区region
在2019/1/25 星期五记录
hbase的热点问题:
hbase热点问题解决(预分区) https://blog.csdn.net/qq_31289187/article/details/80869906
Hbase split的三种方式和split的过程 https://www.cnblogs.com/niurougan/p/3976519.html
—————————————————————————————————————————————————
什么是hbase的热点问题
出现热点问题原因
1、hbase的中的数据是按照字典序排序的,当大量连续的rowkey集中写在个别的region,各个region之间数据分布不均衡;
2、创建表时没有提前预分区,创建的表默认只有一个region,大量的数据写入当前region;
3、创建表已经提前预分区,但是设计的rowkey没有规律可循,设计的rowkey应该由regionNo+messageId组成。

如何解决热点问题
解决这个问题,关键是要设计出可以让数据分布均匀的rowkey,与关系型数据库一样,rowkey是用来检索记录的主键。访问hbase table中的行,rowkey 可以是任意字符串(最大长度 是 64KB,实际应用中长度一般为 10-100bytes),在hbase内部,rowkey保存为字节数组,存储时,数据按照rowkey的字典序排序存储。

创建表命令:
create 'testTable',{NAME => 'cf', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE=> '0', VERSIONS => '1', COMPRESSION => 'snappy', MIN_VERSIONS =>'0', TTL => '15552000', KEEP_DELETED_CELLS => 'false', BLOCKSIZE =>'65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA =>{'ENCODE_ON_DISK' => 'true'}},{SPLITS_FILE=>'/app/soft/test/region.txt'}

https://blog.csdn.net/weixin_41279060/article/details/78855679 hbase系列-Hbase热点问题、数据倾斜和rowkey的散列设计

预分区和rowkey的散列设计——解决数据倾斜和热点问题
预分区,让表的数据可以均衡的分散在集群中,而不是默认只有一个region分布在集群的一个节点上。(预分区个数=节点的倍数,看数据量估算,region不足了会被分列,预分区后每个region的rowkey还是有序的)

如何给hbase表预分区
HBase预分区方法 https://www.cnblogs.com/quchunhui/p/7543385.html *****
Hbase 表的设计原则 ————总结 https://blog.csdn.net/m0_37138008/article/details/78985946

行键(RowKey)设计

HBase的行由行键按字典顺序排序,这样的设计优化了扫描,允许存储相关的行或者那些将被一起读的邻近的行。
然而,设计不好的行键是导致hots potting(热点问题)的常见原因。当大量的客户端流量( traffic )被定向在集群上的一个或几个节点时,就会发生hots potting。这些流量可能代表着读、写或其他操作。流量超过了承载该region的单个机器所能负荷的量,这就会导致性能下降并有可能造成region的不可用。在同一RegionServer上的其他region也可能会受到其不良影响,因为主机无法提供服务所请求的负载。设计使集群能被充分均匀地使用的数据访问模式是至关重要的。


预分区和rowkey的散列设计——解决数据倾斜和热点问题
预分区
预分区,让表的数据可以均衡的分散在集群中,而不是默认只有一个region分布在集群的一个节点上。(预分区个数=节点的倍数,看数据量估算,region不足了会被分列,预分区后每个region的rowkey还是有序的)
一个RegionServer能管理10-1000个Region,0.92.x版本后,默认的Region大小为10G,向下可以支持256MB,向上可以支持到20G,也就是说,每个RegionServer能管理的数据量为2.5GB-20TB。
如果有5个节点,3年内数据量为5T,那么分区数可以预设为:
5000G/10G=500个region
这500个Region就会被均衡的分布在集群各个节点上(具体分布看机器的性能和存储空间而定),机器硬盘不足可以添加硬盘,性能不足可以添加新节点(添加新机器)。
Rowkey长度原则(最好不超过16字节)
Rowkey是一个二进制码流,Rowkey的长度被很多开发者建议说设计在10~100个字节,不过建议是越短越好,不要超过16个字节。
原因如下:
(1)数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;
(2)MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
(3)目前操作系统是都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。

rowkey散列原则
把主键哈希后当成rowkey的头部

rowkey唯一原则
必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。
时间戳反转
如果数据需要保留多个版本,可以使用反转的时间戳作为rowkey的一部分,用 Long.Max_Value - timestamp 追加到key的末尾,例如 [key][reverse_timestamp] , [key] 的最新值可以通过scan [key]获得[key]的第一条记录,因为HBase中rowkey是有序的,第一条记录是最后录入的数据。

整个rowkey(timestamp并不是必要的,视业务而定)
rowkey=哈希(主键<递增的id\手机号码等>)+Long.Max_Value - timestamp


作者:boat824109722
来源:CSDN
原文:https://blog.csdn.net/weixin_41279060/article/details/78855679
版权声明:本文为博主原创文章,转载请附上博文链接!

rk设计小结1:
1、首先先规划hbase表的大小,计算规划出合理的region数
2、rk长度设计(最好不超过16字节)
3、rk散列原则(把主键哈希后当成rk的头部,这里的散列理解为前缀指派的随机数添加到rk前面)
4、rk唯一原则(将经常读取的数据放在一起,将最近可能被访问的数据放在一个块)
5、版本数为3合理,如果过期数据不是很重要的话。

行键rk的设计小结2:
设计行键时应该使得数据尽量同时往多个region上写,而避免只向一个region写(避免hbase的热点问题),可用用前缀指派的随机数添加到rk的前面,这样就可以分散到不同的region中(salting),使用了顺序的key会将本没有顺序的数据变得有顺序,把负载压在一台机器上。所以要尽量避免时间戳或者序列(e.g. 1, 2, 3)这样的行键。(减少单调递增行键/时序数据)。

表模式经验法则
1、region规模大小在10到50GB之间;
2、单元的大小不要超过10MB,如果使用 Object Store(在下面介绍) ,可放宽到50MB;不然,可以考虑将单元数据存在HDFS中,或者在HBase中存一个指向这些数据的指针;
3、一个典型的模式每个表中含有1~3个列族
4、对于只有1~2个列族的表,50到100个region是一个比较合适的数量。需要提醒的是,每个region都是列族的一个连续段;
5、列族的名字越短越好,因为对每个值(忽略前缀编码, prefix encoding ),列族名都会存一次。它们不应当像典型RDNMS一样自记录( self-documenting ) 和描述。
6、如果在基于时间的机器上存储数据或日志信息,行键(Row Key)是由设备ID或服务器ID加上时间得到的,那最后能得到这样的模式:除了某个特定的时间段,旧的数据region没有额外的写。在这种情况下,得到的是少量的活跃region和大量的没有新写入的旧region。这时由于资源消耗仅来自于活跃的region,大量的region能被容纳接受;

大部分时候,细微的低效不会影响很大。但不幸的是,在这里却不能忽略。无论是列族、属性和行键都会在数据中重复上亿次。
1、列族:尽量使列族名小,最好一个字符。(如 "d" 表示 data/default).
2、属性:详细属性名 (如, "myVeryImportantAttribute") 易读,最好还是用短属性名 (e.g., "via") 保存到HBase.
3、行键长度:让行键短到可读即可,这样对获取数据有帮助(e.g., Get vs. Scan)。短键对访问数据无用,并不比长键对get/scan更好。设计行键需要权衡。
4、字节模式:long类型有8字节。8字节内可以保存无符号数字到18,446,744,073,709,551,615。 如果用字符串保存——假设一个字节一个字符——需要将近3倍的字节数。

行键永远不变:行键不能改变。唯一可以“改变”的方式是删除然后再插入。这是一个常问问题,所以要注意开始就要让行键正确(且/或在插入很多数据之前)。

猜你喜欢

转载自blog.51cto.com/12445535/2352410