前面,咱们已经打下了不少关于HBase的理论基础,今天,咱们主要聊聊在实际开发使用HBase中,须要关注的一些最佳实践经验。git
1.Schema设计七大原则
1)每一个region的大小应该控制在10G到50G之间;github
2)一个表最好保持在 50到100个 region的规模;面试
3)每一个cell最大不该该超过10MB,若是超过,应该有些考虑业务拆分,若是实在没法拆分,那就只能使用mob;算法
4)跟传统的关系型数据库不一样,一个HBase的表中列族最多不超过3个,列族中的列能够动态添加的,不要设计过多列族;数据库
5)列族名必须尽可能短,由于咱们知道在存储的时候,每一个keyvalue都会包含列族名;性能优化
6)若是一个表存在一个以上的列族,那么必需要注意,不一样列族之间行数相差不要太大。 例如列族A有10万行,而列族B有1亿行,那么rowkey就有1亿行,而region是按照行键进行切分的,所以列族A可能会被打散为不少不少小region,这会致使在扫描列族A时会引起较多IO,效率低下。app
7)列族能够设置TTL时间,HBase在超过设定时间后,会自动删除数据。分布式
设置方法有两种:性能
# 建表时设置,TTL单位为秒,此例中列簇'f1'的数据保留1天(86400秒)优化
hbase(main):002:0>create 'table', {NAME => 'f1', TTL => 86400}
# 经过修改表设置
hbase(main):002:0>alter 'table', {NAME => 'f1', TTL => 86400}
这里须要注意,一旦超过设定时间后,该数据就没法读取了,可是,真正的过时数据删除,是发生在major compaction时。
2.RowKey设计三大策略
HBase做为一个分布式存储数据库,虽然扩容很是容易,可是,对于“热点”问题,仍是很是头疼的。
所谓“热点”问题(HotSpotting),就是请求(读或者写)短期内落在了集中的个别region上,致使了该region所在机器的负载急剧上升,超过了单点实例的承受能力,从而引发性能降低或者不可用。
要解决这个问题,就须要设计RowKey时,使得数据尽可能往多个region上去写。
举个例子:
假如region按照26个字母分红26个,那么同时写入m开头的rowkey的记录都会同时写入同一个region
好比m001,m002,m003,m004,m005。
所以,RowKey的设计很是关键。常见的设计策略有这么几种。
1)salting
salting策略就是将生成随机数放在行键的开头做为前缀,使得每一个行键有随机的字典序。
对上面的案例进行优化,咱们采用了salting策略,插入前给每一个rowkey生成一个随机的字母,变成了
am001,zm002,nm003,qm004,lm005
这样就能同时往5个region里面写入了,成功打散。
反作用:因为前缀生成是随机的,所以若是想要按照字典序查询这些行,则须要作更多的事情。从这个角度上看,salting增长了写操做的吞吐量,却也增大了读操做的开销。
2)Hashing
Hashing策略也是一种特殊的salting,是用一个单向的 hash 来取代随机指派前缀。
这样能使一个给定rowkey的行在“salted”时有相同的前缀,所以,这样既能够分散RegionServer间的负载的,同时也容许在读操做时可以预测这个前缀值是什么。肯定性hash( deterministic hash )可让客户端重建完整的行键,而后就能够像正常同样用Get方法查询肯定的行。
3)reverse key
第三种预防hotspotting的方法是反转一段固定长度或者可数的键,让变化最多的某个位置放在rowkey的第一位,
反作用:对于Get操做没有影响,可是不利于Scan操做进行范围查询,由于数据在原RowKey上的顺序已经被打乱。
3.预分区
在 HBase核心特性—region split 中,咱们知道已经提到过关于预分区。
主要缘由是当一张表被首次建立时,只会分配一个region给这个表。所以,在刚刚开始时,全部读写请求都会落在这个region所在的region server上,而无论你整个集群有多少个region server。不能充分地利用集群的分布式特性。
所以,预分区主要也是解决“热点”问题。
最为常见的建表语句为:
create ‘tb’,{NAME => ‘f1’,COMPRESSION => ‘snappy’ }, { NUMREGIONS => 50, SPLITALGO => ‘HexStringSplit’ }
- NUMREGIONS 为 region的个数,通常按照每一个region 8-10GB左右来计算region数量,若是集群规模很是大,那么region数量能够适当取大一些
- SPLITALGO 为 rowkey分割的算法,Hbase自带了三种pre-split的算法,分别是 HexStringSplit、DecimalStringSplit 和 UniformSplit。
各类Split算法适用场景:
- HexStringSplit: rowkey是十六进制的字符串做为前缀的
- DecimalStringSplit: rowkey是10进制数字字符串做为前缀的
- UniformSplit: rowkey前缀彻底随机
4.读性能优化
前面主要讲一些设计方面的优化点。
那若是在HBase的使用过程当中,发现查询较慢,那么就须要根据具体状况,分析查询慢的缘由,并采起相应的策略。

看到这里了,原创不易,点个关注、点个赞吧,你最好看了~
知识碎片从新梳理,构建Java知识图谱:https://github.com/saigu/JavaKnowledgeGraph(历史文章查阅很是方便)
扫码关注个人公众号“阿丸笔记”,第一时间获取最新更新。同时能够免费获取海量Java技术栈电子书、各个大厂面试题。