Можно ли получить обратный вызов от Cassandra после операции INSERT, что запись была успешно создана?

Я столкнулся с очень странным поведением и пытаюсь понять, в каких случаях это может произойти. В моем приложении Python я получаю доступ к базе данных Cassandra через драйвер.

Как вы можете видеть ниже, сначала я INSERTоперация, которая создает запись в таблице. Затем я делаю SELECTоперация, которая должна вернуть последнее сообщение, которое было создано ранее. Иногда операция выбора возвращает мне пустые значения. У меня есть предположение, что у Кассандры есть внутренний планировщик, который выполняет задачу INSERT. Однако когда я пытаюсь получить последнюю запись с помощью операции SELECT, запись еще не создана. Это возможно?

ВОПРОС:

Можно ли получить обратный вызов от Cassandra после операции INSERT, что запись была успешно создана?

СНИПЕТ:

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.

1 ответ

Когда вы выполняете первый оператор вставки и получаете результат, это означает, что Кассандра завершила ваш оператор вставки.

Похоже, вы вставляете с уровнем согласованности (CL) LOCAL_QUORUM но CL не устанавливается, когда вы выбираете ту же запись.

По умолчанию драйвер python использует LOCAL_ONE для уровня согласованности, если он не установлен.

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

В вашем случае, когда вы вставляете запись с помощью LOCAL_QUORUM, если у вас коэффициент репликации 3, то по крайней мере 2 узла реплики из 3 имеют ваши данные.

(обратите внимание, что Кассандра всегда пытается писать на все узлы реплик.)

И затем вы запрашиваете с помощью LOCAL_ONE, вы можете попасть в эти 2 узла и получить результат, или вы можете попасть в тот, который не смог записать вашу запись.

Чтобы добиться сильной согласованности в Cassandra, вы должны использовать LOCAL_QUORUM для чтения и записи.

Попробуйте использовать LOCAL_QUORUM для выбора также или установите уровень согласованности по умолчанию на LOCAL_QUORUMчерез профиль выполнения по умолчанию: https://docs.datastax.com/en/developer/python-driver/3.24/getting_started/#execution-profiles

Другие вопросы по тегам