【问题标题】:How to fix problem "Unable to complete the operation against any hosts" in Cassandra?如何解决 Cassandra 中“无法完成对任何主机的操作”的问题?
【发布时间】:2021-01-28 19:41:37
【问题描述】:

我有一个非常简单的 AWS Lambda 函数,我在其中连接到 Amazon Keyspaces for 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

【问题讨论】:

    标签: python cassandra nosql amazon-keyspaces datastax-python-driver


    【解决方案1】:

    这是我看到的最大问题:

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

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

    专业提示:Cassandra 中的所有查询都应该有一个 WHERE 子句。

    【讨论】:

    • 您好!在这篇文章中,我忘了指定它,但实际上,我使用了WHERE 子句。还有什么可能导致前面提到的错误?我想我需要向集群添加额外的设置,但我不知道是哪些。您对此有何看法?
    【解决方案2】:

    在客户端设置最大连接数没有多大意义,因为 AWS Lambda 在运行之间实际上是“死的”。出于同样的原因,建议禁用驱动程序心跳(使用idle_heartbeat_interval = 0),因为在下次调用该函数之前不会发生任何活动。

    这不一定会导致您看到的问题,但很有可能连接在服务器端关闭后被驱动程序重用。

    由于缺乏关于 AWS Keyspaces 内部运作的公共文档,因此很难知道集群上发生了什么。我一直怀疑 AWS Keyspaces 在 Dynamo DB 前面有一个类似 CQL 的 API 引擎,所以像你所看到的那样的怪癖很难追踪,因为它需要的知识只能在 AWS 内部获得。

    FWIW DataStax 驱动程序未针对 AWS Keyspaces 进行测试。

    【讨论】:

    • 非常感谢您的建议。因为每次连接数据库都需要很长的时间,所以我在lambda_handler函数之外定义了与数据库的连接。第一次调用该函数时,将创建与数据库的连接。任何后续函数调用都将使用相同的数据库连接。如果 15 分钟未使用 AWS Lambda 函数,则连接将消失。您认为这有多正确?
    • 我将尝试在集群初始化期间添加idle_heartbeat_interval,并在今天白天测试它。我会让你知道结果。
    • 再说一次,很难知道 AWS Keyspaces 如何处理连接,因此很难评论。干杯!
    猜你喜欢
    • 2017-03-24
    • 2021-07-27
    • 2016-07-11
    • 1970-01-01
    • 2018-01-16
    • 2017-11-22
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    相关资源
    最近更新 更多