我正在处理单个节点。我有下表来存储文档列表:
CREATE TABLE my_keyspace.document (
status text,
date timestamp,
doc_id text,
raw_content text,
title text,
PRIMARY KEY (status, date, doc_id)
) WITH CLUSTERING ORDER BY (date ASC, doc_id ASC)
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 = 0
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';
CREATE INDEX doc_id_idx ON my_keyspace.document (doc_id);
我正在做很多查询,如:
SELECT * FROM my_keyspace.document WHERE status='PROCESSED' AND data>=start_date AND data<=end_date;
出于某种原因,它非常缓慢,起初我的警告是这样的:
[2016-07-26 18:10:46] {cassandra.protocol:378} WARNING - Server warning: Read 5000 live rows and 19999 tombstone cells for query SELECT * FROM my_keyspace.document WHERE token(status) >= token(PROCESSED) AND token(status) <= token(PROCESSED) AND date >= 2016-07-08 02:00+0200 AND date <= 2016-07-23 01:59+0200 LIMIT 5000 (see tombstone_warn_threshold)
[2016-07-26 18:10:52] {cassandra.protocol:378} WARNING - Server warning: Read 5000 live rows and 19999 tombstone cells for query SELECT * FROM my_keyspace.document WHERE token(status) >= token(PROCESSED) AND token(status) <= token(PROCESSED) AND date >= 2016-07-08 02:00+0200 AND date <= 2016-07-23 01:59+0200 LIMIT 5000 (see tombstone_warn_threshold)
认为这个问题与我做过太多的tombestones有关:
ALTER TABLE my_keyspace.document WITH gc_grace_seconds = '0';
然后:
nodetool compact my_keyspace document
现在我没有任何警告,但查询仍然很慢并且经常超时。任何有关超时的日志中都不会显示任何消息。我所拥有的文档数量大约是200k个实例。这些文件在20天内分发,每天约有4500份文件status='PROCESSED'
。查询回答时间取决于日期范围:一天时间范围约为3秒,4天为15秒,两周超时。另外,我禁用了交换。我使用的Cassandra版本是3.5。
最近我注意到,提取精确列而不是*正在改善响应时间,但系统仍然太慢。
编辑:根据Reveka提出的计算分区大小
所以,遵循以下公式:
因此值的数量是90000 *(19-3)= 1,440,000
对于分区的大小,我估计大约1.2GB。
这可能有点大。但是,如何修改我的分区键,以便在具有较小分区时仍能够执行相同的范围查询?我可以有一个包含status
的复合分区键和从date
中提取的那一天,但是我不必指定能够按范围查询的那一天:
SELECT * FROM my_keyspace.document WHERE status='PROCESSED' AND day='someday' AND date>='start_date' AND date<='end_date';
这迫使我每天进行一次查询。
答案 0 :(得分:3)
我发现您的主键包含status,date和doc_id,并且您只使用status作为分区键。这意味着无论日期如何,所有相同状态的文档都将放在同一个分区中。我想这是一个分区的很多信息。 Cassandra在100MB(或更高版本的几百MB)的分区中运行良好,请参阅here。 Datastax D220 cource(它只需要创建一个帐户是免费的)有一个video,可以显示如何计算分区大小。您可以将结果发布到分析中,以便我们进一步为您提供帮助。 :)
编辑:尺寸分析后
您必须按日期进行分区才能拥有较小的分区。这意味着现在您将无法按范围进行查询。解决方法是根据您想要的范围进行多个查询。例如:如果你想对8月12日到8月14日的范围进行查询,你会按天拆分并进行三次查询,一次是8月12日,一次是13次,一次是14次。但是,如果你的范围很大,你将会结束检索数据的gb。我不知道你的用例,但我猜你每次进行日期范围查询都不需要gb值的文件。你能给我更多关于你的用例的信息(a.k.a你想做什么?)
PS。我还不能写评论,所以我只能通过这个答案给你建议