1

我遇到了非常奇怪的行为,并试图了解在哪些情况下可能会发生这种情况。在我的Python应用程序中,我通过驱动程序访问Cassandra数据库。

正如你在下面看到的,首先,我做了一个INSERT操作,它在表中创建了一条记录。接下来,我执行一个SELECT操作,该操作应返回之前创建的最后一条消息。有时选择操作会向我返回空值。我假设 Cassandra 有一个内部调度程序来执行 INSERT 任务。但是,当我尝试通过 SELECT 操作获取最后一条记录时,该记录尚未创建。这可能吗?

问题

是否可以在成功创建记录的 INSERT 操作后从 Cassandra 获得回调?

片段

import uuid
import sys
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement, dict_factory


def send_message(chat_room_id, message_author_id, message_text):
    message_id = uuid.uuid1()


    first_query = """
    insert into messages (
        created_date_time,
        chat_room_id,
        message_id,
        message_author_id,
        message_text
    ) values (
        toTimestamp(now()),
        {0},
        {1},
        {2},
        {3}
    );
    """.format(
        chat_room_id,
        message_id,
        message_author_id,
        message_text
    )

    first_statement = SimpleStatement(
        first_query,
        consistency_level=ConsistencyLevel.LOCAL_QUORUM
    )

    try:
        db_connection.execute(first_statement)
    except Exception as error:
        logger.error(error)
        sys.exit(1)

    db_connection.row_factory = dict_factory

    second_query = """
    select
        created_date_time,
        chat_room_id,
        message_id,
        message_author_id,
        message_text
    from
        messages
    where
        chat_room_id = {0}
    and
        message_id = {1}
    limit 1;
    """.format(
        chat_room_id,
        message_id
    )

    try:
        message = db_connection.execute(second_query).one()
    except Exception as error:
        logger.error(error)
        sys.exit(1)

    print(message) # Sometimes when it's the first message in the chat room I see a "None" value.
4

1 回答 1

2

当您执行第一个插入语句并获得结果时,这意味着 Cassandra 完成了您的插入语句。

看起来您插入的一致性级别(CL)为,LOCAL_QUORUM但选择同一记录时未设置 CL。

默认情况下,LOCAL_ONE如果未设置,python 驱动程序使用一致性级别。

https://docs.datastax.com/en/developer/python-driver/3.24/getting_started/#setting-a-consistency-level

在您的情况下,当您使用 插入记录时LOCAL_QUORUM,假设您的复制因子为 3,那么 3 个中至少有 2 个副本节点具有您的数据。

(请注意,Cassandra 总是尝试写入所有副本节点。)

然后你用 查询LOCAL_ONE,你可能会命中这两个节点并得到结果,或者你可能会命中未能写入记录的节点。

为了在 Cassandra 中实现强一致性,必须使用LOCAL_QUORUMfor reads 和 writes。

也尝试使用LOCAL_QUORUMfor select,或LOCAL_QUORUM通过默认执行配置文件将默认一致性级别设置为:https ://docs.datastax.com/en/developer/python-driver/3.24/getting_started/#execution-profiles

于 2020-11-25T10:53:07.430 回答