Cassandra中的慢速查询

时间:2016-07-29 10:37:05

标签: cassandra nosql

我正在处理单个节点。我有下表来存储文档列表:

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提出的计算分区大小

所以,遵循以下公式:

  • 行数= 20 * 4500 = 90,000
  • 列数= 19
  • 主键数= 3
  • 静态列数= 0

因此值的数量是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';

这迫使我每天进行一次查询。

1 个答案:

答案 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。我还不能写评论,所以我只能通过这个答案给你建议