16进制 hbase phoenix_HBase 预分区 & Phoenix 加盐

HBase 热点问题

刚创建 HBase 表的时候默认只有一个 Region 由一个 Region Server 管理,在数据量达到一定值的时候会触发分裂 split,这样会不断的分裂出更多的 Region,由不同的 Region Server 管理,每个 Region 管理的是一段连续的 row key,由 start row key 和 end row key 表示,这样会出现两个问题

无法充分利用分布式并发处理的优势,必须等待 Region 自动分裂成多个,这个过程可能会很久

由于每个 Region 管理一段连续的 row key,这样如果数据的读写不够随机,比如有自增 ID,比如大量操作集中在某段 row key,这样有可能导致压力都在同一个 Region 上

Region 分裂策略

定义在 hbase-site.xml 文件

hbase.regionserver.region.split.policy

org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy

A split policy determines when a region should be split. The various other split policies that

are available currently are ConstantSizeRegionSplitPolicy, DisabledRegionSplitPolicy,

DelimitedKeyPrefixRegionSplitPolicy, KeyPrefixRegionSplitPolicy etc.

默认策略是 IncreasingToUpperBoundRegionSplitPolicy,在 HBase 1.2 中,这个策略默认表示,当 Region 的大小达到 Region 个数的立方乘以 hbase.hregion.memstore.flush.size(默认 128 MB)再乘以 2 ,或是达到 hbase.hregion.max.filesize (默认 10 GB)时,就对该 Region 做分裂操作

第一次分裂的大小:1^3 * 128MB * 2 = 256MB

第二次分裂的大小:2^3 * 128MB * 2 = 2048MB

第三次分裂的大小:3^3 * 128MB * 2 = 6912MB

第四次分裂的大小:4^3 * 128MB * 2 = 16384MB,超过了 10GB,因此只取 10GB

后面的分裂大小都是 10GB

可以看到如果可以利用的节点比较多的话,那么可能得等很久才能充分利用

预分区

第一种预分区的方法

hbase org.apache.hadoop.hbase.util.RegionSplitter tablename HexStringSplit -c 10 -f f1:f2:f3

上面的命令表示创建一张名为 tablename 的表,这张表预先分配了 10 个 Region,有三个 CF,分别是 f1、f2、f3,预分区算法是 HexStringSplit,也可以选择 UniformSplit,其中 HexStringSplit 适合 row key 的前缀是十六进制的字符串的,UniformSplit 适合 row key 前缀完全随机的,预分区后,哪怕连续的 row key, HBase 也会通过算法将其分到不同的 Region,实现均匀分布,避免热点

第二种预分区的方法

hbase shell > create 'tablename', 'f1', SPLITS=> ['10', '20', '30', '40']

当可以提前知道 row key 的分布的时候,可以指定每个预分区的 region 的分割点,上面命令创建的表中,有 5 个 Region

Region 1 : row key 的前两位是 min~10

Region 2 : row key 的前两位是 10~20

Region 3 : row key 的前两位是 20~30

Region 4 : row key 的前两位是 30~40

Region 5 : row key 的前两位是 40~max

注意这里不单指数字字符,比如 1a 就会落在 Region 2

对已存在的表可以做强制分裂

hbase shell > split 'table', 'split point'

此外也可以设计自己的分裂方法

Phoenix 加盐

CREATE TABLE IF NOT EXISTS Product (

id VARCHAR not null,

time VARCHAR not null,

price FLOAT,

sale INTEGER,

inventory INTEGER,

CONSTRAINT pk PRIMARY KEY (id, time)

) COMPRESSION = 'GZ', SALT_BUCKETS = 6

本质上是对 HBase 表的 row key 做了哈希后,对 SALT_BUCKETS 取余数,并将结果(上面的例子中是 0~5)作为 byte 插入到 row key 的第一位,根据这个数值将数据分到不同 Region 中,由于是作为 byte 存储,所以 SALT_BUCKETS 能取的最大值是 256,拥有相同 salt byte 的 row 会被分到相同的 region server,所以通常取 region server 的数量作为 SALT_BUCKETS

由于加了盐的数据最前面多了一位,这样默认情况下,从不同 region server 取出来的数据无法按原来的 row key 排序,如果需要保证排序,需要改一个配置

phoenix.query.force.rowkeyorder = true

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值