Можно ли получить обратный вызов от 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
для уровня согласованности, если он не установлен.
В вашем случае, когда вы вставляете запись с помощью
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