首页 > 解决方案 > 优化子句查询cassandra?

问题描述

我在 Scylladb 有一张这样的桌子。为了清楚起见,我从下表中删除了很多列,但总的来说,这张表总共有 25 列。

CREATE TABLE testks.client (
    client_id int,
    lmd timestamp,
    cola list<text>,
    colb list<text>,
    colc boolean,
    cold int,
    cole int,
    colf text,
    colg set<frozen<colg>>,
    colh text,
    PRIMARY KEY (client_id, lmd)
) WITH CLUSTERING ORDER BY (lmd DESC)
    AND bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
    AND comment = ''
    AND compaction = {'class': 'TimeWindowCompactionStrategy', 'compaction_window_size': '1', 'compaction_window_unit': 'DAYS'}
    AND compression = {'sstable_compression': '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 = 172800
    AND max_index_interval = 1024
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';

现在我们的查询模式是这样的。50 clientIds我可以在我的IN条款中拥有更多。

select * FROM testks.client WHERE client_id IN ? PER PARTITION LIMIT 1

几个问题:

我们在一个 DC 中运行 6 个节点集群,RF 为 3。我们作为本地仲裁进行读/写。

标签: database-designcassandrascylla

解决方案


当您发出IN分区键时,请求被发送到协调器节点(我不记得了,我认为在这种情况下,它可能是任意节点),然后协调器节点将其分解IN为对各个分区的查询,执行查询到特定的副本,收集数据并发送给调用者。所有这些都会导致协调器节点和副本之间的额外往返,以及协调器的额外负载。

通常,更好的解决方案是为列表中的每个分区发出 N 个异步查询IN,并在客户端收集数据 - 当您使用准备好的语句时,驱动程序将能够使用令牌感知负载平衡,并将查询直接发送到副本持有给定的分区,因此您可以避免协调器和副本之间的额外网络往返。


推荐阅读