关于程序员:Apache-HBase-MTTR-优化实践

51次阅读

共计 8302 个字符,预计需要花费 21 分钟才能阅读完成。

HBase 介绍

HBase 是 Hadoop Database 的简称,是建设在 Hadoop 文件系统之上的分布式面向列的数据库,它具备高牢靠、高性能、面向列和可伸缩的个性,提供疾速随机拜访海量数据能力。

HBase 采纳 Master/Slave 架构,由 HMaster 节点、RegionServer 节点、ZooKeeper 集群组成,底层数据存储在 HDFS 上。

整体架构如图所示:

HMaster 次要负责:

  • 在 HA 模式下,蕴含主用 Master 和备用 Master。
  • 主用 Master:负责 HBase 中 RegionServer 的治理,包含表的增删改查;RegionServer 的负载平衡,Region 散布调整;Region 决裂以及决裂后的 Region 调配;RegionServer 生效后的 Region 迁徙等。
  • 备用 Master:当主用 Master 故障时,备用 Master 将取代主用 Master 对外提供服务。故障复原后,原主用 Master 降为备用。

RegionServer 次要负责:

  • 寄存和治理本地 HRegion。
  • RegionServer 负责提供表数据读写等服务,是 HBase 的数据处理和计算单元,间接与 Client 交互。
  • RegionServer 个别与 HDFS 集群的 DataNode 部署在一起,实现数据的存储性能。读写 HDFS,治理 Table 中的数据。

ZooKeeper 集群次要负责:

  • 寄存整个 HBase 集群的元数据以及集群的状态信息。
  • 实现 HMaster 主从节点的 Failover。

HDFS 集群次要负责:

  • HDFS 为 HBase 提供高牢靠的文件存储服务,HBase 的数据全副存储在 HDFS 中。

构造阐明:

Store

  • 一个 Region 由一个或多个 Store 组成,每个 Store 对应图中的一个 Column Family。

MemStore

  • 一个 Store 蕴含一个 MemStore,MemStore 缓存客户端向 Region 插入的数据,当 RegionServer 中的 MemStore 大小达到配置的容量下限时,RegionServer 会将 MemStore 中的数据“flush”到 HDFS 中。

StoreFile

  • MemStore 的数据 flush 到 HDFS 后成为 StoreFile,随着数据的插入,一个 Store 会产生多个 StoreFile,当 StoreFile 的个数达到配置的阈值时,RegionServer 会将多个 StoreFile 合并为一个大的 StoreFile。

HFile

  • HFile 定义了 StoreFile 在文件系统中的存储格局,它是以后 HBase 零碎中 StoreFile 的具体实现。

HLog(WAL)

  • HLog 日志保障了当 RegionServer 故障的状况下用户写入的数据不失落,RegionServer 的多个 Region 共享一个雷同的 HLog。

HBase 提供两种 API 来写入数据。

  • Put:数据间接发送给 RegionServer。
  • BulkLoad:间接将 HFile 加载到表存储门路。

HBase 为了保证数据可靠性,应用 WAL(Write Ahead Log)来保证数据可靠性。它是 HDFS 上的一个文件,记录 HBase 中数据的所有更改。所有的写操作都会先保障将数据写入这个文件后,才会真正更新 MemStore,最初写入 HFile 中。如果写 WAL 文件失败,则操作会失败。在失常状况下,不须要读取 WAL 文件,因为数据会从 MemStore 中长久化为 HFile 文件。然而如果 RegionServer 在长久化 MemStore 之前解体或者不可用,零碎依然能够从 WAL 文件中读取数据,回放所有操作,从而保证数据不失落。

写入流程如图所示:

默认状况下 RegionServer 上治理的所有 HRegion 共享同一个 WAL 文件。WAL 文件中每个记录都包含相干 Region 的信息。当关上 Region 时,须要回放 WAL 文件中属于该 Region 的记录信息。因而,WAL 文件中的记录信息必须按 Region 进行分组,以便能够回放特定 Region 的记录。按 Region 分组 WAL 的过程称为 WAL Split。

