没有足够的字节使用复合列与Astyanax客户端读取组件的值 [英] Not enough bytes to read value of component using Composite Columns with Astyanax client

查看:166
本文介绍了没有足够的字节使用复合列与Astyanax客户端读取组件的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Astyanax客户端插入到Cassandra列族的复合列中。

 创建列系列USER_DATA 
with key_validation_class ='UTF8Type'
和comparator ='CompositeType(UTF8Type,UTF8Type,DateType)'
和default_validation_class ='UTF8Type'
和gc_grace = 86400;

我希望在插入后,它会像这样

  user-id column1 
123(Column1-Value Column1- SchemaName LastModifiedDate)

下面是我的java主代码 -

  public static void main args){

ComplexType ct = new ComplexType();
ct.setVal1(Hello);
ct.setVal2(World);
ct.setTimestamp(System.currentTimeMillis());

// e1是列名,ct是其复合值。
attributeMap.put(e1,ct);

clientDao.upsertCompositeAttributes(123,attributesMap,USER_DATA);
}

以下是我的ComplexType类 -

  public static class ComplexType {
@Component(ordinal = 0)
String val1;

@Component(ordinal = 1)
String val2;

@Component(ordinal = 2)
long timestamp;


public String getVal1(){
return val1;
}
public void setVal1(String val1){
this.val1 = val1;
}
public String getVal2(){
return val2;
}
public void setVal2(String val2){
this.val2 = val2;
}
public long getTimestamp(){
return timestamp;
}
public void setTimestamp(long timestamp){
this.timestamp = timestamp;
}
}



下面是我的 upsertCompositeAttributes

  void upsertCompositeAttributes(final String rowKey,final Map< String,ComplexType> ct,final String columnFamilyName){

try {
AnnotatedCompositeSerializer< ComplexType> complexTypeSerializer = new AnnotatedCompositeSerializer< ComplexType>(ComplexType.class);

ColumnFamily columnFamily = new ColumnFamily(columnFamilyName,StringSerializer.get(),StringSerializer.get());

MutationBatch m = CassandraAstyanaxConnection.getInstance()。getKeyspace()。prepareMutationBatch();

ColumnListMutation< String> mutation = m.withRow(columnFamily,rowKey);

for(Map.Entry< String,ComplexType> entry:ct.entrySet()){
// entry.getKey()是列名,entry.getValue复合值。
mutation = mutation.putColumn(entry.getKey(),entry.getValue(),complexTypeSerializer,null);
}

m.setConsistencyLevel(ConsistencyLevel.CL_ONE).execute();

} catch(ConnectionException e){

} catch(Exception e){

}
}



现在我得到以下异常:

  com.netflix.astyanax.connectionpool.exceptions.BadRequestException:BadRequestException:[host = 10.109.107.27(10.109.107.27):9160,latency = 99(131),attempts = 1] InvalidRequestException字节读取组件0的值)
at com.netflix.astyanax.thrift.ThriftConverter.ToConnectionPoolException(ThriftConverter.java:159)
at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl。 java:65)
at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:28)
at com.netflix.astyanax.thrift.ThriftSyncConnectionFactoryImpl $ ThriftConnection.execute(ThriftSyncConnectionFactoryImpl.java: 151)
at com.netflix.astyanax.connectionpool.impl.AbstractExecuteWithFailoverImpl.tryOperation(AbstractExecuteWithFailoverImpl.java:69)
at com.netflix.astyanax.connectionpool.impl.AbstractHostPartitionConnectionPool.executeWithFailover(AbstractHostPartitionConnectionPool.java: 256)
at com.netflix.astyanax.thrift.ThriftKeyspaceImpl.executeOperation(ThriftKeyspaceImpl.java:485)
at com.netflix.astyanax.thrift.ThriftKeyspaceImpl.access $ 000(ThriftKeyspaceImpl.java:79)
at com.netflix.astyanax.thrift.ThriftKeyspaceImpl $ 1.execute(ThriftKeyspaceImpl.java:123)
at com.cassandra.astyanax.CassandraAstyanaxClient.upsertCompositeAttributes(CassandraAstyanaxClient.java:167)
at com .example.AstyanaxCompositeColumns.main(AstyanaxCompositeColumns.java:24)
引发者:InvalidRequestException(为什么:没有足够的字节读取组件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 com.netflix.astyanax.thrift.ThriftKeyspaceImpl $ 1 $ 1.internalExecute(ThriftKeyspaceImpl .java:129)
at com.netflix.astyanax.thrift.ThriftKeyspaceImpl $ 1 $ 1.internalExecute(ThriftKeyspaceImpl.java:126)
at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java :60)
... 9 more

