hbase最佳实践

  • HBase 适用场景
  • rowkey设计
  • 建议


HBase 适用场景

不需要复杂查询的应用。HBase 原生只支持基于 RowKey 的索引,对于某些复杂查询(如模糊查询,多字段查询),HBase 可能需要全表扫描来获取结果。
写密集应用。HBase 是一个写快读慢(慢是相对的)的系统。HBase 是根据 Google 的 BigTable 设计的,典型应用就是不断插入新数据(如 Google 的网页信息)。
对事务要求不高的应用。HBase 只支持基于 RowKey 的事务。
对性能、可靠性要求高的应用。HBase 不存在单点故障,可用性高。
数据量特别大的应用。HBase 支持百亿行百万列的数据量,单个 Region 过大将自动触发分裂,具备较好的伸缩能力。

不要期许HBase可以完全替代关系型数据库
虽然它在许多方面都表现优秀。它不支持SQL,也没有优化器,更不能支持跨越多条记录的事务或关联查询。如果你用不到这些特性,那HBase将是你的不二选择。
在复用HBase的服务器时有一些注意事项。
如果你需要保证HBase的服务器质量,同时又想在HBase上运行批处理脚本,建议还是另搭一套集群。HBase在处理大量顺序I/O操作时(如MapReduce),其CPU和内存资源将会十分紧张。将这两类应用放置在同一集群上会造成不可预估的服务延迟。此外,共享集群时还需要调低任务槽(task slot)的数量,至少要留一半的CPU核数给HBase。密切关注内存,因为一旦发生swap,HBase很可能会停止心跳,从而被集群判为无效,最终产生一系列宕机。

不建议线上实时对外服务使用HBase
Hbase是一个CP的设计,如果发生宕机,会有一定的不可用的时间。如果坚持要使用,建议对HBase环境进行隔离,尽量采用阿里云HBase。

对延迟要求比较高的场景
由于GC,读取抖动会到100-200ms,建议升级2.0或者隔离单独的hbase集群。

rowkey设计

rowkey常见的几种方式
Salting
从某种程度上看与加密无关,它指的是将随机数放在行键的起始处。进一步说,salting给每一行键随机指定了一个前缀来让它与其他行键有着不同的排序。所有可能前缀的数量对应于要分散数据的region的数量。如果有几个“hot”的行键模式,而这些模式在其他更均匀分布的行里反复出现,salting就能到帮助,salting增加了写操作的吞吐量,却也增大了读操作的开销。

Hashing
可用一个单向的 hash 散列来取代随机指派前缀。这样能使一个给定的行在“salted”时有相同的前缀,从某种程度上说,这在分散了RegionServer间的负载的同时,也允许在读操作时能够预测。确定性hash( deterministic hash )能让客户端重建完整的行键,以及像正常的一样用Get操作重新获得想要的行。
考虑和上述salting一样的情景,现在可以用单向hash来得到行键foo0003,并可预测得‘a’这个前缀。然后为了重新获得这一行,需要先知道它的键。可以进一步优化这一方法,如使得将特定的键对总是在相同的region。

Reversing the Key(反转键)
第三种预防hotspotting的方法是反转一段固定长度或者可数的键,来让最常改变的部分(最低显著位, the least significant digit )在第一位,这样有效地打乱了行键,但是却牺牲了行排序的属性

单调递增行键/时序数据
在一个集群中,一个导入数据的进程锁住不动,所有的client都在等待一个region(因而也就是一个单个节点),过了一会后,变成了下一个region… 如果使用了单调递增或者时序的key便会造成这样的问题。使用了顺序的key会将本没有顺序的数据变得有顺序,把负载压在一台机器上。所以要尽量避免时间戳或者序列(e.g. 1, 2, 3)这样的行键。

简化行和列
在HBase中,值是作为一个单元(Cell)保存在系统的中的,要定位一个单元,需要行,列名和时间戳。通常情况下,如果行和列的名字要是太大(甚至比value的大小还要大)的话,可能会遇到一些有趣的情况。在HBase的存储文件( storefiles )中,有一个索引用来方便值的随机访问,但是访问一个单元的坐标要是太大的话,会占用很大的内存,这个索引会被用尽。要想解决这个问题,可以设置一个更大的块大小,也可以使用更小的行和列名 。压缩也能得到更大指数。

列族
尽量使列族名小,最好一个字符。(如:f 表示)
属性
详细属性名 (如:”myVeryImportantAttribute”) 易读,最好还是用短属性名 (e.g., “via”) 保存到HBase.