WAL Split 由 HMaster 在集群启动时实现或者在 RegionServer 敞开时由 ServershutdownHandler 实现。在给定的 Region 再次可用之前,须要复原和回放所有的 WAL 文件。因而在数据恢复之前,对应的 Region 无奈对外服务。

HBase 启动时,Region 调配简要调配流程如下:

  • HMaster 启动时初始化 AssignmentManager。
  • AssignmentManager 通过 hbase:meta 表查看以后 Region 调配信息。
  • 如果 Region 调配仍然无效(Region 所在 RegionServer 仍然在线),则保留调配信息。
  • 如果 Region 调配有效,调用 LoadBalancer 来进行重调配。
  • 调配实现后更新 hbase:meta 表。

本文次要关注集群重新启动和复原相干内容,着重形容相干优化,缩小 HBase 复原时长。

RegionServer 故障复原流程

当 HMaster 检测到故障时,会触发 SCP(Server Crash Procedure)流程。SCP 流程包含以下次要步骤:

  • HMaster 创立 WAL Split 工作,用于对属于解体 RegionServer 上 Region 进行记录分组。
  • 将原属于解体 RegionServer 上 Region 进行重调配,调配给失常 RegionServer。
  • 失常 RegionServer 执行 Region 上线操作,对须要复原数据进行回放。

故障复原常见问题

HMaster 期待 Namespace 表超时终止

当集群进行重启时,HMaster 进行初始化会找到所有的异样 RegionServer(Dead RegionServer)并开始 SCP 流程,并持续初始化 Namespace 表。

如果 SCP 列表中存在大量的 RegionServer,那么 Namespace 表的调配将可能被提早并超过配置的超时工夫(默认 5 分钟),而这种状况在大集群场景下是最常见的。为长期解决该问题,经常将默认值改大,然而必不能保障肯定会胜利。

另外一种形式是在 HMaster 上启用表来防止此问题(hbase.balancer.tablesOnMaster=hbase:namespace),HMaster 会优先将这些表进行调配。然而如果配置了其它表也能够调配到 HMaster 或者因为 HMaster 性能问题,这将无奈做到 100% 解决此问题。此外在 HBase 2.X 版本中也不举荐应用 HMaster 来启用表。解决这个问题的最佳办法是反对优先表和优先节点,当 HMaster 触发 SCP 流程时,优先将这些表调配到优先节点上,确保调配的优先级,从而齐全打消此问题。

批量调配时 RPC 超时

HBase 专门线性可扩展性而设计。如果集群中的数据随着表减少而增多,集群能够很容易扩大增加 RegionServer 来治理表和数据。例如:如果一个集群从 10 个 RegionServer 扩大到 20 个 RegionServer,它在存储和解决能力方面将会减少。

随着 RegionServer 上 Region 数量的减少,批量调配 RPC 调用将会呈现超时(默认 60 秒)。这将导致从新进行调配并最终对调配上线工夫产生重大影响。

在 10 个 RegionServer 节点和 20 个 RegionServer 节点的测试中,RPC 调用别离破费了约 60 秒和 116 秒。对于更大的集群来说,批量调配无奈一次胜利。次要起因在于对 ZooKeeper 进行大量的读写操作和 RPC 调用,用来创立 OFFLINE ZNode 节点,创立正在复原的 Region ZNode 节点信息等。

复原可扩展性测试

在 10 到 100 个节点的集群测试中,咱们察看到复原工夫随着集群规模的增大而线性减少。这意味着集群越大,复原所需的工夫就越多。特地是当要复原 WAL 文件时,复原工夫将会十分大。在 100 个节点的集群中,通过 Put 申请写入数据的状况下,复原须要进行 WAL Split 操作,发现须要 100 分钟能力从集群解体中完全恢复。而在雷同规模的集群中,如果不写入任何数据大概须要 15 分钟。这意味着 85% 以上的工夫用于 WAL Split 操作和回放用于复原。

Cluster SizeRecovered edit files countTotal No. Of regions [2k per RS]Region Assignment (with WAL split)Empty Region Assignment
10 Node4,00,00020,0007.5 Mins4 Min
20 Node8,00,00040,00012 Mins6 Mins
40 Node1.6 Million80,00042 Mins7 Mins
100 Nodes4 Million0.2 Million106 Mins15 Mins

