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

相关推荐
希忘auto21 分钟前
详解Servlet的使用
java·servlet·tomcat
ygl61503731 小时前
Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统
java·spring boot·vue
Code哈哈笑1 小时前
【Java 学习】构造器、static静态变量、static静态方法、static构造器、
java·开发语言·学习
是老余1 小时前
Java三大特性:封装、继承、多态【详解】
java·开发语言
鸽鸽程序猿1 小时前
【JavaEE】Maven的介绍及配置
java·java-ee·maven
尘浮生2 小时前
Java项目实战II基于微信小程序的南宁周边乡村游平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·微信小程序·小程序·maven
耀耀_很无聊6 小时前
第1章 初识SpringMVC
java·spring·mvc
麻衣带我去上学6 小时前
Spring源码学习(一):Spring初始化入口
java·学习·spring
东阳马生架构6 小时前
MySQL底层概述—1.InnoDB内存结构
java·数据库·mysql
手握风云-7 小时前
数据结构(Java版)第一期:时间复杂度和空间复杂度
java·数据结构