一.HBase管理
1.Region管理
一个Region就是一个表的一段Rowkey的数据集合。Hbase设计中,当某个Region太大的时候Hbase就会拆分它。
那么为什么要拆分Region?
- 因为当某个 Region 太大的时候读取效率太低了。
为什么从 MySQL、Oracle 转移到 NoSQL 来?
- 最根本的原因就是这些关系型数据库把数据放到一个地方,查询的本质其实也就是遍历 key;而当数据增大到上亿的时候同一个磁盘已经无法应付这些数据的读取了,因为遍历一遍数据的时间实在太长了
- NoSQL就是其能把大数据分拆到不同的机器上,然后就像查询一个完整的数据一样查询他们。但是当你的 Region 太大的时候,此时这个 Region 一样会遇到跟传统关系型数据库一样的问题,所以 HBase会拆分 Region。
Region 的拆分分为自动拆分和手动拆分
1.1Region的自动拆分
(1)ConstantSizeRegionSplitPolicy
在 0.94 版本的时候 HBase 只有一种拆分策略
- 拆分策略:按照固定大小来拆分 Region
- 拆分参数:
hbase.hregion.max.filesize
——Region 的最大大小。默认是 10GB
当单个 Region 大小超过了 10GB,就会被 HBase 拆分成为 2 个 Region
(2)IncreasingToUpperBoundRegionSplitPolicy(0.94 版本后默认)
-
拆分策略:是限制不断增长的文件尺寸
-
拆分参数:
Math.min(tableRegionsCounts^3 * initialSize,defaultRegionMaxFileSize)
来计算文件尺寸的上限增长
-
tableRegionCount:表在所有 RegionServer 上所拥有的 Region 数量总和
-
initialSize:如果定义了 hbase.increasing.policy.initial.size,则使用这个数值。如 果 没 有 定 义 , 就 用 memstore 的 刷 写 大 小 的 2 倍 ,hbase.hregion.memstore.flush.size * 2
-
defaultRegionMaxFileSize:ConstantSizeRegionSplitPolicy 所 用 到 的hbase.hregion.max.filesize,即 Region 最大大小
假如 hbase.hregion.memstore.flush.size 定义为 128MB,那么文件尺寸的上限增长将是这样:
-
-
刚 开 始 只 有 一 个 region 的 时 候 , 上 限 是 256MB ,因为 1^3 *128*2=256MB。
-
当有 2 个 region 的时候,上限是 2GB,因为 2^3 * 128*2=2048MB。
-
当有 3 个文件的时候,上限是 6.75GB,因为 3^3 * 128 * 2=6912MB。
-
以此类推,直到计算出来的上限达到 hbase.hregion.max.filesize 所定义region 的 10GB。
当 Region 个数达到 4 个的时候由于计算出来的上限已经达到了 16GB,已经大于 10GB 了,所以后面当 Region 数量再增加的时候文件大小上限已经不会增加了。在最新的版本里 IncreasingToUpperBoundRegionSplitPolicy 是默认的配置
(3)KeyPrefixRegionSplitPolicy
除了简单粗暴地根据大小来拆分,我们还可以自己定义拆分点。KeyPrefixRegionSplitPolicy 是 IncreasingToUpperBoundRegionSplitPolicy 的子类,在前者的基础上,增加了对拆分点(splitPoint,拆分点就是 Region 被拆分处的rowkey)的定义。它保证了有相同前缀的 rowkey 不会被拆分到两个不同的 Region 里面
- 拆分策略:增加了对拆分点
- 拆分参数:
KeyPrefixRegionSplitPolicy.prefix_length
——rowkey 的前缀长度 - 使用场景:数据有多种前缀。
该策略会根据 KeyPrefixRegionSplitPolicy.prefix_length 所定义的长度来截取rowkey 作为分组的依据,同一个组的数据不会被划分到不同的 Region 上。比如rowKey 都是 16 位的,指定前 5 位是前缀,那么前 5 位相同的 rowKey 在进行 region split 的时候会分到相同的 region 中
如果你的所有数据都只有一两个前缀,那么 KeyPrefixRegionSplitPolicy 就无效了,此时采用默认的策略较好。如果你的前缀划分的比较细,你的查询就比较容易发生跨 Region 查询的情况,此时采用 KeyPrefixRegionSplitPolicy 较好。
(4)DelimitedKeyPrefixRegionSplitPolicy
- 拆分策略:增加了对拆分点
- 拆分参数:
DelimitedKeyPrefixRegionSplitPolicy.delimiter
——前缀分隔符 - 使用场景:定义长度字符前缀的自由
该策略也是继承自 IncreasingToUpperBoundRegionSplitPolicy,它也是根据你的 rowkey 前缀来进行切分的。唯一的不同就是:KeyPrefixRegionSplitPolicy 是根据 rowkey 的固定前几位字符来进行判断,而 DelimitedKeyPrefixRegionSplitPolicy是根据分隔符来判断的。有时候 rowkey 的前缀可能不一定都是定长的,比如你拿服务器的名字来当前缀,有的服务器叫 host12 有的叫 host1。这些场景下严格地要求所有前缀都定长可能比较难,而且这个定长如果未来想改也不容易。DelimitedKeyPrefixRegionSplitPolicy 就给了你一个定义长度字符前缀的自由。使用
这个策略需要在表定义中加入以下属性:
DelimitedKeyPrefixRegionSplitPolicy.delimiter:前缀分隔符。比如你定义了前缀分隔符为_,那么 host1_001 和 host12_999 的前缀就分别是 host1 和 host12。
(5)BusyRegionSplitPolicy
-
拆分策略:增加了对拆分点
-
拆分参数:
hbase.busy.policy.blockedRequests
——请求阻塞率,即请求被阻塞的严重程度。取值范围是 0.0~1.0,默认是 0.2,即 20%的请求被阻塞的意思hbase.busy.policy.minAge
——拆分最小年龄。当 Region 的年龄比这个小的时候不拆分,这是为了防止在判断是否要拆分的时候出现了短时间的访问频率波峰,结果没必要拆分的 Region 被拆分了,因为短时间的波峰会很快地降回到正常水平。单位毫秒,默 认值是 600000,即 10 分钟。
hbase.busy.policy.aggWindow
——计算是否繁忙的时间窗口,单位毫秒