如果您遇到性能问题,邮件列表可以提供帮助。例如,这里是关于解决读取时间问题的一个很好的通用线程: HBase 随机读取延迟> 100 毫秒

122.1。扫描缓存

例如,如果将 HBase 用作 MapReduce 作业的输入源,请确保 MapReduce 作业的输入 Scan 实例将setCaching设置为大于默认值(即 1)的值。使用默认值意味着 map-task 将为处理的每个记录回调 region-server。例如,将此值设置为 500 将一次传输 500 行到要处理的客户端。缓存值很大是有成本/收益的,因为客户端和 RegionServer 的内存成本更高,因此更大并不总是更好。

122.1.1。在 MapReduce 作业中扫描缓存

MapReduce 作业中的扫描设置值得特别注意。如果在客户端返回到 RegionServer 以获取下一组数据之前处理一批记录需要更长时间,则可能会在 Map 任务中导致超时(例如,UnknownScannerException)。发生此问题的原因是每行发生非平凡处理。如果快速处理行,请将缓存设置得更高。如果您更慢地处理行(例如,每行进行大量转换,写入),则将缓存设置得更低。

超时也可能发生在非 MapReduce 用例(即执行扫描的单线程 HBase 客户端)中,但通常在 MapReduce 作业中执行的处理往往会加剧此问题。

122.2。扫描属性选择

每当使用扫描处理大量行(特别是用作 MapReduce 源)时,请注意选择了哪些属性。如果调用scan.addFamily,则 _ 指定 ColumnFamily 中属性的所有 _ 将返回给客户端。如果只处理少量可用属性,则只应在输入扫描中指定那些属性,因为属性过度选择对大型数据集而言是一个非常重要的性能损失。

122.3。避免扫描寻求

当使用scan.addColumn显式选择列时,HBase 将调度搜索操作以在所选列之间进行搜索。当行包含很少的列而每列只有几个版本时,这可能效率很低。如果不寻求至少过去 5-10 列/版本或 512-1024 字节,则查找操作通常较慢。

为了机会性地向前看几个列/版本以查看在调度搜索操作之前是否可以找到下一列/版本,可以在 Scan 对象上设置新属性Scan.HINT_LOOKAHEAD。以下代码指示 RegionServer 在调度搜索之前尝试下一次迭代:

Scan scan = new Scan();
scan.addColumn(...);
scan.setAttribute(Scan.HINT_LOOKAHEAD, Bytes.toBytes(2));
table.getScanner(scan); 

122.4。 MapReduce - 输入拆分

对于使用 HBase 表作为源的 MapReduce 作业,如果存在“慢”映射任务似乎具有相同输入拆分的模式(即,为服务数据提供服务的 RegionServer),请参阅案例研究中的故障排除案例研究#1(单节点上的性能问题)

122.5。关闭 ResultScanners

这不是提高性能,而是 _ 避免 _ 性能问题。如果您忘记关闭 ResultScanners ,可能会导致 RegionServers 出现问题。始终将 ResultScanner 处理包含在 try / catch 块中。

