问题描述
我有一个非常简单的 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
子句。