行键长度
让行键短到可读即可,这样对获取数据有帮助(e.g., Get vs. Scan)。短键对访问数据无用,并不比长键对get/scan更好。设计行键需要权衡
字节模式
long类型有8字节。8字节内可以保存无符号数字到18,446,744,073,709,551,615。 如果用字符串保存——假设一个字节一个字符——需要将近3倍的字节数。

倒序时间戳
一个数据库处理的通常问题是找到最近版本的值。采用倒序时间戳作为键的一部分可以对此特定情况有很大帮助。该技术包含追加( Long.MAX_VALUE - timestamp ) 到key的后面,如 [key][reverse_timestamp] 。
表内[key]的最近的值可以用[key]进行Scan,找到并获取第一个记录。由于HBase行键是排序的,该键排在任何比它老的行键的前面,所以是第一个。

行键和列族
行键在列族范围内。所以同样的行键可以在同一个表的每个列族中存在而不会冲突。行键不可改,唯一可以“改变”的方式是删除然后再插入。这是一个常问问题,所以要注意开始就要让行键正确(且/或在插入很多数据之前)。

行键和region split的关系
如果已经 pre-split (预裂)了表,接下来关键要了解行键是如何在region边界分布的。pre-split时要注意使得所有的region都能在键空间中找到对应。

建议

开启压缩和编码。根据使用场景设置TTL和版本数。

升级为HBase2.0的版本。针对场景进行配置优化(读场景多,还是写场景多),建议尽量批量读写,也可以设置读写分离。
使用预分区,可以根据业务自定义预分区的RowKey,也可以使用内置的分区算法。

#常用建表语句
create ‘t3’,{NAME => ‘f1’,COMPRESSION => ‘snappy’ }, { NUMREGIONS => 50, SPLITALGO => ‘HexStringSplit’ }

在真正使用HBase时,监控则成了第一要务。和大多数分布式服务一样,HBase服务器宕机会有多米诺骨牌效应。如果一台服务器因内存不足开始swap数据,它会失去和Master的联系,这时Master会命令其他服务器接过这部分请求,可能会导致第二台服务器也发生宕机。所以,你需要密切监控服务器的CPU、I/O以及网络延迟,确保每台HBase服务器都在良好地工作。监控对于维护HBase集群的健康至关重要。

HBase作为JAVA性存储系统,大容量的内存堆使得YoungGC、FullGC的停顿成为我们一直以来挥之不去的痛苦。HBase内部的写缓冲Memstore和读缓存BlockCache是造成GC停顿的最大源头。导致业务系统在读取HBase数据时,由于GC会导致读取抖动到100-200ms。hbase2.0读写链路 Off-heap主要就是优化GC的问题。

当HBase集群中的一个RegionServer崩溃(如RegionServer进程挂掉)后,此时该RegionServer和Zookeeper集群的Server间的Socket连接会断开,但是二者之间的Session由于有超时时间的存在而不会立即被删除,需要等到Session超时之后才会被Zookeeper集群删除,只有Session超时了Zookeeper集群才会删除该RegionServer启动时创建的临时节点。只有Zookeeper集群中代表此RegionServer的节点删除后,HMaster才可以得知该RegionServer发生故障,才能启动故障恢复流程。HMaster恢复故障时,将故障RegionServer所管理的Region一个一个重新分配到集群中。Session Timeout的存在使得HMaster无法立即发现故障RegionServer,从而延迟了故障的恢复时间,间接增加了业务中断的时间。同时,HMaster重新分配Region的处理过程效率太低,尤其是Region数目很大时,可能需要1到2分钟,所以说HBase一直是一个CP(Consistency&Partition tolerance)系统。
hbase2.0的Region Replica功能给HBase用户带来了高可用的读能力,提高了HBase的可用性,但同时也存在一定的缺点:
高可用的读基于Timeline consistency,用户需要接受非强一致性读才能开启这个功能
使用Replication来做数据同步意味着额外的CPU,带宽消耗,同时根据replica的多少,可能会有数倍的memstore内存消耗
读取replica region中的block同样会进block cache(如果表开启了block cache的话),这意味着数倍的cache开销
客户端Timeline consistency读可能会把请求发往多个replica,可能带来更多的网络开销
Region Replica只带来了高可用的读,宕机情况下的写,仍然取决于主region的恢复时间,因此MTTR时间并没有随着使用Region replica而改善。虽然说region replica的作者在规划中有写计划在宕机时把一个replica提升为主,来优化MTTR时间,但截至目前为止,还没有实现。

HBase2.0版本目前已经在阿里云提供商业化服务,云HBase版本与自建HBase相比在运维、可靠性、性能、稳定性、安全、成本等方面均有很多的改进。建议可以考虑使用阿里云HBase。