向Hbase插入时,报错java.lang.IllegalArgumentException: KeyValue size too large的解决办法

最近在向Hbase中插入数据时, 报了个KeyValue size too large 的错误,  具体报错信息如下:

Error: java.lang.IllegalArgumentException: KeyValue size too large
	at org.apache.hadoop.hbase.client.HTable.validatePut(HTable.java:1567)
	at org.apache.hadoop.hbase.client.BufferedMutatorImpl.validatePut(BufferedMutatorImpl.java:152)
	at org.apache.hadoop.hbase.client.BufferedMutatorImpl.mutate(BufferedMutatorImpl.java:127)
	at org.apache.hadoop.hbase.client.BufferedMutatorImpl.mutate(BufferedMutatorImpl.java:113)
	at org.apache.hadoop.hbase.mapreduce.TableOutputFormat$TableRecordWriter.write(TableOutputFormat.java:138)
	at org.apache.hadoop.hbase.mapreduce.TableOutputFormat$TableRecordWriter.write(TableOutputFormat.java:94)
	at org.apache.hadoop.mapred.ReduceTask$NewTrackingRecordWriter.write(ReduceTask.java:558)
	at org.apache.hadoop.mapreduce.task.TaskInputOutputContextImpl.write(TaskInputOutputContextImpl.java:89)
	at org.apache.hadoop.mapreduce.lib.reduce.WrappedReducer$Context.write(WrappedReducer.java:105)
	at com.dxyun.dxdp.activity.tempScript.countMaxInvNumSingleTel.reducer.CountMaxNumReducer.reduce(CountMaxNumReducer.java:50)
	at com.dxyun.dxdp.activity.tempScript.countMaxInvNumSingleTel.reducer.CountMaxNumReducer.reduce(CountMaxNumReducer.java:20)
	at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:171)
	at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:627)
	at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:389)
	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:1693)
	at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
根据错误信息提示,找到源码中的  validatePut 方法:
public static void validatePut(Put put, int maxKeyValueSize) throws IllegalArgumentException {
        if (put.isEmpty()) {
            throw new IllegalArgumentException("No columns to insert");
        } else {
            if (maxKeyValueSize > 0) {
                Iterator i$ = put.getFamilyCellMap().values().iterator();

                while(i$.hasNext()) {
                    List<Cell> list = (List)i$.next();
                    Iterator i$ = list.iterator();

                    while(i$.hasNext()) {
                        Cell cell = (Cell)i$.next();
                        if (KeyValueUtil.length(cell) > maxKeyValueSize) {
                            throw new IllegalArgumentException("KeyValue size too large");
                        }
                    }
                }
            }

        }
    }

在源码中我们发现,在进行插入操作的时候,hbase会挨个检查要插入的列,检查每个列的大小是否小于 maxKeyValueSize值,当cell的大小大于maxKeyValueSize时,就会抛出KeyValue size too large的异常。问题定位到了,下面看这个maxKeyValueSize值是在哪里设定的。在validatePut方法所在的同一个类(HTable.class)中,可以找到maxKeyValueSize的信息:

public static int getMaxKeyValueSize(Configuration conf) {
        return conf.getInt("hbase.client.keyvalue.maxsize", -1);
    }
在上述方法中可以看出, maxKeyValueSize的值是在配置文件中配置的,配置参数的key值就是: hbase.client.keyvalue.maxsize。

在官网,我查到了关于hbase.client.keyvalue.maxsize的描述信息:

hbase.client.keyvalue.maxsize
一个KeyValue实例的最大size.这个是用来设置存储文件中的单个entry的大小上界。因为一个KeyValue是不能分割的,所以可以避免因为数据过大导致region不可分割。
明智的做法是把它设为可以被最大region size整除的数。如果设置为0或者更小,就会禁用这个检查。默认10MB。

默认: 10485760
也就是说, hbase.client.keyvalue.maxsize 的默认大小是10M,如果cell的大小超过10M,那么就会报 KeyValue size too large的错误。

解决方法:

方法一、根据官网提示,修改配置文件hbase-default.xml ,调大hbase.client.keyvalue.maxsize  的值: 

<property>
    <name>hbase.client.keyvalue.maxsize</name>
    <value>20971520</value>
  </property>
不建议通过直接修改配置文件的方式修改。改完后,需重启hbase(需不需要重启?带验证)

方法二:修改代码,使用configuration对象修改此配置:

Configuration conf = HBaseConfiguration.create();  
conf.set("hbase.client.keyvalue.maxsize","20971520");
推荐此种方式。

附:Hbase 官方文档(中文)地址


  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值