大家好,我是明哥!
本篇文章,我们回顾一次 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.YarnChild$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.mr