赞
踩
摘录自《HBase 权威指南》
HBase 内置的处理拆分和合并的机制一般是合理的,并且它们按照预期处理任务,但在某些情况下,还是需要按照应用需求对这部分功能进行优化以获得额外的性能改善。
通常 HBase 是自动处理 region 拆分的:一旦它们达到了既定的阈值,region 将被拆分成两个,之后它们可以接受新的数据并继续增长。这个默认行为能满足大多数用例的需求。但是其中一种可能出现问题的情况被称为“拆分/合并风暴”:当用户的 region 大小以恒定的速度保持增长时,region 拆分会在同一时间发生,因为同时需要压缩 region 中的存储文件,这个过程会重写拆分之后的 region,这将会引起磁盘 I/O 上升。
与其依赖 HBase 自动管理拆分,用户还不如关闭这个行为然后手动调用 split 和 major_compact 命令。用户可以通过设置这个集群的 hbase.hregion.max.filesize 值或者在列族级别把表模式中对应参数设置成非常大的值来完成。为防止手动拆分无法运行,最好不要将其设置为 Long.MAX_VALUE。用户最好将这个值设置为一个合理上限,例如,100GB(如果触发的话将会导致一个小时的 major 合并)。
手动运行命令来拆分和压缩 region 的好处是可以对它们进行时间控制。在不同 region 上交错运行,这样可以尽可能分散 I/O 负载,并且可以避免拆分/合并风暴。用户可以实现一个,调用 split() 和 majorCompact() 方法的客户端,也可以使用 Shell 命令交互地调用相关命令,或者使用 cron 定时地运行它们。
另外一个手动管理拆分的优势是用户能够更好地在任意时间控制哪些 region 可用。这对于用户需要解决底层 bug 这种少数情况来说是十分有用的,例如,排查某一个 region 的问题。在使用自动拆分时,用户可能发现要检查的 region 已经被两个拆分后的子 region 替代了。这些子 region 有新的名字,并且客户端需要大量的时间更新定位 region,这使得查询所需要的信息变得更加困难。
可以缓解这种现象的途径就是手动地将热点 region 按特定的边界拆分成一个或多个新 region,然后将子 region 负载分布到多个 region 服务器上。用户可以为 region 指定一个拆分行键,即 region 被拆分为两部分的位置;也可以指定 region 中任意的行键,这样可以生成完全不同的两个 region。这个只能在处理非完全连续的行键范围时起作用,因为采用连续的行键时,过一段时间插入的数据总会集中到最近生成的几个 region 上。
对于拥有很多 region 的表来说,大部分 region 分布并不均匀,即大多数 region 位于同一个 region 服务器上。这就意味着,即使用随机的 key 来写入数据,某一台 region 服务器的负载仍大于其它的 region 服务器。用户可以从 HBase Shell 或者使用 HBaseAdmin 类中的 API,并通过 move() 函数显示地把 region 从一个 region 服务器移动到另一个 region 服务器。另外一个方法就是使用 unassgin() 方法或者 Shell 命令简单地从当前服务器移除受影响的表的 region,master 会立即将其部署到其它 region 服务器上。
管理拆分能够在集群负载增加时有效地进行负载控制。但是,用户仍然会面临的一个问题是,在用户初始创建一个新表之后,用户需要频繁地拆分 region,因为建立的新表通常只有一个 region,不推荐让单个 region 增长到太大。因此,在表创建时,最好就有较大数量的 region。用户可以在创建表时指定需要的 region 数目来达到预拆分的目的。
管理接口中的 createTable() 方法和 Shell 中的 create 命令都可以接受以列表形式提供的拆分行键作为参数,该参数在创建表的时候会被用来预拆分 region。
例如使用 Shell 的 create 命令:
hbase(main):001:0> create 'testtable','cf1',{SPLITS => ['row-100','row-200','row-300','row-400']}
0 row(s) in 1.4870 seconds
=> Hbase::Table - testtable
这将生成以下的 region,可以使用在hbase shell 下 scan ‘hbase:meta’,FILTER => “PrefixFilter (‘testtable’)” 查看:
表名,region startKey,创建时间.hash值
testtable,,1591710550406.59ce5ddd99780faf22cf0ff39352774d.
testtable,row-100,1591710550406.d4e486efb83c91dc9c3066f4ffe4d3f7.
testtable,row-200,1591710550406.62a10ba62b27d3bc6625d8ec2b9f512e.
testtable,row-300,1591710550406.bc96221f395381cdb6329bd416fb7790.
testtable,row-400,1591710550406.845de79cc30bf9f1a27b0afe2fe7711a.
关于如何设定预拆分的 region 数量,用户可以先按照每个服务器 10 个 region 来进行预拆分,随着时间的推移观察数据的增长情况。先设置较少的 region 数目再稍后滚动拆分它们是一种更好的方法,因为过多的 region 通常会影响集群性能。另一种方法是,用户可以基于 region 中最大存储文件大小来决定预拆分 region 的数目,随着数据的增加,该大小会随之一起增加。用户希望最大的 region 正好能够跳过 major 合并,否则用户可能会面对前面提到的 compaction(压缩) 风暴。
如果用户将 region 预拆分的太小,可以通过增加 hbase.hregion.majorcompaction 的值来加大 major 合并的间隔。如果用户的数据规模增加过大,用户可以使用 RegionSplitter 工具在所有 region 上通过网络 I/O 执行安全的滚动拆分。
使用手动拆分和预拆分是高级概念,需要用户有谨慎的计划并仔细监控操作时 HBase 系统的运行情况。另一方面,这能够避免全局一致的数据增长造成的合并风暴,并可以通过手动拆分摆脱 region 热点的困扰。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。