在规划 HBase 群集的容量和执行初始配置时,需要考虑几个因素。首先要充分了解 HBase 如何在内部处理数据。

160.1。节点计数和硬件/ VM 配置

160.1.1。物理数据大小

磁盘上的物理数据大小与数据的逻辑大小不同,并受以下因素影响:

  • HBase 开销增加

  • 参见 keyvaluekeysize 。每个键值(单元格)至少 24 个字节可以更多。小键/值意味着更多的相对开销。

  • KeyValue 实例聚合为块,这些块已编制索引。索引也必须存储。 Blocksize 可以基于每个 ColumnFamily 进行配置。见 regions.arch

  • 压缩和数据块编码减少,具体取决于数据。另见这个帖子。您可能希望测试哪些压缩和编码(如果有)对您的数据有意义。

  • 区域服务器 wal 的大小增加(通常固定且可忽略不计 - 小于 RS 内存大小的一半,每 RS)。

  • HDFS 复制增加 - 通常是 x3。

除了存储数据所需的磁盘空间之外,由于区域计数和大小的一些实际限制,一个 RS 可能无法提供任意大量的数据(参见 ops.capacity.regions )。

160.1.2。读/写吞吐量

节点数也可以由读取和/或写入所需的吞吐量驱动。每个节点可以获得的吞吐量很大程度上取决于数据(尤其是密钥/值大小)和请求模式,以及节点和系统配置。如果负载可能是节点数量增加的主要驱动因素,则应该针对峰值负载进行规划。 PerformanceEvaluation 和 ycsb 工具可用于测试单个节点或测试集群。

对于写入,通常每个 RS 可以达到 5-15Mb / s,因为每个区域服务器只有一个活动的 WAL。读取没有很好的估计,因为它很大程度上取决于数据,请求和缓存命中率。 perf.casestudy 可能会有帮助。

160.1.3。 JVM GC 限制

由于 GC 的成本,RS 目前无法使用非常大的堆。每个服务器运行多个 RS-es 也没有好办法(除了每台机器运行多个 VM)。因此,建议专用于一个 RS 的~20-24Gb 或更少的存储器。大堆大小需要 GC 调整。参见 gcpausetrouble.log.gc 和其他地方(TODO:哪里?)

160.2。确定区域数量和大小

通常较少的区域使得运行集群更加平滑(您可以随后手动拆分大区域(如果需要)以在集群上传播数据或请求加载);每个 RS 20-200 个区域是合理的范围。无法直接配置区域数量(除非您完全 disable.splitting );调整区域大小以达到给定表大小的目标区域大小。

为多个表配置区域时,请注意,可以通过 HTableDescriptor 以及 shell 命令在每个表的基础上设置大多数区域设置。这些设置将覆盖hbase-site.xml中的设置。如果您的表具有不同的工作负载/用例,那么这很有用。

另请注意,在这里讨论区域大小时, HDFS 复制因子不会(也不应该)被考虑在内,而其他因素 ops.capacity.nodes.datasize 应该是。 因此,如果你的数据被 HDFS 压缩和复制 3 种方式,“9 Gb 区域”意味着 9 Gb 的压缩数据。 HDFS 复制因子仅影响磁盘使用,对大多数 HBase 代码不可见。

160.2.1。查看当前的区域数量

您可以使用 HMaster UI 查看给定表的当前区域数。在“表”部分中,“在线区域”列中列出了每个表的联机区域数。此总计仅包括内存中状态,不包括禁用或脱机区域。

160.2.2。每个 RS 的区域数 - 上限

在生产场景中,如果您拥有大量数据,通常会关注每台服务器可以拥有的最大区域数。 太多地区就此问题进行了技术讨论。基本上,区域的最大数量主要由 memstore 内存使用量决定。每个地区都有自己的 memstore;它们长大到可配置的大小;通常在 128-256 MB 范围内,请参见 hbase.hregion.memstore.flush.size 。每个列族存在一个 memstore(因此,如果表中有一个 CF,则每个区域只有一个)。 RS 将总内存的一部分专用于其存储器(参见 hbase.regionserver.global.memstore.size )。如果超出此内存(memstore 使用率过高),则可能会导致不良后果,例如无响应的服务器或压缩风暴。每个 RS 的区域数量(假设一个表)的良好起点是:

