Composite做rowkey抛出InvalidRequestException解决方法

1.问题描述

       软件版本:cassandra2.0.1,Hector-1.1-4

       由于业务需要,需要使用Composite做rowkey,我使用的CQL创建的table,CQL脚本如下:

CREATE TABLE t_sim_gameinfo (
  column1 text,
  column2 text,
  column3 text,
  column4 text,
  PRIMARY KEY (column1, column2)
 );

      按照上面create table的脚本,column1和column2组成一个composite row key,在Hector中我也是用这个composite row key建Mutator。但是Hector在插入数据时总是不能成功,调试期间会出现如下2个异常(第1个出现得最多):

Caused by: InvalidRequestException(why:Not enough bytes to read value of component 0)
	at org.apache.cassandra.thrift.Cassandra$batch_mutate_result.read(Cassandra.java:20833)
	at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78)
	at org.apache.cassandra.thrift.Cassandra$Client.recv_batch_mutate(Cassandra.java:964)
	at org.apache.cassandra.thrift.Cassandra$Client.batch_mutate(Cassandra.java:950)
	at me.prettyprint.cassandra.model.MutatorImpl$3.execute(MutatorImpl.java:246)
	at me.prettyprint.cassandra.model.MutatorImpl$3.execute(MutatorImpl.java:1)
	at me.prettyprint.cassandra.service.Operation.executeAndSetResult(Operation.java:104)
	at me.prettyprint.cassandra.connection.HConnectionManager.operateWithFailover(HConnectionManager.java:241)
	... 3 more
InvalidRequestException(why:String didn't validate.)

  2、发现问题

       经查资料,另外Hector主要也是对columnfamily来操作的,于是通过cassandra-cli查看table(describe t_sim_gameinfo),出现如下信息:

ColumnFamily: t_sim_gameinfo
      Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type
      Default column value validator: org.apache.cassandra.db.marshal.BytesType
      Cells sorted by: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.UTF8Type)
      从上面可以看出,此create table的脚本对应的ColumnFamily的row key是UTF8Type,根本不是CompositeType,所以用Composite做row key来建Mutator后执行异常。


  3、问题解决

      2种行不通的解决方法

  • 修改key_validation_class为CompositeType。我们可能会想到,既然key_validation_class是UTF8Type,那就把它改成CompositeType。那为什么不行。第1,Alter table根本就没有key_validation_class相关的参数。第2,如果通过修改ColumnFamily,例如:
    UPDATE COLUMN FAMILY t_sim_gameinfo WITH  comparator =UTF8Type AND  column_metadata =[{ name:null, keyvalidation_class:'CompositeType(UTF8Type, UTF8Type)'}];
    会抛异常的哦。
  • 把column1当key,PK中所有的column再组合成当Composite Column。但是这种方式也不行,会抛上面第一种异常的。


     解决方法

  • 修改cassandar-cli脚本

       要使用Composite做rowkey,可以修改cassandar-cli脚本,如下:

create column family t_sim_gameinfo with comparator = 'UTF8Type' 
and key_validation_class = 'CompositeType(UTF8Type, UTF8Type)' 
AND default_validation_class = UTF8Type
    and column_metadata=[
        {column_name: column3, validation_class: UTF8Type},
        {column_name: column4, validation_class: UTF8Type}
    ]
    with read_repair_chance=0.1
    and dclocal_read_repair_chance=0.5;   

       这时再通过cassandra-cli查看,相应的columnfamily信息是:

ColumnFamily: t_sim_gameinfo
      Key Validation Class: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.UTF8Type)
      Default column value validator: org.apache.cassandra.db.marshal.BytesType
      Cells sorted by: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type)

      key_validation_class已经成CompositeType,默认会有key,key1当做联合主键,此时如果把key和key1组成CompositeType做为row key建Mutator就没有问题了。

  • 修改cql脚本

      另外,也可以修改cql脚本,如下。Insert数据没有问题,但只可以通过cassandra-cli查看数据,用cqlsh查不到数据。

    CREATE TABLE t_sim_gameinfo (  
      column1 text,  
      column2 text,  
      column3 text,  
      column4 text,  
      PRIMARY KEY ((column1, column2))  
     )WITH COMPACT STORAGE;  
参考: cannot insert composite keyCan't insert rows with composite key using Hector

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值