我们尝试使用IN
查询从Cassandra
数据库中获取数据,以过滤特定时间段的数据,如下所述:
"SELECT * FROM "+ DATABASES['default']['NAME'] +".perform_stats WHERE device_id IN (" + ','.join(device_id_lst) + " AND created_at <= " + created_at +" and created_at >= " start_time + ";"
但随机观察下面的错误日志。
cassandra.cluster.NoHostAvailable: ('Unable to complete the operation against any hosts', {<Host: host:9042 datacenter1>: ConnectionBusy('Connection host:9042 is overloaded')})
File "/opt/app-root/lib64/python3.8/site-packages/cassandra/cqlengine/query.py", line 515, in __iter__
File "/opt/app-root/lib64/python3.8/site-packages/cassandra/cqlengine/query.py", line 472, in _execute_query
File "/opt/app-root/lib64/python3.8/site-packages/cassandra/cqlengine/query.py", line 404, in _execute
File "/opt/app-root/lib64/python3.8/site-packages/cassandra/cqlengine/query.py", line 1531, in _execute_statement
File "/opt/app-root/lib64/python3.8/site-packages/cassandra/cqlengine/connection.py", line 345, in execute
File "cassandra/cluster.py", line 2618, in cassandra.cluster.Session.execute
File "cassandra/cluster.py", line 4877, in cassandra.cluster.ResponseFuture.result
cassandra.cluster.NoHostAvailable: ('Unable to complete the operation against any hosts', {<Host: host:9042 datacenter1>: ConnectionBusy('Connection host:9042 is overloaded')})
在单个查询中,我们尝试在15分钟内获取大约10个设备的数据,对于每个设备,我们有4个条目,持续15分钟。因此,每次查询总计约40个条目。但是观察到系统内存缓存消耗急剧增加,尽管其堆内存约为6/8 GB,并且随机观察上述错误。
你可以参考下面的模式
CREATE TABLE sample.perform_stats (
device_id uuid,
created_at bigint,
stats_data text,
PRIMARY KEY (device_id, created_at)
) WITH CLUSTERING ORDER BY (created_at DESC)
AND bloom_filter_fp_chance = 0.01
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
AND comment = ''
AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND crc_check_chance = 1.0
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99PERCENTILE';
当前环境的详细信息如下:
CentOS Version: 7.9
Cassandra version: 4.1.0
Java Version: 11.0.18
python Version: 3.6.8
Django: 3.1.4
django-cassandra-engine: 1.6.1
cassandra-driver==3.24.0
我们已经尝试增加内存,并将每个查询的设备数量从2500减少到10个设备。我们还尝试将django
ORM
查询替换为Cassandra
RAW
查询。但到目前为止,没有任何好处。
任何人都可以建议什么可以是这个问题的可能原因和方法,以进一步调试,以解决这个问题?
1条答案
按热度按时间iqih9akk1#
这是预期的行为。问题是您的查询使集群中的节点过载。
当您在多个分区上使用
IN()
操作符时,查询的协调器必须发出多个单独的请求来获取所有分区。这是一种非常昂贵的分散-聚集访问模式,这意味着客户端请求在协调器上排队,直到它们的队列填满。当协调器的队列达到容量时(因为它正在等待其他节点响应多个请求),它不再能够接受新的请求,导致
ConnectionBusy
错误。它到达了一个点,所有节点都已使其队列达到最大,导致NoHostAvailable
异常。IN()
运算符不是为多分区筛选设计的。相反,它应该只用于筛选单个分区内的行(只用于筛选聚类列)。根据我的经验,在分区键上使用
IN()
操作符只有在有2个项目要过滤时才有效,最多可能有3个。再多的话,表现就变得非常不可预测了。如果在分区键上使用了
IN()
操作符,则表明数据模型不正确。您应该根据应用程序查询对表进行分区。干杯!