((RS memory) * (total memstore fraction)) / ((memstore size)*(# column families)) 

这个公式是伪代码。以下是使用实际可调参数的两个公式,首先是 HBase 0.98+,第二个是 HBase 0.94.x.

HBase 0.98.x

((RS Xmx) * hbase.regionserver.global.memstore.size) / (hbase.hregion.memstore.flush.size * (# column families)) 

HBase 0.94.x

((RS Xmx) * hbase.regionserver.global.memstore.upperLimit) / (hbase.hregion.memstore.flush.size * (# column families))+ 

如果给定的 RegionServer 具有 16 GB 的 RAM,并且具有默认设置,则该公式可以达到 16384 * 0.4 / 128~51 个区域,每个 RS 是一个起点。公式可以扩展到多个表;如果它们都具有相同的配置,只需使用总系列数。

这个数字可以调整;上面的公式假设您所有的区域都以大致相同的速率填充。如果只有一部分区域将被主动写入,则可以将结果除以该分数以获得更大的区域计数。然后,即使写入所有区域,也不会均匀地填充所有区域存储器,并且最终出现抖动,即使它们是(由于并发刷新的数量有限)。因此,人们可以拥有比起点多 2-3 倍的区域;然而,增加的数字会增加风险。

对于写入繁重的工作负载,可以在配置中增加 memstore 分数,但代价是块缓存;这也将允许一个人拥有更多的地区。

160.2.3。每个 RS 的区域数 - 下限

HBase 通过跨多个服务器的区域来扩展。因此,如果您有 16 个数据的 2 个区域,则在 20 节点计算机上,您的数据将集中在几台计算机上 - 几乎整个群集都将处于空闲状态。这真的不够强调,因为一个常见的问题是将 200MB 数据加载到 HBase 中,然后想知道为什么你真棒的 10 节点集群没有做任何事情。

另一方面,如果您拥有大量数据,您可能还需要选择更多区域以避免区域过大。

160.2.4。最大区域大小

对于生产场景中的大型表,最大区域大小主要受到压缩的限制 - 非常大的压缩,尤其是压缩。 major,会降低集群性能。目前,推荐的最大区域大小为 10-20Gb,最佳区域为 5-10Gb。对于较早的 0.90.x 代码库,regionsize 的上限约为 4Gb,默认值为 256Mb。

区域分成两部分的大小通常通过 hbase.hregion.max.filesize 配置;有关详细信息,请参阅 arch.region.splits

如果你不能很好地估计表的大小,那么在开始时,最好坚持使用默认的区域大小,对于热表可能会更小(或者手动拆分热区以将负载分散到集群上),或者与如果您的细胞大小往往较大(100k 及以上),则区域尺寸较大。

在 HBase 0.98 中,添加了实验条带压缩功能,允许更大的区域,特别是对于日志数据。见 ops.stripe

160.2.5。每个区域服务器的总数据大小

根据区域大小和每个区域服务器区域数量的上述数字,在乐观估计中,每个 RS 10 GB×100 个区域将为每个区域服务器提供高达 1TB 的服务,这与一些报告的多 PB 用例一致。但是,重要的是要考虑 RS 级别的数据与缓存大小比率。每个服务器有 1TB 的数据和 10 GB 的块缓存,只有 1%的数据会被缓存,这几乎不能覆盖所有的块索引。

160.3。初始配置和调整

首先,参见重要配置。请注意,某些配置(多于其他配置)取决于特定方案。特别注意:

  • hbase.regionserver.handler.count - 请求处理程序线程数,对高吞吐量工作负载至关重要。

  • config.wals - WAL 文件的阻塞数量取决于您的 memstore 配置,应相应地设置以防止在执行大量写入时可能阻塞。

然后,在设置群集和表时需要考虑一些因素。

160.3.1。 Compactions

根据读/写卷和延迟要求,最佳压缩设置可能不同。有关详细信息,请参见压缩

但是,在为大数据量配置时,请记住压缩会影响写入吞吐量。因此,对于写入密集型工作负载,您可以选择较少频繁的压缩和每个区域的更多存储文件。压缩的最小文件数(hbase.hstore.compaction.min)可以设置为更高的值; hbase.hstore.blockingStoreFiles 也应该增加,因为在这种情况下可能会累积更多文件。您也可以考虑手动管理压缩: managed.compactions

160.3.2。预分割表格

根据每个 RS 的区域的目标数量(参见 ops.capacity.regions.count )和 RS 的数量,可以在创建时预分割表。当表开始填满时,这将避免一些昂贵的拆分,并确保表已经分布在许多服务器上。

如果预计该表会增长到足以证明其合理性,则应创建每个 RS 至少一个区域。不建议立即分成完整目标区域数(例如 50 * RSes 数),但可以选择低中间值。对于多个表,建议保守预分裂(例如,每个 RS 最多预分割 1 个区域),特别是如果您不知道每个表将增长多少。如果分割太多,最终可能会出现太多区域,某些表区域的区域太多。

对于预分割方法,请参见手动区域分割决策precreate.regions