HBase

HBase架构及各节点的作用

  • HMaster的作用:维护表和region的元数据,对表模式的操作,为HRegionServer分配Region
    负责管理HBase元数据,即表的结构、表存储的Region等元信息。
    负责表的创建,删除和修改(因为这些操作会导致HBase元数据的变动)。
    负责为HRegionServer分配Region,分配好后也会将元数据写入相应位置(后面会详细讲述放在哪)。

  • HRegionServer作用:
    处理Client端的读写请求(根据从HMaster返回的元数据找到对应的Region来读写数据)。
    管理Region的分裂、StoreFile的Compaction合并。

HBase读写

参考文献:
[1] HBase系列(二):HBase架构及读写流程
[2] HBase:数据读写基本流程


  • Client访问ZK,根据ROOT表获取meta表所在Region的位置信息,并将该位置信息写入Client Cache。
    (注:为了加快数据访问速度,我们将元数据、Region位置等信息缓存在Client Cache中。)
    .
    Client读取meta表,再根据meta表中查询得到的Namespace、表名和RowKey等相关信息,获取将要写入Region的位置信息(此过程即Region三层定位,如下图),最后client端会将meta表写入Client Cache。
    .
    Client向上一步HRegionServer发出写请求,HRegionServer先将操作和数据写入HLog(预写日志,Write Ahead Log,WAL),再将数据写入MemStore,并保持有序。
    (联想:HDFS中也是如此,EditLog写入时机也是在真实读写之前发生)
    .
    当MemStore的数据量超过阈值时,将数据溢写磁盘,生成一个StoreFile文件。
    当Store中StoreFile的数量超过阈值时,将若干小StoreFile合并(Compact)为一个大StoreFile。
    当Region中最大Store的大小超过阈值时,Region分裂(Split),等分成两个子Region。

  • 1,Client先访问zookeeper,从meta表读取region的位置,然后读取meta表中的数据。meta中又存储了用户表的region信息。
    2,根据namespace、表名和rowkey在meta表中找到对应的region信息
    3,找到这个region对应的regionserver
    4,查找对应的region
    5,先从MemStore找数据,如果没有,再到StoreFile上读(为了读取的效率)。
  • 读 简版:
    获取将要读取Region的位置信息(同读的1、2步)。
    Client向HRegionServer发出读请求。
    HRegionServer先从MemStore读取数据,如未找到,再从StoreFile中读取。

1 HBase预分区

1.1 为什么要进行预分区?

为了解决“热点问题”。

热点问题:在HBase中查询数据时,需要通过RowKey定位数据行。当大量客户端访问少数几个结点,造成少数RegionServer的读写请求过多,而其他RegionServer负载却很小,就造成了“热点”现象。

热点问题出现的原因:
hbase的中的数据行,按照行键的字典序排序,当大量连续的rowkey集中写在个别的region,各个region之间数据分布不均衡;

1.2 怎么进行预分区?

通过设计RowKey,进行预分区。

1.2.1 常用方法

参考自:hbase热点问题解决(预分区)

  1. 第一种设计rowkey方式:随机数+messageId,如果想让最近的数据快速get到,可以将时间戳加上。

  2. 第二种设计rowkey的方式:通过messageId映射regionNo,这样既可以让数据均匀分布到各个region中,同时可以根据startkey和endkey可以get到同一批数据
    messageId映射regionNo,使用一致性hash算法解决。
    什么是一致性hash算法?参考:五分钟理解一致性哈希算法(consistent hashing)

1.2.2 大部分方法

下面是一些常见的避免热点的方法以及它们的优缺点:参考自Hbase中的rowkey以及热点问题阿里云-RowKey表设计

  • 加盐
    这里所说的加盐不是密码学中的加盐,而是在rowkey的前面增加随机数,具体就是给rowkey分配一个随机前缀以使得它和之前的rowkey的开头不同。给多少个前缀?这个数量应该和我们想要分散数据到不同的region的数量一致(类似hive里面的分桶)。加盐之后的rowkey就会根据随机生成的前缀分散到各个region上,以避免热点。

  • 哈希
    哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的rowkey,可以使用get操作准确获取某一个行数据。

  • 反转
    第三种防止热点的方法是反转固定长度或者数字格式的rowkey。这样可以使得rowkey中经常改变的部分(最没有意义的部分)放在前面。这样可以有效的随机rowkey,但是牺牲了rowkey的有序性。
    .
    反转rowkey的例子:以手机号为rowkey,可以将手机号反转后的字符串作为rowkey,从而避免诸如139、158之类的固定号码开头导致的热点问题。

  • 时间戳反转
    一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为rowkey的一部分对这个问题十分有用,可以用Long.Max_Value - timestamp追加到key的末尾,例如[key][reverse_timestamp] ,[key] 的最新值可以通过scan [key]获得[key]的第一条记录,因为HBase中rowkey是有序的,第一条记录是最后录入的数据。

  • 尽量减少行和列的大小
    在HBase中,value永远和它的key一起传输的。当具体的值在系统间传输时,它的rowkey,列名,时间戳也会一起传输。如果你的rowkey和列名很大,HBase storefiles中的索引(有助于随机访问)会占据HBase分配的大量内存,因为具体的值和它的key很大。可以增加block大小使得storefiles索引再更大的时间间隔增加,或者修改表的模式以减小rowkey和列名的大小。压缩也有助于更大的索引。

  • 其他办法
    列族名的长度尽可能小,最好是只有一个字符。冗长的属性名虽然可读性好,但是更短的属性名存储在HBase中会更好。也可以在建表时预估数据规模,预留region数量,例如create 'myspace:mytable’, SPLITS => [01,02,03,…99]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张之海

若有帮助,客官打赏一分吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值