Hbase java客户端调优——Connections

1、介绍:

大约一年前,有人要求我为一个时间序列产品调优 HBase 的读写性能。该产品在 AWS i2.4XL 中使用 10 个数据节点,并有 15 个计算节点,其中 10 个用于连续写入,5 个用于读取并运行来自这些数据节点的批处理作业。大多数计算节点都在 r3.xl 上

我们的目标是实现每分钟 1000 万个指标的提取和读取。有一些批处理作业将在协处理器内运行,用于处理这些数据节点上过去 10 分钟和 1 小时的数据。需要对整个集群进行调整。

在本文中,我将仅关注 HBase 客户端调优以及客户端面临的问题和调优方法。当然,这还需要调优 HBase 服务器端,我将在另一个主题中介绍这一点。本文将介绍以下 3 个客户端配置

  1. 不要使用单个Put,而是批量List<Put>
  2. 如何控制每个 RegionServer 的 HBase 客户端连接数/Socket 数
  3. 使用通用连接并共享池

2、开始压测:

我使用 2 Mil/min 指标进行了负载测试,运行了大约一个小时,希望这会起作用。但与大多数假设一样,这个假设也是短暂的,并经历了失败。看起来系统无法处理压力。

2.1)Call queue is full is ipc.server.max.callqueue.size too small?

当我检查日志时,我发现几乎每个计算节点都抛出了这个错误:

复制代码
java.util.concurrent.ExecutionException: java.io.IOException: Call queue is full is ipc.server.max.callqueue.size too small? ...

看起来callqueue正在排队,我应该增加这个大小吗?

从以往的经历来看:"要解决问题,总是先看大局"。原因如下:从异常来看,增加 hbase.ipc.server.max.callqueue.size大小似乎可以解决问题。但是,您需要解释或证明此更改的合理性,以及为什么默认值不够?

当阅读有关此参数的信息时,发现默认值为1G(1024*1024*1024),并且增加此值会对 HBase 内存产生一些副作用,RegionServer可能会内存不足------如果队列大小超过 1GB ,虽然区域服务器将智能地丢弃新调用,但仍可能出现 OOM。

因此,在进行此更改之前,让我们先找出为什么队列已满,或者为什么这个队列也被使用?

理论上,如果您对一个区域服务器进行大量 IPC 调用,或者所有调用都集中在一个区域服务器上,就会发生这种情况,热点?

在这种情况下,数据分布均匀,我们在这个集群上没有看到任何热点。所以我怀疑我们是否对服务器进行了大量调用?

然后我深入研究我们的代码,看到了这个:

java 复制代码
Put p = new Put(Bytes.toBytes("xxxxxx"));
p.add(Bytes.toBytes("xxxx"),  Bytes.toBytes("someQualifier"),
Bytes.toBytes("Some Value"));
table.put(p);

从上面的代码片段中,可以看到整个集群在一分钟内将执行多少个 put 操作。这里的复杂度是 O(n),在我们的例子中,O(n) 将解析为我们发送的指标数量。这里的负载是 200 万/分钟,所以在一分钟内,我们调用 put 200 万次,并且每个 read 调用也将使用自己的一组 IPC。看起来现在很明显为什么我们在每个计算节点上都会遇到异常。

这里的更改是批处理 PUT 并重新运行测试。现在,我们不再逐一写入,而是使用以下更改每 10 秒写入一次。

java 复制代码
table.put(List<Put> puts)

自从更改以来,我们从未遇到过这种异常。

2.2)SocketTimeOut:

对于 2 百万/分钟公制来说,它有效。耶!!!现在,让我们升级游戏并运行 5 mil/min 的公制负载。开始加载,一切看起来都很好,没有更多的队列大小警告或错误。但是,嘿,它又失败了!