上面咱们将分析测试过程中发现的瓶颈在哪里?

复原耗时剖析

HDFS 负载

在 10 个节点的 HBase 集群上,通过 JMX 来获取 HDFS 的 RPC 申请监控信息,发现在启动阶段有 1200 万读取 RPC 调用。

其中 GetBlockLocationNumOps:380 万、GetListingNumOps:13 万、GetFileInfoNumOps:840 万。

当集群规模达到 100 个时,RPC 调用和文件操作将会十分大,从而对 HDFS 负载造成很大压力,成为瓶颈。可能因为以下起因导致 HDFS 写入失败、WAL Split 和 Region 上线迟缓超时重试。

  • 微小的预留磁盘空间。
  • 并发拜访达到 DataNode 的 xceiver 的限度。

HMaster 负载

HMaster 应用基于 ZooKeeper 的分配机制时,在 Region 上线过程中 HMaster 会创立一个 OFFLINE ZNode 节点,RegionServer 会将该 ZNode 更新为 OPENING 和 OPENED 状态。对于每个状态变动,HMaster 都会进行监听并解决。

对于 100 个节点的 HBase 集群,大略将会有 6,000,000 个 ZNode 创立和更新操作和 4,000,000 个监听事件要进行解决。

ZooKeeper 的监听事件告诉解决是程序的,旨在保障事件的程序。这种设计在 Region 锁获取阶段将会导致提早。在 10 个节点的集群中发现等待时间为 64 秒,而 20 节点的集群中等待时间为 111 秒。
.png)

GeneralBulkAssigner 在批量发送 OPEN RPC 申请到 RegionServer 之前会获取相干 Region 的锁,再收到 RegionServer 的 OPEN RPC 申请响应时才会开释该锁。如果 RegionServer 再解决批量 OPEN RPC 申请时须要工夫,那么在收到确认响应之前 GeneralBulkAssigner 将不会开释锁,其实局部 Region 曾经上线,也不会独自解决这些 Region。

HMaster 依照程序创立 OFFLINE ZNode 节点。察看发现在执行批量调配 Region 到 RegionServer 之前将会有 35 秒的提早来创立 ZNode。
.png)

采纳不依赖 ZooKeeper 的分配机制将会缩小 ZooKeeper 的操作,能够有 50% 左右的优化。HMaster 仍然会协调和解决 Region 的调配。

晋升 WAL Split 性能

长久化 FlushedSequenceId 来减速集群重启 WAL Split 性能 (HBASE-20727)

ServerManager 有每个 Region 的 flushedSequenceId 信息,这些信息被保留在一个 Map 构造中。咱们能够利用这些信息来过滤不须要进行回放的记录。然而这个 Map 构造并没有被长久化,当集群重启或者 HMaster 重启后,每个 Region 的 flushedSequenceId 信息将会失落。

如果这些信息被长久化那么即便 HMaster 重启,这些仍然存在可用于过滤 WAL 记录,放慢复原记录和回放。hbase.master.persist.flushedsequenceid.enabled 可用于配置是否开启此性能。flushedSequenceId 信息将会定时长久化到如下目录 < habse root dir >/.lastflushedseqids。能够通过参数 hbase.master.flushedsequenceid.flusher.interval 来配置长久化距离,默认为 3 小时。

留神:此个性在 HBase 1.X 版本不可用。

改善 WAL Split 在故障切换时稳定性 (HBASE-19358)

在 WAL 记录复原期间,WAL Split 工作将会将 RegionServer 上的所有待复原记录输入文件关上。当 RegionServer 上治理的 Region 数量较多时将会影响 HDFS,须要大量的磁盘保留空间然而磁盘写入十分小。

当集群中所有 RegionServer 节点都重启进行复原时,状况将变得十分蹩脚。如果一个 RegionServer 上有 2000 个 Region,每个 HDFS 文件为 3 正本,那么将会导致每个 WAL Splitter 关上 6000 个文件。

