Cassandra更新并不总是一致的

时间:2013-07-09 19:26:05

标签: java cassandra astyanax

我在最新版本的 Datastax社区(Apache Cassandra 1.2.6)上使用 Astyanax 1.56.42 在新的双节点Cassandra群集上一个双节点的Glassfish集群,我在编写一些新的用户会话条目时发现了一些问题。

我的键空间设置是:

CREATE KEYSPACE test WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 2 };

我正在使用以下方法对我的用户会话表执行UPDATE:

KEYSPACE.prepareQuery(CF_USER_SESSIONS)
                .setConsistencyLevel(ConsistencyLevel.CL_ALL)
                .withCql("INSERT into usersessions (uid, (...)) VALUES (?, (...));")
                .asPreparedStatement()
                .withUUIDValue(uid)
                (...)
                .execute();

然后尝试用以下内容准确阅读此会话:

result = KEYSPACE.prepareQuery(CF_USER_SESSIONS)
                .withCql("SELECT * from usersessions where uid=?;")
                .asPreparedStatement()
                .withUUIDValue(uid)
                .execute();

此读取有时会失败(=没有返回行)。 “有时”意味着如果我的集群几乎空闲,它根本不会失败。但是,尽管在UPDATE语句中将setConsistencyLevel-Attribute设置为“ALL”,但它在负载较重时会更频繁。

有趣的是:延迟“解决”了这个问题。如果我稍后在新会话上尝试在cqlsh上进行手动SELECT,那么我的第二次查询就太迟了。

我做错了什么?这是一个错误吗?如何确保ConsistencyLevel.CL_ALL按预期工作?

(我的问题在某种程度上与Cassandra updates not working consistently有关,但我做的不同。)

编辑:我的Keyspace使用:

设置
CONTEXT = new AstyanaxContext.Builder()
    .forCluster("test cluster")
    .forKeyspace("test")
    .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()      
        .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
        .setCqlVersion("3.0.0")
        .setTargetCassandraVersion("1.2")
    )
    .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl(CONNECTION_POOL_NAME)
        .setPort(9160)
        .setMaxConnsPerHost(100)
        .setSeeds(SOME_CLUSTER_SEEDS_IP_AND_PORT)
    )
    .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
    .buildKeyspace(ThriftFamilyFactory.getInstance());

CONTEXT.start();
KEYSPACE = CONTEXT.getClient();
编辑#2:编辑#2: 我已经在所有查询中将一致性级别设置为“ALL”,并且我已将replication_factor切换为1.此外,我已切换到单个(应用程序服务器)客户端以确保这与客户端时间戳无关。读取和写入是同步完成的,但问题仍然是随机发生的。

1 个答案:

答案 0 :(得分:0)

您也可以尝试在读取时设置一致性级别,以确保您正确地执行操作,例如

result = KEYSPACE.prepareQuery(CF_USER_SESSIONS)
                .setConsistencyLevel(ConsistencyLevel.CL_ALL)
                .withCql("SELECT * from usersessions where uid=?;")
                .asPreparedStatement()
                .withUUIDValue(uid)
                .execute();

如果有帮助,请告诉我,然后我们可以从那里开始。

编辑:此外,如果这不起作用,请尝试将复制因子设置为1,如果这不起作用,请尝试读取/写入单个节点。