【问题标题】:Cassandra updates are not always consistentCassandra 更新并不总是一致的
【发布时间】:2013-07-07 13:11:41
【问题描述】:

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

我的键空间设置是:

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

我正在使用以下方法对我的用户会话表进行更新:

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 相关,但我正在做一些不同的事情。)

编辑:我的密钥空间是通过以下方式设置的:

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: 我已将所有查询的一致性级别设置为“ALL”,并将 replication_factor 切换为 1。此外,我已切换到一个(应用程序服务器)客户端,以确保这与客户端时间戳无关。读写是同步进行的,但是问题还是随机出现的。

【问题讨论】:

    标签: java cassandra astyanax


    【解决方案1】:

    您也可以尝试在读取时设置一致性级别,以确保您做的事情正确,例如

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

    让我知道这是否有帮助,然后我们可以从那里开始。

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

    【讨论】:

    • 谢谢,我过几天试试。
    • 我已将所有查询的一致性级别设置为“ALL”,并将 replication_factor 切换为 1。此外,我已切换到一个(应用程序服务器)客户端,以确保这没有任何问题处理客户端时间戳。读取和写入是同步完成的,但问题仍然随机发生。您还有其他想法吗?
    • 抱歉@Chris,我不知道有什么问题,除非您用于插入的时钟实现有问题。尝试调试以查看是否是这种情况,并且您有两个或多个具有相同时间戳的插入。我发现的 cassandra 的特点是,如果您有两个具有相同时间戳和键的插入,则具有更高字节值 col 名称的插入将优先,因此可能需要查看。
    • @Nikola - 谢谢!我有同样的问题,这是由时钟漂移引起的。
    猜你喜欢
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多