下面是我的CassandraAstyanaxConnection类 -

  private CassandraAstyanaxConnection(){

context = new AstyanaxContext.Builder()
forfor .CLUSTER)
.forKeyspace(Constants.KEYSPACE)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl(MyConnectionPool)
.setPort(9160)
.setMaxConnsPerHost(1000)
.setSeeds(host:9160)

.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion(3.0.0)
.setTargetCassandraVersion(1.2)
.setConnectionPoolType(ConnectionPoolType.ROUND_ROBIN)
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance

context.start();
keyspace = context.getEntity();

emp_cf = ColumnFamily.newColumnFamily(
Constants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}

首先,我的列族是否正确?

  create column family USER_DATA 
with key_validation_class ='UTF8Type'
and comparator ='CompositeType(UTF8Type,UTF8Type,DateType) '
and default_validation_class ='UTF8Type'
and gc_grace = 86400;

下面是我们的用例 -

  user-id column1 column2 column3 
123(Column1- Value Column1- SchemaName LMD)(Column2- Value Column2- SchemaName LMD)(Column3- Value Column3- SchemaName LMD)

对于每个用户ID,我们将存储column1及其值,该值将存储这三个总是 -

 (Column1-Value Column1-SchemaName LMD)

在上面的例子中,我只显示三列,但可能有更多列。



运行Cassandra 1.2.9

解决方案

创建ColumnFamily时,参数为columnName,rowKey序列化器和列 name 序列化程序。列类型序列化程序(complexTypeSerializer)仅在putColumn中使用。您应该有:

  ColumnFamily columnFamily = new ColumnFamily(columnFamilyName,StringSerializer.get(),StringSerializer.get 

因为您不使用复合列名称而是使用复合列值。


I am tyring to insert into Composite Column in Cassandra column family using Astyanax client. Below is my column family in Cassandra.

create column family USER_DATA
with key_validation_class = 'UTF8Type'
and comparator = 'CompositeType(UTF8Type,UTF8Type,DateType)'
and default_validation_class = 'UTF8Type'
and gc_grace = 86400;

I am expecting after insertion, it will look like this

user-id   column1
123      (Column1-Value  Column1-SchemaName  LastModifiedDate)

Below is my java main code-

public static void main(String[] args) {

    ComplexType ct = new ComplexType();
    ct.setVal1("Hello");
    ct.setVal2("World");
    ct.setTimestamp(System.currentTimeMillis());

    // e1 is the column-name and ct is its composite-value.
    attributesMap.put("e1", ct);

    clientDao.upsertCompositeAttributes("123", attributesMap, "USER_DATA");
}

Below is my ComplexType class-

public static class ComplexType {
    @Component(ordinal = 0)
    String val1;

    @Component(ordinal = 1)
    String val2;

    @Component(ordinal = 2)
    long timestamp;


    public String getVal1() {
        return val1;
    }
    public void setVal1(String val1) {
        this.val1 = val1;
    }
    public String getVal2() {
        return val2;
    }
    public void setVal2(String val2) {
        this.val2 = val2;
    }
    public long getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
}

Below is my upsertCompositeAttributes method in my DAOImpl class.

public void upsertCompositeAttributes(final String rowKey, final Map<String, ComplexType> ct, final String columnFamilyName) {

    try {
        AnnotatedCompositeSerializer<ComplexType> complexTypeSerializer = new AnnotatedCompositeSerializer<ComplexType>(ComplexType.class);

        ColumnFamily columnFamily = new ColumnFamily(columnFamilyName, StringSerializer.get(), StringSerializer.get());

        MutationBatch m = CassandraAstyanaxConnection.getInstance().getKeyspace().prepareMutationBatch();

        ColumnListMutation<String> mutation = m.withRow(columnFamily, rowKey);

        for (Map.Entry<String, ComplexType> entry : ct.entrySet()) {
          // entry.getKey() is the column name and entry.getValue() is its composite value.
            mutation = mutation.putColumn(entry.getKey(), entry.getValue(), complexTypeSerializer, null);
        }

        m.setConsistencyLevel(ConsistencyLevel.CL_ONE).execute();

    } catch (ConnectionException e) {

    } catch (Exception e) {

    }
}

Now I am getting the below exception-

com.netflix.astyanax.connectionpool.exceptions.BadRequestException: BadRequestException: [host=10.109.107.27(10.109.107.27):9160, latency=99(131), attempts=1]InvalidRequestException(why:Not enough bytes to read value of component 0)
    at com.netflix.astyanax.thrift.ThriftConverter.ToConnectionPoolException(ThriftConverter.java:159)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:65)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:28)
    at com.netflix.astyanax.thrift.ThriftSyncConnectionFactoryImpl$ThriftConnection.execute(ThriftSyncConnectionFactoryImpl.java:151)
    at com.netflix.astyanax.connectionpool.impl.AbstractExecuteWithFailoverImpl.tryOperation(AbstractExecuteWithFailoverImpl.java:69)
    at com.netflix.astyanax.connectionpool.impl.AbstractHostPartitionConnectionPool.executeWithFailover(AbstractHostPartitionConnectionPool.java:256)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl.executeOperation(ThriftKeyspaceImpl.java:485)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl.access$000(ThriftKeyspaceImpl.java:79)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl$1.execute(ThriftKeyspaceImpl.java:123)
    at com.cassandra.astyanax.CassandraAstyanaxClient.upsertCompositeAttributes(CassandraAstyanaxClient.java:167)
    at com.example.AstyanaxCompositeColumns.main(AstyanaxCompositeColumns.java:24)
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 com.netflix.astyanax.thrift.ThriftKeyspaceImpl$1$1.internalExecute(ThriftKeyspaceImpl.java:129)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl$1$1.internalExecute(ThriftKeyspaceImpl.java:126)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:60)
    ... 9 more

