如何解决Cassandra中的问题“无法针对任何主机完成操作”?

问题描述

我有一个非常简单的 AWS Lambda函数,其中我连接到 Cassandra的Amazon Keyspaces 数据库。该代码在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

解决方法

在客户端设置最大连接没有什么意义,因为AWS Lambda在两次运行之间实际上是“死机”。出于相同的原因,建议禁用驱动程序心跳(使用idle_heartbeat_interval = 0),因为直到下一次调用该函数时,才会发生活动。

这不一定会引起您所遇到的问题,但是在服务器端关闭连接之后,驱动程序很有可能会重新使用该连接。

由于缺乏有关AWS Keyspaces内部工作的公开文档,因此很难知道集群上正在发生什么。我一直怀疑AWS Keyspaces在Dynamo DB的前面有一个类似CQL的API引擎,所以很难找到类似您所看到的怪癖,因为它只需要AWS内部提供的知识。

FWIW尚未针对AWS Keyspaces测试过DataStax驱动程序。

,

这是我看到的最大问题:

result = cassandra_db_session.execute('select * from "your-keyspace"."your-table";')

代码看起来不错,但是我没有看到WHERE子句。因此,如果有大量数据,则必须从单个节点(选择为协调器)构建结果集,同时从所有其他节点提取数据。由于这会导致(无法预料的)不良性能,因此可以解释为什么有时会有效,而其他情况不会。

提示:Cassandra中的所有查询都应带有WHERE子句。