Как исправить проблему "Невозможно завершить операцию против любых хостов" в Кассандре?
У меня есть довольно простая функция AWS Lambda, в которой я подключаюсь к базе данных Amazon Keyspaces для Cassandra. Этот код на Python работает, но время от времени я получаю ошибку. Как мне исправить это странное поведение? У меня есть предположение, что при инициализации кластера нужно сделать дополнительные настройки. Например,
set_max_connections_per_host
. Буду признателен за любую помощь.
ОШИБКА:
('Unable to complete the operation against any hosts', {<Host: X.XXX.XX.XXX:XXXX eu-central-1>: ConnectionShutdown('Connection to X.XXX.XX.XXX:XXXX was closed')})
lambda_function.py:
import sessions
cassandra_db_session = None
cassandra_db_username = 'your-username'
cassandra_db_password = 'your-password'
cassandra_db_endpoints = ['your-endpoint']
cassandra_db_port = 9142
def lambda_handler(event, context):
global cassandra_db_session
if not cassandra_db_session:
cassandra_db_session = sessions.create_cassandra_session(
cassandra_db_username,
cassandra_db_password,
cassandra_db_endpoints,
cassandra_db_port
)
result = cassandra_db_session.execute('select * from "your-keyspace"."your-table";')
return 'ok'
sessions.py:
from ssl import SSLContext
from ssl import CERT_REQUIRED
from ssl import PROTOCOL_TLSv1_2
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from cassandra.policies import DCAwareRoundRobinPolicy
def create_cassandra_session(db_username, db_password, db_endpoints, db_port):
ssl_context = SSLContext(PROTOCOL_TLSv1_2)
ssl_context.load_verify_locations('your-path/AmazonRootCA1.pem')
ssl_context.verify_mode = CERT_REQUIRED
auth_provider = PlainTextAuthProvider(username=db_username, password=db_password)
cluster = Cluster(
db_endpoints,
ssl_context=ssl_context,
auth_provider=auth_provider,
port=db_port,
load_balancing_policy=DCAwareRoundRobinPolicy(local_dc='eu-central-1'),
protocol_version=4,
connect_timeout=60
)
session = cluster.connect()
return session
2 ответа
Нет особого смысла устанавливать максимальное количество подключений на стороне клиента, поскольку AWS Lambdas фактически "мертвы" между запусками. По той же причине рекомендуется отключить сердцебиение драйвера (с
idle_heartbeat_interval = 0
), так как никаких действий не происходит до следующего вызова функции.
Это не обязательно вызывает проблему, которую вы видите, но есть большая вероятность, что соединение повторно используется драйвером после того, как оно было закрыто на стороне сервера.
Из-за отсутствия общедоступной документации по внутренней работе AWS Keyspaces трудно понять, что происходит в кластере. Я всегда подозревал, что у AWS Keyspaces есть CQL-подобный механизм API перед Dynamo DB, поэтому есть причуды, подобные тому, что вы видите, которые трудно отследить, поскольку для этого требуются знания, доступные только внутри AWS.
FWIW драйверы DataStax не тестируются на AWS Keyspaces.
Это самая большая проблема, которую я вижу:
result = cassandra_db_session.execute('select * from "your-keyspace"."your-table";')
Код выглядит нормально, но я не вижу
WHERE
пункт. Поэтому, если данных много, один узел (выбранный в качестве координатора) должен будет построить набор результатов, извлекая данные из всех других узлов. Поскольку это приводит к (не) предсказуемо плохой производительности, это может объяснить, почему он иногда работает, но не работает в других случаях.
Совет: все запросы в Cassandra должны иметь
WHERE
пункт.