这次集群经历了很多事情。由于所有这些问题的相关性,我将一次性涵盖所有这些问题,以下是面临的 4 个问题的列表:

  1. HBase 客户端/计算节点在写入时永远卡住,并且 HBase 客户端线程永远处于 TIMED_WAIT 状态。
  2. 在高负载的计算节点上,开始在写入和读取时抛出套接字超时。
  3. 写入和读取吞吐量缓慢。
  4. 无法达到每分钟 1000 万次的目标。

我们开始在所有计算节点上收到以下异常,这里的异常是读取,但也出现了相同的写入堆栈。

java 复制代码
2016-01-22 22:10:47.257 HBase READ-23 WARN o.a.h.hbase.client.ScannerCallable -- Ignore, probably already closed
java.net.SocketTimeoutException: Call to ip-xx-xxx-xxx-xxx/xx.xxx.xxx.xxx:60020 failed because java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannelconnected local=/xx.xxx.xxx.xxx:44064 remote=ip-xx.xxx.xxx.xxx/xx.xxx.xxx.xxx:60020
at org.apache.hadoop.hbase.ipc.RpcClient.wrapException(RpcClient.java:1486) ~hbase-client-0.98.12.1-hadoop2.jar:0.98.12.1-hadoop2
at org.apache.hadoop.hbase.ipc.RpcClient.call(RpcClient.java:1461) ~hbase-client-0.98.12.1-hadoop2.jar:0.98.12.1-hadoop2
at org.apache.hadoop.hbase.ipc.RpcClient.callBlockingMethod(RpcClient.java:1661) ~hbase-client-0.98.12.1-hadoop2.jar:0.98.12.1-hadoop2
at

为什么会出现套接字超时异常? 我能想到的这个例外有两个原因:

  1. HBase服务器读写返回慢
  2. 客户端无法连接到服务器并超时。线程/连接拥塞?

如果您遇到"1",那么增加 hbase.rpc.timeout 可能是您的解决方案,但您很可能最终也会遇到"2"。对于我们的案例 1 不是原因。怎样说呢?我们在RegionServer上启用了调试日志记录,它会打印扫描所需的时间。每次调用几乎不需要 5-10 毫秒。所以对于我们来说,HBase 服务器响应不是问题。

现在让我们关注 2,如果您使用默认的 hbase-client 属性,大多数人也会遇到这种情况。 在研究了其中一个计算节点后,我注意到 HBase 客户端默认情况下只为每个 RegionServer 创建一个连接。当负载启动并运行时,我使用以下命令查看与 RegionServer 建立的 HBase 连接数。

java 复制代码
netstat -an | grep 60020 | grep EST

令我惊讶的是,对于每个 RegionServer,该进程只建立了一个连接。这解释了超时。只有一个连接?似乎这是默认的 HBase 客户端行为。还不知道为什么?

我随后搜索了 HBase 连接设置并找到了以下属性:

java 复制代码
<property>
   <name>hbase.client.ipc.pool.type</name>
   <value>RoundRobinPool</value>
</property>
<property>
   <name>hbase.client.ipc.pool.size</name>
   <value>20</value>
</property>

这个 hbase.client.ipc.pool.size 属性有什么作用? 对于每个客户端连接,根据负载,它将创建到每个 RegionServer 的 20 个连接。并且连接将以循环方式使用。对于这个测试台,上述值已经足够好了。 我们再次搞定了它,再次运行测试,从那以后再也没有见过套接字超时异常。

HBase Tuning: Client and Connections -- Jaskirat Bhatia

相关推荐
BillKu2 分钟前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥3 分钟前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii4 分钟前
12.7Swing控件6 JList
java
全栈凯哥6 分钟前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表
YuTaoShao6 分钟前
Java八股文——集合「List篇」
java·开发语言·list
PypYCCcccCc11 分钟前
支付系统架构图
java·网络·金融·系统架构
华科云商xiao徐32 分钟前
Java HttpClient实现简单网络爬虫
java·爬虫
扎瓦1 小时前
ThreadLocal 线程变量
java·后端
BillKu1 小时前
Java后端检查空条件查询
java·开发语言
jackson凌1 小时前
【Java学习笔记】String类(重点)
java·笔记·学习