我正在使用cassandra来查询实体的非常大的键空间(大约10亿条记录),并且查询似乎需要花费很多时间
键空间如下:
CREATE KEYSPACE IF NOT EXISTS DB WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1};
CREATE TABLE IF NOT EXISTS DB.table (time timeuuid, channelId int, datetime Timestamp, description text,
att1 boolean,
att2 boolean,
att3 boolean,
att4 boolean,
image blob,
PRIMARY KEY(channelId, time));
ALTER TABLE DB.table WITH compaction = {'class': 'DateTieredCompactionStrategy', 'base_time_seconds':'3600', 'max_sstable_age_days':'365'}
ALTER TABLE DB.table WITH GC_GRACE_SECONDS = 3600;
CREATE CUSTOM INDEX att1index ON SUSEDB.suspectentity (att1) USING 'org.apache.cassandra.index.sasi.SASIIndex';
CREATE CUSTOM INDEX att2index ON SUSEDB.suspectentity (att2) USING 'org.apache.cassandra.index.sasi.SASIIndex';
运行以下查询
select channelid from suspectentity where channelid = 100 and time >= mintimeuuid('2016-06-29 23:00') and time <= mintimeuuid('2016-06-29 23:50') and att1= true;
查询运行大约4.5秒,&#34;合并数据来自memtables和23 sstables&#34;为什么需要这么长时间?
>Preparing statement - 396
>
>Index mean cardinalities are attributesfacehat:-9223372036854775808. Scanning >with att1index. - 1545
>
>Computing ranges to query - 1583
>
>Submitting range requests on 1 ranges with a concurrency of 1 (-3.24259165E16 >rows per range expected) - 1638
>
>Submitted 1 concurrent range requests - 1688
>
>Executing read on susedb.suspectentity using index attributesfacehat - 5453
>
>Executing single-partition query on suspectentity - 6450
>
>Acquiring sstable references - 6487
>
>cache hit for sstable 5520 - 6669
>
>cache hit for sstable 5487 - 6967
>cache hit for sstable 5569 - 36011
>
>cache hit for sstable 5309 - 36324
>
>cache hit for sstable 5085 - 36564
>
>Skipped 21/26 non-slice-intersecting sstables, included 18 due to tombstones - 230753
>
>cache hit for sstable 5968 - 230920
>
>cache hit for sstable 5939 - 231177
>
>cache hit for sstable 5933 - 231363
>
>cache hit for sstable 5922 - 231533
>
>cache hit for sstable 5901 - 231717
>
>cache hit for sstable 5896 - 231892
>
>cache hit for sstable 5886 - 232056
>
>cache hit for sstable 5879 - 232265
>
>cache hit for sstable 5943 - 232418
>
>cache hit for sstable 5751 - 232615
>
>cache hit for sstable 5777 - 232769
>
>cache hit for sstable 5969 - 232949
>
>cache hit for sstable 5627 - 233133
>
>cache hit for sstable 5680 - 233321
>
>cache hit for sstable 5489 - 262047
>
>cache hit for sstable 5326 - 283459
>
>cache hit for sstable 5581 - 283539
>
>cache hit for sstable 5348 - 283620
>
>Merged data from memtables and 23 sstables - 4321883
>Read 500 live and 0 tombstone cells - 4324074
答案 0 :(得分:3)
看起来查询使用范围和索引来生成结果。这两种操作都大量利用布隆过滤器来优化其读取路径。但是由于这个表的创建方式,我认为由于以下原因,布隆过滤机会设置得太低了:
由于在没有指定压缩策略的情况下创建了表,因此将使用默认的SizeTieredCompactionStrategy,以及它的默认值bloom_filter_fp_chance为0.01这对于DateTieredCompactionStrategy的设置来说太低了,这个压缩策略的默认值是bloom_filter_fp_chance of 0.1(更多的东西通常是递减收益)。
要将布隆过滤器调整为适当的设置:
ALTER TABLE DB.table WITH bloom_filter_fp_chance = 0.1;
最后,最好的做法是在创建表时定义所需的压缩策略,而不是ALTER语句,以避免将来出现类似问题。
答案 1 :(得分:0)
这里的令牌分配是什么。如果这是一个vnode令牌类型,那么每个分区键的块将分布在您的节点上。 这可能会导致读取延迟。 我不认为分区是数据模型中的宽行。
但您使用的压缩策略是DateTieredCompactionStrategy。使用Datetiered,您应该查询最新数据。它对时间序列用例更有用。如果要查询的数据是旧的,则大部分数据将刷新到磁盘并最终标记为逻辑删除。 您可以在此处详细了解:http://www.datastax.com/dev/blog/dtcs-notes-from-the-field
答案 2 :(得分:0)
分区中的20M行是真正的问题 - 您的查询会在执行读取时生成大量java对象(请参阅Cassandra jira#9754),这可能会填满您的新内容并导致在促销期间暂停/集合。
您的数据模型存在问题,但您可以通过提高堆大小来解决这个问题(特别是如果您正在使用CMS,则可以解决新的堆大小问题。)