Below is my CassandraAstyanaxConnection class-

private CassandraAstyanaxConnection() {

    context = new AstyanaxContext.Builder()
    .forCluster(Constants.CLUSTER)
    .forKeyspace(Constants.KEYSPACE)
    .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
        .setPort(9160)
        .setMaxConnsPerHost(1000)
        .setSeeds("host:9160")
    )
    .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
        .setCqlVersion("3.0.0")
        .setTargetCassandraVersion("1.2")
        .setConnectionPoolType(ConnectionPoolType.ROUND_ROBIN)
        .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE))
    .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
    .buildKeyspace(ThriftFamilyFactory.getInstance());

    context.start();
    keyspace = context.getEntity();

    emp_cf = ColumnFamily.newColumnFamily(
        Constants.COLUMN_FAMILY, 
        StringSerializer.get(), 
        StringSerializer.get());
}

First of all, my column family is correct or not?

create column family USER_DATA
with key_validation_class = 'UTF8Type'
and comparator = 'CompositeType(UTF8Type,UTF8Type,DateType)'
and default_validation_class = 'UTF8Type'
and gc_grace = 86400;

Below is my requirement per our use case-

user-id   column1                                        column2                                     column3
123      (Column1-Value  Column1-SchemaName  LMD)       (Column2-Value Column2-SchemaName  LMD)     (Column3-Value  Column3-SchemaName  LMD)

For each user-id, we will be storing column1 and its value and that value will store these three things always-

(Column1-Value   Column1-SchemaName     LMD)

In my above example, I have show only three columns but it might have more columns.

I am running Cassandra 1.2.9

解决方案

When you create the ColumnFamily, the arguments are for the columnName, the rowKey serializer and the column name serializer. The column type serializer (complexTypeSerializer) is only used in the putColumn. You should have:

ColumnFamily columnFamily = new ColumnFamily(columnFamilyName, StringSerializer.get(), StringSerializer.get());

since you are not using composite column names but composite column values.

这篇关于没有足够的字节使用复合列与Astyanax客户端读取组件的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