记录一次 Hbase 线上问题的分析和解决
大家好,我是明哥!
本篇文章,我们回顾一次 hbase 线上问题的分析和解决 - KeyValue size too large,总结下背后的知识点,并分享一下查看开源组件不同版本差异点的方法。
希望大家有所收获,谢谢大家!
01 Hbase 简介
Hbase 作为 hadoop database, 是一款开源,分布式易扩展,面向大数据场景的,多版本,非关系型,数据库管理系统,是 Google Bigtable 的 JAVA 版开源实现。
Hbase 的底层存储引擎是 HDFS,可以在普通商业级服务器硬件(即常说的 x86 架构的服务器)的基础上,提供对超大表(表的数据量可以有百万行,每行的列数可以有百万级)的随机实时读写访问。
Hbase具有以下特征:
模块化的线性扩展性; 强一致性并发读写支持; 可配置的表的自动 sharding; 表分区在 RegionServer 间的自动 failover; 基于 Block cache 和 Bloom 过滤器的实时读取; 基于 server 端过滤器的查询谓词下推;
正是因为 Hbase 的上述特征,Hbase 在各行各业有许多线上应用案列,可以说是 NoSql 数据库的一个典型代表:
在各种超大数据量级 在需要实时并发读写支持 在表的结构比较灵活(即有很多稀疏列:有很多行和很多列,但每一行只有众多列中的少数列有值) 笔者就在车联网场景下重度使用过 Hbase
题外话:
Nosql 数据库有几大类,几个典型代表是:Hbase, ElasticSearch, MongoDb;
有个有趣的现象,笔者发现国内 Hbase 使用的多,而国外似乎 Cassandra 使用的多。
02 一次线上 Hbase 问题的问题现象
某线上应用使用了 Hive 到 Hbase 的映射表,在使用 insert overwrite 从 hive 表查询数据并插入 HBASE 表时,发生了错误。
通过查看 HIVE 背后 YARN 上的作业的日志,发现主要错误信息是 java.lang.记录IllegalArgumentException: KeyValue size too large,详细报错截屏和日志如下:
2020-04-08 09:34:38,120 ERROR [main] ExecReducer: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) {"key":{"_col0":"0","_col1":"","_col2":"2020-04-08","_col3":"joyshebaoBeiJing","_col4":"105","_col5":"北京,"},"value":null} at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:253) at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:444) at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392) at org.apache.hadoop.mapred.Yarn一次Child$2.run(YarnChild.java:164) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1924) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158) Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.IllegalArgumentException: KeyValue size too large at org.apache.hadoop.hive.ql.exec.GroupByOperator.processOp(GroupByOperator.java:763) at org.apache.hadoop.hive.ql.exec. Hmr.ExecReducer.reduce(ExecReducer.java:244) ... 7 more Caused by: java.lang.IllegalArgumentException: KeyValue size too large at org.apache.hadoop.hbase.client.HTable.validatePut(HTable.java:1577) at org.apache.hadoop.hbase.client.BufferedMutatorImpl.validatePut(BufferedMutatorImpl.java:158) at org.apache.hadoop.hbase.client.BufferedMutatorImpl.mutate(BufferedMutatorImpl.java:133) at org.apache.hadoop.hbase.client.BufferedMutatorImpl.mutate(BufferedMutatorImpl.java:119) at org.apache.hadoop.hbase.client.HTable.put(HTable.java:1085) ba at org.apache.hadoop.hive.hbase.HiveHBaseTableOutputFormat$MyRecordWriter.write(HiveHBaseTableOutputFormat.java:146) at org.apache.hadoop.hive.hbase.HiveHBaseTableOutputFormat$MyRecordWriter.write(HiveHBaseTableOutputFormat.java:117) at org.apache.hadoop.hive.ql.io.HivePassThroughRecordWriter.write(HivePassThroughRecordWriter.java:40) at org.apache.hadoop.hive.ql.exec.FileSinkOperator.processOp(FileSinkOperator.java:717) at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:815) at org.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:84) &senbsp; at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:815) at org.apache.hadoop.hive.ql.exec.GroupByOperator.forward(GroupByOperator.java:1007) at org.apache.hadoop.hive.ql.exec.GroupByOperator.processAggr(GroupByOperator.java:818) at org.apache.hadoop.hive.ql.exec.GroupByOperator.processKey(GroupByOperator.java:692) at org.apache.hadoop.hive.ql.exec.GroupByOperator.processOp(GroupByOperator.java:758) ... 8 more 03 该线上 Hbase 问题的问题原因
其实以上作业的报错日志还是比较详细的:Caused by: java.lang.IllegalArgumentException: KeyValue size too large at org.apache.hadoop.hbase.client.HTable.validatePut(HTabl 线e.java:1577);
即报错详细信息是:KeyValue size too large; 报错来自 Hbase (而不是 HIVE)的类,从类名看是 hbase 客户端在对待插入数据校验时发现了错误:org.apache.hadoop.hbase.client.HTable.validatePut(HTable.java:1577);
熟悉 Hbase 的小伙伴(其实不熟悉 Hbase 的小伙伴,也能从报错信息和报错类上猜到一点点),从以上信息能够猜到,是 Hbase 对每条记录的 KyeValue 的大小做了限制,当实际插入的 KeyValue 的大小超过该大小限制阈值时,就会报上述错误。
什么是 KeyValue 呢?
这涉及到 Hbase 的存储结构,Hbase 内部是通过 KeyValue 结构来存储表数据的; 大致上大家可以认为:某个 KeyValue 对应的是 Hbase 大宽表中的某行的某列; 每个 KeyVlue 内部内容包含:rowKey+CF(ColumnFamily)+CQ(Column qualifier)+Timestamp+Value; 详细说明见官方文档,截图如下:
Hbase 为什么要限制每个 KeyValue 的大小呢?
究其原因,是因为 Hbase 需要在 hdfs 存储引擎(基于分磁盘)之上提供对数据实时读写的支持; Hbase 在内部数据读写时使用了 LSM 数据结构 (Log-Structured-Merge Tree),这背后涉及到了大量对内存的使用(读数据时使用 BlockCache,写数据时使用 memStore),也涉及到了内存数据的异步 flush 和 hfile 文件的异步 compaction;(当然为了容错,又涉及到了 wal Hlog); 因为涉及到基于内存提供对数据读写的支持,所以需要限制使用的内存的总大小,由于内存 BlockCache 中缓存的数据是以Block 为单位的,而Block内部存储的是一个个 KeyVal上问ue, 所以从细节来讲也需要限制每个 KeyValue的大小; 这里的 Block 是 Hbase的概念,不是 HDFS Block; (Hbase 每个 Block 的默认大小是 64KB, HDFS 每个BLOCK的默认大小一般是 128MB); 04 该线上 Hbase 问题的扩展知识-不同 Hbase 版本相关的参数
Hbase 作为一个流行的 Nosql数据库,推出十多年来,目前有多个经典版本:
0.98;-- 该版本比较老了,部分遗留线上应用还有使用该版本的; 1.2.x;(1.4.x) -- 1.2.x 和 1.4.x 都是1.x 系列下用的比较多的稳定版本 2.1.x(2.4.x) -- 2.1.x 和 2.4.x 都是2.x系列下用的比较多的稳定版本 3.0.0-alpha-1 -- 3.x 系列目前还不是稳定版
对应该 “KeyValue size too large” 问题,不同版本推出了不同的相关参数:
在hbase-1.4 以前的版本中,(包括hbase 1.2.0-cdh5.14.2 和 hbase 1.2.0-cdh5.16.2),只有一个客户端参数 hbase.client.keyvalue.maxsize; 在 hbase-1.4 及以后版本中,除了该客户端参数 hbase.client.keyvalue.maxsize,还有一个服务端参数 hbase.server.keyvalue.maxsize;
其实,由于笔者并没有持续跟进 HBASE 社区对 feautre 和 issue相关的讨论(大部分使用者可能都不会),所以也是在查阅不同版本的官方文档时留意到了上述细节,然后通过在本地 IDEA 中使用 git->show history 对比不同版本 HBASE 中 hbase-default.xml 的源码,进而确认到了JIRA记录号,并在JIRA中确认了这点:
正如该 JIRA 中描述:
HBASE-18043:
For sake of service protectio题的n we should not give absolute trust to clients regarding resource limits that can impact stability, like cell size limits. We should add a server side configuration that sets a hard limit for individual cell size that cannot be overridden by the client. We can keep the client side check, because it's expensive to reject a RPC that has already come in.
所以,不同版本中遇到不同情况,可能会包的错误主要有两个:
情况1:Hbase KeyValue size too large 情况2:Cell with size 25000046 exceeds limit of 10485760 bytes
报错情况一和报错情况而,问题原因如下:
报错情况一:没有配置客户端参数 hbase.client.keyvalue.maxsize,且实际插入的 keyvalue 的大小超过了该客户端参数的默认大小限制;
报错情况二:程序设置调大了客户端参数 hbase.client.keyvalue.maxsize,但没有调大服务端参数 hbase.server.keyvalue.maxsize,且实际插入的 keyvalue 小于该客户端参数,但大于该服务端参数:
报错情况二,某次作业日志:
Exception in thread "main"org.apache.hadoop.hbase.DoNotRetryIOException: org.apache.hadoop.hbase.DoNotRetryIOException: Cel分析l with size 25000046 exceeds limit of 10485760 bytes at org.apache.hadoop.hbase.regionserver.RSRpcServices.checkCellSizeLimit(RSRpcServices.java:944) at org.apache.hadoop.hbase.regionserver.RSRpcServices.mutate(RSRpcServices.java:2792) at org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:42000) at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:413) at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:130) at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecut和解or.java:324) at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:304)
报错情况二,某次报错截图:
05 该线上 Hbase 问题的解决方案
知道了问题原因,其实解决方法也就呼之欲出了,在确认要插入的业务数据没有异常,确实需要调大 keyvalue 限制的阈值时,大体总结下,有以下解决办法:
方法一:修改配置文件 hbase-site.xml, 调大客户端参数 hbase.client.keyvalue.maxsize 的值; 方法二:如果使用了 HBASE JAVA API, 可以修改代码使用 configuration 对象修改此客户端参数的默认配置:Configuration conf = HBaseConfiguration.create(); conf.set("hbase.client.keyvalue.maxsize","20971520"); 方法三:如果使用了 HIVE,可以在客户端覆盖该客户端参数:set hbase.client.keyvalue.maxsize=0; (hive sql中) 说明:一般该客户端参数和服务端参数,默认值应该配置一样;当更改服务端参数时,需要重启服务端才能生效;当更改客户端参数时,不同客户端设置的值可以不同,且不需要重启服务端; 在CDH中配置更改截图如下:
06 该线上 Hbase 问题的技术背景 Hbase 内部是通过 KeyValue 结构来存储表数据的,某个 KeyValue 对应的是 Hbase 大宽表中的某行的某列,每个 KeyVlue 内部内容包含:rowKey+CF(ColumnFamily)+CQ(Column qualifier)+Timestamp+Value; hbase 在进行 PUT记录 操作的时候,会逐个检查要插入的每个列 (keyvalue cell) 的大小,当其大小大于 maxKeyValueSize 时,就会抛出异常,拒绝写入; maxKeyValueSize 大小相关的参数,在hbase-1.4 以前的版本中,(包括hbase 1.2.0-cdh5.14.2 和 hbase 1.2.0-cdh5.16.2),只有一个客户端参数 hbase.client.keyvalue.maxsize; maxKeyValueSize 大小相关的参数,在 hbase-1.4 及以后版本中,除了该客户端参数 hbase.client.keyvalue.maxsize,还有一个服务端参数 hbase.server.keyvalue.maxsize; Hbase 限制每个 KeyValue 大小的原因,主要在于: Hbase 需要在 hdfs 存储引擎(基于分磁盘)之上提供对数据实时读写的支持,因此 Hbase 在内部数据读写时使用了 LSM 数据结构 (Log-Structured-Merge Tree),这背后涉及到了大量对内存的使用(读数据时使用 BlockCache,写数据时使用 memStore),也涉及到了内存数据的异步 flush 和 hfile 文件的异步 compaction;(当然为了容错,又涉及到了 wal Hlog); 因为涉及到基于内存提供对数据读写的支持,所以需要限制使用的内存的总大小,由于内存 BlockCache 中缓存的数据是以Block 为单位的,而Block内部存储的是一个个 KeyValue, 所以从细节来讲也需要限制每个 KeyValue的大小; 这里的 Block 是 Hbase的概念,不是 HDFS Block; (Hbase 每个 Block 的默认大小是 64KB, HDFS 每个BLOCK的默认大小一般是 128MB); 该客户端参数 hbase.client.keyvalue.maxsize,和服务端参数hbas一次e.server.keyvalue.maxsize,集群级别的默认配置推荐保持一致,且不推荐在集群级别配置这两个参数为0或更小(即禁用大小检查),因为此时可能会造成某个cell 存很大的数据比如 1G,此时集群性能就会大打折扣; 服务端参数只能在服务端进行配置,且配置后要重启服务端的 hbase, 其做用是 “This is a safety setting to protect the server from OOM situations.”; 客户端参数可以在服务端进行全局默认配置,也可以在客户端进行定制配置,不同客户端设置的值可以不同,但不能大于服务端的值,且客户端配置后不需要重启服务端,其含义是:一个KeyValue实例的最大size(一个KeyValue在io时是不能进一步分割的); 客户端参数,具体需要设置为多大,需要根据业务允许的最大keyValue是多少来进行配置,默认是10M,一般是以默认值10M为基础,如果有客户遇到以上报错,且实际的KEYVALUE也不是业务脏数据,就调大1倍到20MB看看; 在通过hive外表使用 HBaseStorageHandler 向 HBASE 写数据时,可以直接在beeline中更改配置客户端参数 (set hbase.client.keyvalue.maxsize=10485760),不需要重启hbase服务端; 在探究某个开源组件的某个类或配置文件,在不同版本的变化历史时,可以通过 git clone 在本地克隆创建 git repository,然后在本地 IDEA 中通过使用命令 git->show history 对比不同版本中类或配置文件的,进而确认到 JIRA 记录号,并在JIRA中确认相关细节; 更多关于hbase数据存储结构的细节: hbase 中的数据,可以有多个columnFamily, 每个 columnFamily 内部可以有多个column;
每个 Col HumnsFamily 落地到hdfs上的文件是 hfile/storeFile, storeFile 是由 data block组成的(block 是IO和压缩的基本单位,默认64KB);(Within an HFile, HBase cells are stored in data blocks as a sequence of KeyValues;KeyValue instances are aggregated into blocks, which are indexed and Indexes also have to be stored; Blocksize is configurable on a per-ColumnFamily basis); 每个 block 内部存储了多个columns,每个column都是以 keyvalue 的形式存储的,每个keyvalue的大小受hbase.clent.keyvalue.maxsize/hbase.server.keyvalue.maxsize限制的; compression and DATA BLOCK ENCODING doesn't help with the cell size check, as compress and data block encoding happens when flush memstore to hfile and compaction of hfile; HBase supports several different compression algorithms which can be enabled on a ColumnFamily. Data block encoding attempts to limit duplication of information in keys, taking advantage of some of the fundamental designs and patterns of HBase, such as sorted row keys andba the schema of a given table. Compressors reduce the size of large, opaque byte arrays in cells, and can significantly reduce the storage space needed to store uncompressed data.
(责任编辑:促销资讯)
-
标签: 夸克AI眼镜 Super Raw算法 Raw域降噪 高通骁龙AR1
云梦级11月13日云梦级消息,11月13日,根据国家知识产权局官网显示,夸克AI眼镜已为其“Super Raw暗光处理算法”申请相关专利,公开号为:CN120915925A。 该专利将Raw域降噪技术...[详细]
-
谷歌推新AI学习工具Learn Your Way,用 AI 打造个性化教科书
随着教育领域的不断发展,传统的教科书作为教学的重要工具,逐渐显露出一刀切的局限性。为了打破这种局限性,谷歌正在探索如何利用生成性 AI(GenAI)来自动生成多样化的教育材料。近期,谷歌推出了一项名为...[详细]
-
前言:吉祥彩是什么吉祥彩当然是人们非常充满着吉祥可爱,五彩缤纷的一种颜色。大家都喜欢和和美美而显得充满着吉祥。吉祥彩怎么样?很不错的,是菲律宾政\\\府指定机构颁发的牌照,很受欢迎的公司。吉祥彩单号最...[详细]
-
赚钱思路 利用AI技术,将人类脱口秀或播客的音频,配以宠物(猫、狗等)的视频或图片,制作成有趣的宠物“开口说话”的短视频,通过吸引流量和粉丝变现。 适合人群 喜爱宠物、对短视频内容创作感兴趣、懂基础视...[详细]
-
拿下全球48%收益!苹果却担忧“遭断供”,投资77亿赴欧研发芯片
本文为「金十数据」原创文章,未经许可,禁止转载,违者必究。 据新浪财经3月23日最新报道,研究机构Strategy Analytics发布报告指出,2020年全球平板电脑应用处理器(AP)市场时隔5年...[详细]
-
阿里云蒋江伟:坚持“做深基础”战略 从飞天云操作系统向下延伸定义硬件
5月28日消息,在2021云峰会上,阿里云基础产品负责人蒋江伟公布了飞天操作系统最新的进化方向:一云多芯、本地region、计算巢。蒋江伟表示,飞天是中国唯一的自研云操作系统,阿里云将坚持“做深基础”...[详细]
-
谷歌宣布搜索整合Google Assistant翻译模式 推出全新模型LaMDA
新浪科技讯 5月19日凌晨消息,Google I/O 2021开发者大会(后文简称谷歌I/O)今日开幕,去年因疫情因新冠疫情而被取消之后,2021年谷歌I/O大会重新回归,并采用全程线上的形式,对所有...[详细]
-
在医疗科技快速发展的今天,影禾医脉与北京天坛医院联手推出了一款颇具创新意义的人工智能产品 ——“小君医生 2.0”。这款全球首个全疾病覆盖的颅脑 CT 辅助报告生成大模型,旨在利用先进的人工智能技术提...[详细]
-
浜戣�绠楀紑鍙戯細Python鍐呯疆鍑芥暟-range() 鍑芥暟璇﹁В
鎻忚堪 python2.x range() 鍑芥暟鍙�垱寤轰竴涓�暣鏁板垪琛�紝涓€鑸�敤鍦� for 寰�幆涓�€� 娉ㄦ剰锛歅ython3 range() 杩斿洖鐨勬槸涓€涓�彲杩�唬瀵硅薄锛堢被...[详细]
-
题目 :请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母。 程序分析 :用情况语句比较好,如果第一个字母一样,则判断用情况语句或if语句判断第二个字母。 程序源代码...[详细]
- https://www.rookwinkel.nl/catalogsearch/result/index/?q=谷歌站群软件【tg:seogoogle987】,y4U
- https://www.smics.com/tc/site/search?token=谷歌站群软件【tg:seogoogle987】,fAK
- https://www.polliwogs.com/search/谷歌站群软件【tg:seogoogle987】,4BB
- https://www.nuovabai.it/catalogsearch/result/?action=SEARCH&q=谷歌站群软件【tg:seogoogle987】,WA9
- https://www.normani.de/search?q=谷歌站群软件【tg:seogoogle987】,sZL
- https://www.sweat.com/collections/vendors?q=谷歌站群软件【tg:seogoogle987】,x0h
- https://www.sonepar.ch/fr/search?q=谷歌站群软件【tg:seogoogle987】,nuJ
- https://www.mingwai.edu.hk/?langzh-hant&s=谷歌站群软件【tg:seogoogle987】,prL
- https://www.umc.edu/search.aspx?ID=I4gnDKRS991MFcIDDzoYze4aWSAszAm7&q=谷歌站群软件【tg:seogoogle987】,lZC
- https://www.uctronics.com/catalogsearch/result/?q=谷歌站群软件【tg:seogoogle987】,wjz

标签: 百度 于轲 短剧 樊婷婷
标签: LeptonAI 贾扬清 英伟达 DGXCloudLepton
标签: 阿兹夫
标签: TCL华星 兆元光电 LED芯片 Mini LED
OpenAI 挥剑指向 LinkedIn,将于2026年推出 AI 招聘平台
