读者来信 | 如果你家HBase集群Region太多请点进来看看,这个问题你可能会遇到
前言:《读者来信》是HBase老店开设的一个问答专栏,旨在能为更多的小伙伴解决工作中常遇到的HBase相关的问题。老店会尽力帮大家解决这些问题或帮你发出求救贴,老店希望这会是一个互帮互助的小平台。有问题请直接在老店后台留言,有好的解决方案也请不要吝啬,诚挚欢迎大家能在留言区积极探讨解决方案,大胆发表自己的看法,也许你今天帮别人解决的问题,就是你明天可能遇到的答案。
来信人:刘*刚
小猿提问
在重启HBase集群的过程中,RS节点全部启动成功了,但是HMaser一直启动不起来,错误日志如下:
unexpected error, closing socket connection and attempting reconnect java.io.IOException: Packet len4745468 is out of range! at org.apache.zookeeper.ClientCnxnSocket.readLength(ClientCnxnSocket.java:112) at org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:79) at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:366) at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1081) 2020-04-02 22:31:08,673 ERROR [hadoop01:16000.activeMasterManager] zookeeper.RecoverableZooKeeper: ZooKeeper getChildren failed after 4 attempts 2020-04-02 22:31:08,674 FATAL [hadoop01:16000.activeMasterManager] master.HMaster: Failed to become active master org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /hbase/region-in-transition at org.apache.zookeeper.KeeperException.create(KeeperException.java:99) at org.apache.zookeeper.KeeperException.create(KeeperException.java:51) at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1472) at org.apache.hadoop.hbase.zookeeper.RecoverableZooKeeper.getChildren(RecoverableZooKeeper.java:295) at org.apache.hadoop.hbase.zookeeper.ZKUtil.listChildrenNoWatch(ZKUtil.java:513) at org.apache.hadoop.hbase.master.AssignmentManager.processDeadServersAndRegionsInTransition(AssignmentManager.java:519) at org.apache.hadoop.hbase.master.AssignmentManager.joinCluster(AssignmentManager.java:494) at org.apache.hadoop.hbase.master.HMaster.finishActiveMasterInitialization(HMaster.java:748) at org.apache.hadoop.hbase.master.HMaster.access$500(HMaster.java:184) at org.apache.hadoop.hbase.master.HMaster$1.run(HMaster.java:1729) at java.lang.Thread.run(Thread.java:748)
小猿分析
- HBase 版本:Apache 1.2.1
- 集群规模:120000+ region
看错误日志,好像只看到了ZK的身影,日志关键词是[
ZooKeeper.getChildren
|Packet
|out of range
|ConnectionLoss for /hbase/region-in-transition
]。
我们知道,HBase Master 重启时要做很多初始化工作,要与ZK数据节点进行一些交互工作,如元数据或节点状态的注册、修改、获取等等。看这些关键词大概好像明白是怎么回事:ZooKeeper在getChildren(region-in-transition)的时候超出了Packet的range,导致连接丢失了,Failed to become active master。
那什么是Packet呢?小猿问了问度娘,度娘回答说:
在 ZooKeeper 中,Packet 是一个最小的通信协议单元,即数据包。Pakcet 用于进行客户端与服务端之间的网络传输,任何需要传输的对象都需要包装成一个 Packet 对象。
那就是读取zk节点数据包长度有限制咯,这个时候我们肯定是先去网上找下zk有没有相关的参数可以调一下。结果还真的有:jute.maxbuffer
,感觉自己很幸运。套用官网的话解释一下这个参数:
(Java system property: jute.maxbuffer)
This option can only be set as a Java system property. There is no zookeeper prefix on it. It specifies the maximum size of the data that can be stored in a znode. The default is 0xfffff, or just under 1M. If this option is changed, the system property must be set on all servers and clients otherwise problems will arise. This is really a sanity check. ZooKeeper is designed to store data on the order of kilobytes in size.
翻译一下:
(Java系统属性:jute.maxbuffer)
此选项只能设置为Java系统属性。上面没有Zookeeper前缀。它指定可以存储在znode中的数据的最大大小。默认值为0xfffff,或不到1M。如果更改此选项,则必须在所有服务器和客户端上设置系统属性,否则会出现问题。这确实是一个健全性检查。ZooKeeper旨在存储大小为千字节的数据。
也有另一种说法:
需要注意的是,该参数并不是在 Server 和 Client 端同时设置才会生效。实际情况是,在客户端设置后,Zookeeper 将控制从 Server 端读取数据的大小(outgoingBuffer);而在服务端设置后,则是控制从 Client 端写入数据的大小(incomingBuffer)
相关代码如下:
protected final ByteBuffer lenBuffer = ByteBuffer.allocateDirect(4); protected ByteBuffer incomingBuffer = lenBuffer; protected void readLength() throws IOException { int len = incomingBuffer.getInt(); if (len < 0 || len >= ClientCnxn.packetLen) { throw new IOException("Packet len" + len + " is out of range!"); } incomingBuffer = ByteBuffer.allocate(len); } public static final int packetLen = Integer.getInteger("jute.maxbuffer", 4096 * 1024);
那为什么会读取这么大一个包呢?基于上文提到的关键字/hbase/region-in-transition
(待分配region信息) 及Region的规模(120000+),我们猜测是因为Region太多了,导致/hbase/region-in-transition
节点太大,HMaster读取该节点数据时超出限制并以失败告终。我们也在HBase Jira库找到了相关issue:
Cluster with too many regions cannot withstand some master failover scenarios
https://issues.apache.org/jira/browse/HBASE-4246
我们很多时候都不是第一个湿鞋的人,也许你今天帮别人解决的问题,就是你明天可能遇到的答案。这也是老店开设问答专栏《读者来信》的初心--为了知识更好的传播与分享!
小猿解答
当然也不只/region-in-transition
节点会有这样的问题,/unssigned
等节点也可能会有一样的问题。解决方案总结如下:
方案一:清理zk节点历史上存在的垃圾数据
该方案旨在将zk节点的数据大小降下来,是否可以降到红线以下。
方案二:调大参数jute.maxbuffer
# 设置 Client 端 $ vim $ZOOKEEPER_HOME/bin/zkCli.sh # 增加 -Djute.maxbuffer=<buffer_size> 参数 "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Djute.maxbuffer=1073741824" \ -cp "$CLASSPATH" $CLIENT_JVMFLAGS $JVMFLAGS \ org.apache.zookeeper.ZooKeeperMain "$@" # 设置 Server 端 $ vim $ZOOKEEPER_HOME/conf/zoo.cfg # 增加 jute.maxbuffer=<buffer_size> 参数 jute.maxbuffer=1073741824
调大该参数可能有风险,上面也提到zk旨在存储大小为千字节的数据。
方案三:使用层次结构(来自社区评论区)
该方案是通过区域ID的前缀将·
/hbase/region-in-transition
目录分片。例如,区域1234567890abcdef
将位于/hbase/region-in-transition/1234/1234567890abcdef
中。因此,我们必须进行遍历才能获得完整列表。
参考文献
- https://issues.apache.org/jira/browse/HBASE-4246
- https://cloud.tencent.com/developer/article/1516691
- https://yuzhouwan.com/posts/31915/
转载请注明出处!欢迎关注本人微信公众号【HBase工作笔记】
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
【云栖号在线课堂】重磅推荐:湖畔大学执行教育长陈龙 讲述疫情下的全球经济
受疫情影响,如何轻松实现在家办公和学习?不用慌,云栖号在线课堂,每天都有产品技术专家分享,带你快速入门云计算!下面就给大家推荐关于CIO学院攻“疫”技术培训及2020大数据技术公开课第二季的精品课程! CIO学院攻“疫”技术培训 “开展技术普惠公益,与广大技术人共同学习成长!”是阿里CIO学院“技术攻疫(公益)大咖讲开设的初衷。该系列课程邀请到李飞飞、贾扬清、丁险峰、华先胜、王刚、金榕、小邪、五福、司罗、肖力、施尧耘、吴翰清等数十位技术大咖,与大家共同探讨人工智能、云计算、企业安全体系……的技术与实践。CIO学院攻“疫”技术培训第一期 达摩院自动驾驶实验室负责人王刚介绍无人驾驶的经典发展路线、面对的核心问题、最新到技术成果以及从黑科技到商业化的未来。阿里巴巴集团副总裁、达摩院高级研究员金榕从深度学习到AI三大关键技术方向,看AI技术应用中的困局、破局,以及未来。 【课程目录】 讲师 直播主题 观看视频 王刚 自动驾驶之路上的“能”与“不能” 点击观看 金榕 困局与破局:从深度学习到AI三大关键技术 点击观看 CIO学院攻“疫”技术培训第二期 云可以带来哪些切实的好处?如何用好云?在云的...
- 下一篇
HBase Shell Get 操作常用小技巧
在工作中,有时候只是想简单看下HBase表某些关键指标的值,这个时候总不能现写Java代码去查看,以下几个小技巧你可能会经常用到。 1. 某行有许多列,只想获取指定2~3列的数据 hbase> get 't1', 'r1', ['f:c1', 'f:c2', 'f:c3'] 2. 想看某个字段多个版本的数据 hbase> get 't1', 'r1', {COLUMN => 'f:c1', VERSIONS => 4} 3. 想看被16进制化的中文或数字 hbase> put 't1','r1','f:c1','中国' hbase> get 't1','r1','f:c1:toString' COLUMN CELL f:c1 timestamp=1585635275771, value=中国 1 row(s) in 0.0180 seconds 对于Int型、Long型数值,支持toInt|toLong语法。 4. 快速获取一个列族下的所有列 使用列族过滤器: 1. 精确匹配列族 hbase> get 't1,'r1',FILTER=>"...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,CentOS7官方镜像安装Oracle11G
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装Docker,最新的服务器搭配容器使用