通过启用 hbase.split.writer.creation.bounded 能够限度每个 WAL Splitter 关上的文件。当设置为 true 时,不会关上任何 recovered.edits 的写入直到在内存积攒的记录曾经达到 hbase.regionserver.hlog.splitlog.buffersize(默认 128M),而后一次性写入并敞开文件,而不是始终处于关上状态。这样会缩小关上文件流数量,从 hbase.regionserver.wal.max.splitters the number of region the hlog contains 缩小为 hbase.regionserver.wal.max.splitters hbase.regionserver.hlog.splitlog.writer.threads。

通过测试发现在 3 节点集群中,领有 15GB WAL 文件和 20K Region 的状况下,集群整体重启工夫从 23 分钟缩短为 11 分钟,缩小 50%。

hbase.regionserver.wal.max.splitters = 5

hbase.regionserver.hlog.splitlog.writer.threads= 50

WAL Split 为 HFile(HBASE-23286)

WAL 复原时应用 HFile 文件替换 Edits 文件这样能够防止在 Region 上线过程中写入。Region 上线过程中须要实现 HFile 文件校验、执行 bulkload 加载并触发 Compaction 来合并小文件。此优化能够防止读取 Edits 文件和长久化内存带来的 IO 开销。当集群中的 Region 数量较少时(例如 50 个 Region)察看发现性能有显著晋升。

当集群中有更多的 Region 时,测试发现因为大量的 HFile 写入和合并将会导致 CPU 和 IO 的减少。能够通过如下额定的措施来缩小 IO。

  • 将故障 RegionServer 作为首选 WAL Splitter,缩小近程读取。
  • 将 Compaction 提早后盾执行,放慢 region 上线解决。

Observer NameNode(HDFS-12943)

当 HBase 集群规模变大时,重启会触发大量的 RPC 申请,使得 HDFS 可能成为瓶颈,能够通过应用 Observer NameNode 累赘读申请来升高 HDFS 的负载。

总结

通过上述剖析,能够配置如下参数来晋升 HBase MTTR,尤其是在集群整体从解体中复原的状况。

ConfigurationRecommendationRemarks
HMaster hbase.master.executor.openregion.thread2 * no. of coresOpened region thread to process OPENED ZK events. Can increase based on the cores in large cluster.
HMaster hbase.assignment.zkevent.workers2 * no. of coresZK event worker thread to process RIT ZK notification, can be tuned based on cores
HMaster hbase.master.skip.log.split.tasktrueMaster participate in WAL split as namespace region is assigned to Hmaster. Hmaster may be overloaded during MTTR
HMaster hbase.balancer.tablesOnMasterhbase:namespaceAssign namespace region to Hmaster, so that HM WAL will be split first to recover namespace region and there wont be any Hmaster abort due to Namespace init timeout Note: Later this will be replaced with Assign system tables to specified RS Group
RegionServer hbase.regionserver.executor.openregion.threads2 * no. of coresHandlers to process Open region requests
RegionServer hbase.regionserver.metahandler.count5 * no. of coresMeta operation handlers. During full cluster restart, all RSs are opening the region concurrently, so we need more handlers. We observed better perf upto 400 handlers.
RegionServer hbase.regionserver.wal.max.splittersSame as hbase.regionserver.maxlogsTo perform WAL split concurrently and avoid overlap with assignment region cycle. If SCP is blocked for assignment which takes more time, WAL split would be delayed.
RegionServer hbase.regionserver.hlog.splitlog.writer.threads50Works in combination with hbase.split.writer.creation.bounded Writer thread to flush the recovered edits region wise. , can be reduced when active regions are less
RegionServer hbase.split.writer.creation.boundedtrueTo control the number of open files in HDFS for writing recovered edits. If true, edits are cached and flushed once the buffer is full.
RegionServer hbase.wal.split.to.hfiletrueWhen the active regions are less per RS, can use this configurations to reduce IO. But if the active regions are high, this feature may not have impact.
RegionServer hbase.regionserver.maxlogs20Lesser the logs, lesser the time for wal split & recovering edits
HMaster hbase.master.persist.flushedsequenceid.enabledtrueSkip WAL edits which are already flushed into Hfile
HMaster hbase.rpc.timeout120000Bulk assignment RPC gets timed out due to slow processing by RS if there are many regions in RS

本文由华为云公布

正文完
 0