Scan scan = new Scan();
// set attrs...
ResultScanner rs = table.getScanner(scan);
try {
  for (Result r = rs.next(); r != null; r = rs.next()) {
  // process result...
} finally {
  rs.close();  // always close the ResultScanner!
}
table.close(); 

122.6。块缓存

Scan 实例可以通过setCacheBlocks方法设置为使用 RegionServer 中的块缓存。对于输入扫描到 MapReduce 作业,这应该是false。对于频繁访问的行,建议使用块缓存。

通过在堆外移动块缓存来缓存更多数据。请参阅堆外块缓存

122.7。行密钥的最佳加载

执行仅需要行键的表扫描时(无族,限定符,值或时间戳),使用setFilter将带有MUST_PASS_ALL运算符的 FilterList 添加到扫描仪。过滤器列表应包括 FirstKeyOnlyFilterKeyOnlyFilter 。使用此过滤器组合将导致 RegionServer 读取磁盘中的单个值以及单个行的客户端最小网络流量的最坏情况。

122.8。并发:监控数据传播

执行大量并发读取时,监视目标表的数据传播。如果目标表具有太少的区域,则可能从太少的节点提供读取。

See Table Creation: Pre-Creating Regions, as well as HBase Configurations

122.9。布隆过滤器

启用 Bloom 过滤器可以节省您必须转到磁盘并有助于改善读取延迟。

Bloom 过滤器是在 HBase-1200 Add bloomfilters 中开发的。有关开发过程的描述 - 为什么是静态绽放而不是动态 - 以及有关 HBase 中的绽放的独特属性的概述,以及可能的未来方向,请参阅文档的 _ 开发过程 _ 部分 HBase 中的 BloomFilters 附着于 HBASE-1200 。这里描述的布隆过滤器实际上是 HBase 中的第二版布隆。在高达 0.19.x 的版本中,HBase 根据欧盟委员会一个实验室项目 034819 所做的工作有一个动态绽放选项。 HBase bloom 工作的核心后来被引入 Hadoop 以实现 org.apache.hadoop.io.BloomMapFile。 HBase 绽放的第 1 版从未如此顺利。版本 2 是从头开始重写,但它再次从单实验室工作开始。

另请参见布隆过滤器

122.9.1。 Bloom StoreFile 足迹

布隆过滤器向StoreFile通用FileInfo数据结构添加条目,然后向StoreFile元数据部分添加两个额外条目。

StoreFile``FileInfo数据结构中的 BloomFilter

FileInfo有一个BLOOM_FILTER_TYPE条目,设置为NONEROWROWCOL.

StoreFile元数据中的 BloomFilter 条目

BLOOM_FILTER_META保存 Bloom Size,使用的哈希函数等。它的大小很小,并且在StoreFile.Reader加载时缓存

BLOOM_FILTER_DATA是实际的 bloomfilter 数据。按需获得。存储在 LRU 缓存中,如果已启用(默认情况下已启用)。

122.9.2。布隆过滤器配置

io.storefile.bloom.enabled全局杀戮开关

如果出现问题,Configuration中的io.storefile.bloom.enabled将作为终止开关。默认= true

io.storefile.bloom.error.rate

io.storefile.bloom.error.rate =平均误报率。默认值= 1%。每个布鲁德条目减少½(例如降至 0.5%)== +1 比特。

io.storefile.bloom.max.fold

io.storefile.bloom.max.fold =保证最低折叠率。大多数人应该单独留下这个。默认值= 7,或者可以折叠到原始大小的至少 1/128。有关此选项的含义的更多信息,请参阅 HBase 文档 BloomFilters 的 _ 开发过程 _ 部分。

122.10。对冲读数

对冲读取是 HDFS 的一个特性,在 Hadoop 2.4.0 中引入了 HDFS-5776 。通常,为每个读取请求生成一个线程。但是,如果启用了对冲读取,则客户端会等待一些可配置的时间,如果读取未返回,则客户端会针对相同数据的不同块副本生成第二个读取请求。无论先使用哪个读取返回,都会丢弃另一个读取请求。

对冲读取是“......非常擅长消除异常数据节点,这反过来使它们成为延迟敏感设置的非常好的选择。但是,如果您正在寻找最大化吞吐量,对冲读取往往会产生负载放大,因为一般情况下变慢。简而言之,需要注意的是当您运行接近某个吞吐量阈值时,非优雅的性能下降。“ (引自 Ashu Pachauri 的 HBASE-17083)。

在启用对冲读取的情况下运行时要记住的其他问题包括:

  • 它们可能导致网络拥塞。见 HBASE-17083

  • 确保将线程池设置得足够大,以便池上的阻塞不会成为瓶颈(再次参见 HBASE-17083

(来自 HBASE-17083 的 Yu Li)

由于 HBase RegionServer 是 HDFS 客户端,因此您可以在 HBase 中启用对冲读取,方法是将以下属性添加到 R​​egionServer 的 hbase-site.xml 并调整值以适合您的环境。

对冲读数的配置

  • dfs.client.hedged.read.threadpool.size - 专用于服务对冲读取的线程数。如果将其设置为 0(默认值),则禁用对冲读取。

  • dfs.client.hedged.read.threshold.millis - 产生第二个读取线程之前等待的毫秒数。

例 39.对冲读取配置示例

<property>
  <name>dfs.client.hedged.read.threadpool.size</name>
  <value>20</value>  <!-- 20 threads -->
</property>
<property>
  <name>dfs.client.hedged.read.threshold.millis</name>
  <value>10</value>  <!-- 10 milliseconds -->
</property> 

使用以下指标调整群集上对冲读取的设置。有关详细信息,请参阅 HBase 指标

对冲读数的指标

  • hedgedReadOps - 已触发对冲读取线程的次数。这可能表明读取请求通常很慢,或者对冲读取的触发过快。

  • hedgeReadOpsWin - 对冲读取线程比原始线程快的次数。这可能表示给定的 RegionServer 在处理请求时遇到问题。