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 调用,或者所有调用都集中在一个区域服务器上,就会发生这种情况,热点?

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

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

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 秒写入一次。

table.put(List<Put> puts)

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

2.2)SocketTimeOut:

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

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

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

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

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 连接数。

netstat -an | grep 60020 | grep EST

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

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

<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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/759754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试十 简单工厂、工厂方法、抽象工厂

/*简单工厂 Simple Factory&#xff1a;优点&#xff1a;把对象的创建封装在一个接口函数里面&#xff0c;通过传入不同的标识&#xff0c;返回创建的对象&#xff0c;客户不用自己负责new对象缺点 &#xff1a;提供创建对象实例的接口函数不闭合&#xff0c;不能对修改关闭&am…

Git一点通

1.Git的优势 Git是一个伟大的版本管理工具&#xff0c;比之svn&#xff0c;具有以下优势&#xff1a; 分布式版本控制&#xff1a;Git是一种分布式版本控制系统&#xff0c;每个开发者都拥有自己的完整代码库&#xff0c;不需要依赖网络连接就可以进行版本控制、合并和提交操作…

了解测试用例与测试场景

测试用例和测试场景是综合测试中最常见的两种测试工件。正确获得这两个可交付成果对于产品成功至关重要&#xff0c;因为它可以让软件开发团队和测试人员更高效地工作。然而&#xff0c;在 QA 测试中&#xff0c;测试场景和测试用例之间的差异可能会在转换过程中丢失。 测试用例…

opengl日记10-opengl使用多个纹理示例

文章目录 环境代码CMakeLists.txt文件内容不变。fragmentShaderSource.fsvertexShaderSource.vsmain.cpp 总结 环境 系统&#xff1a;ubuntu20.04opengl版本&#xff1a;4.6glfw版本&#xff1a;3.3glad版本&#xff1a;4.6cmake版本&#xff1a;3.16.3gcc版本&#xff1a;10.…

66、将同图片下的多个不同类别的xml标注文件合并成一个xml标注文件-labelImg格式

基本思想:手中有一套抽烟的数据集是labelimg格式,但是没有人物标注的数据集,因此使用自动化标注脚本将图片过滤一边,进行生成labelimg文件,只含有80类别的人物标注xml,然后使用脚本将生成标注的人物xml和手中有的抽烟xml进行合并,生成一份xml文件 代码 # -*- coding: u…

Linux查看8080端口是否启用

在Linux系统中&#xff0c;您可以使用几种不同的命令来检查8080端口是否被启用或正在被某个进程使用。以下是几种常用的方法&#xff1a; 使用lsof命令&#xff1a; sudo lsof -i :8080如果8080端口被某个进程使用&#xff0c;lsof命令将列出相关信息。如果没有输出&#xff0c…

docker和kubectl客户端安装Linux

一、docker安装 1.配置yum源&#xff08;系统组&#xff09; 2.查看可安装docker的所有版本 yum provides docker3.安装最新版本dockers yum install docker3.1确定版本没问题输入 y 4.验证 docker -v5.开启私有仓库的证书验证&#xff0c;没有创建一个daemon.json sudo vi…

设计模式之工厂方法模式解析

工厂方法模式 1&#xff09;问题 简单工厂模式 当需要引入新产品时&#xff0c;由于静态工厂方法通过所传入参数的不同来创建不同的产品&#xff0c;需要修改工厂类的源代码。 2&#xff09;概述 针对不同的产品提供不同的工厂&#xff0c;系统提供一个与产品等级结构对应…

我的保研材料全部损坏了!这个压缩包文件格式未知或数据已经被损坏不可预料的压缩文件末端

求助各位友友&#xff0c;我的保研材料全部没了&#xff01; 之前为了清理D盘&#xff0c;把之前保研期间准备的几个G的材料全部压缩放在了U盘&#xff0c;但是现在却损坏打不开了&#xff0c;之前为了省事也没有添加过“恢复记录”&#xff01;&#xff01;&#xff01; 先声…

阿赵UE学习笔记——20、角色蓝图和动画蓝图

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的使用。这次来看看角色控制动画相关的东西&#xff0c;主要用到了动画蓝图和角色蓝图。 一、动画蓝图 之前分析过&#xff0c;蓝图对于虚幻引擎来说&#xff0c;是存在于各个系统里面的&#xff0c;相当…

js 替换数组中的部分文字内容

用js 把[ "2024-03-20实时", "2024-03-20日前", "运行日实时", "运行日日前"]中把所有的“运行日”替换成 “2023” 可以使用 JavaScript 的 Array.prototype.map() 方法来遍历数组&#xff0c;并使用 String.prototype.replace() 方…

【0274】从shared init file或local init file加载relation cache(2 - 1)

上一篇: 【0273】深入分析 relcache(relation descriptor cache)初始化第一阶段(1) 【0264】深入分析relcache(relation descriptor cache)缓存初始化第2阶段(2) 1. 前言 本文内容是作为《【0264】深入分析relcache(relation descriptor cache)缓存初始化第2阶段…

智慧公厕:卫生、便捷、安全的新时代厕所变革

在城市快速发展的背景下&#xff0c;公共厕所的建设和管理变得越来越重要。智慧公厕作为厕所变革的一项全新举措&#xff0c;通过建立公共厕所全面感知监测系统&#xff0c;以物联网、互联网、大数据、云计算、自动化控制技术为支撑&#xff0c;实现对公共厕所的智能化管理和运…

FPGA学习_时序约束以及VIVADO时序报告

文章目录 前言时序约束的目的一、时序约束种类1、约束主时钟2、约束衍生时钟3、约束虚拟时钟4、input delay5、output delay6、约束异步时钟组7、约束互斥时钟8、假路径约束9、多周期约束 二、VIVADO时序报告三、从时序的角度看为什么寄存器赋值慢一拍 前言 一边学习一边补充当…

消除 Git diff 中的换行符差异(Linux)

通常编辑器默认使用的换行符是跟随操作系统的&#xff0c;而windows操作系统上修改的代码&#xff0c;其换行符会被转成win的\r\n,在提交代码时会显示大量改动&#xff08;对于sh脚本还会存在无法执行的问题&#xff09;&#xff0c;这时候我们可以通过设置git自动转成unix格式…

容器中的大模型(三)| 利用大语言模型:容器化高效地部署 PDF 解析器实践...

作者&#xff1a;宋文欣&#xff0c;智领云科技联合创始人兼CTO 01 简介 大语言模型&#xff08;LLMs&#xff09;正逐渐成为人工智能领域的一颗璀璨明星&#xff0c;它们的强大之处在于能够理解和生成自然语言&#xff0c;为各种应用提供了无限可能。为了让这些模型更好地服务…

【Hadoop】Hadoop 编译源码

目录 为什么要源码编译Hadoop 编译源码1前期工作准备2jar 包安装2.1安装 Maven2.2安装 ant2.3安装 glibc-headers 和 g2.4安装 make 和 cmake2.5安装 protobuf2.6安装 openssl 库2.7安装 ncurses-devel 库 3编译源码3.1解压源码到 /opt/ 目录3.2 进入到 hadoop 源码主目录 /opt…

原生小程序开发的父子组件传值,兄弟组件传值

1.父子传值&#xff0c;父组件通过属性的方式去给子组件传递值&#xff0c;子组件在properties属性去接收父组件传递过来的值&#xff1a; 父组件部分&#xff1a; <view class"pcolor"><customer id"child" bind:changSex"changSex"…

AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星评选TOP 10&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作…

UniTask 异步任务

文章目录 前言一、UniTask是什么&#xff1f;二、使用步骤三、常用的UniTask API和示例1.编写异步方法2.处理异常3.延迟执行4.等待多个UniTask或者一个UniTas完成5.异步加载资源示例6.手动控制UniTask的完成状态7.UniTask.Lazy延迟任务的创建8.后台线程切换Unity主线程9.不要返…