Cassandra中的行排序
Posted
技术标签:
【中文标题】Cassandra中的行排序【英文标题】:Row ordering in Cassandra 【发布时间】:2014-03-28 07:26:16 【问题描述】:我在 Cassandra 2.0.5 中有以下列族,使用 Murmur3Partitioner
。在这个列族中,我存储了一个时间范围内唯一散列的幻影数量(从随时间发生的事件中提取的散列 - 并不真正相关)。
我的用例是选择给定时间范围内的所有哈希及其计数(hour
字段)。
由于数据量可能非常大,我尝试使用LIMIT
进行分页并从最后返回的哈希继续,如下例所示。它似乎起作用,因为散列似乎以升序排序返回。
有人可以解释这是否真的有效,为什么?特别是因为我发现this link 指出行是……没有排序的,所以现在我想起来了,应该随机返回散列。
我确实通过使用分页方法计算行数并在 cqlsh 中使用 COUNT
来验证该过程,但我真的不能
检查是否由于数据量大而返回了所有正确的哈希值。
cqlsh:db> DESCRIBE COLUMNFAMILY hashes ;
CREATE TABLE hashes (
hour text,
hash text,
count counter,
PRIMARY KEY (hour, hash)
) WITH COMPACT STORAGE AND
bloom_filter_fp_chance=0.010000 AND
caching='KEYS_ONLY' AND
comment='' AND
dclocal_read_repair_chance=0.000000 AND
gc_grace_seconds=864000 AND
index_interval=128 AND
read_repair_chance=0.100000 AND
replicate_on_write='true' AND
populate_io_cache_on_flush='false' AND
default_time_to_live=0 AND
speculative_retry='99.0PERCENTILE' AND
memtable_flush_period_in_ms=0 AND
compaction='class': 'SizeTieredCompactionStrategy' AND
compression='sstable_compression': 'LZ4Compressor';
cqlsh:db> SELECT * FROM hashes WHERE hour = '2014032710' LIMIT 10;
hour | hash | count
------------+------------------------------------------------------------------+----------
2014032710 | 000034d4b821c9af90bbf39cd803d45b25d7c14777697b8d9fc71c3a102c360f | 1
2014032710 | 000063b39f526788dc026a07abe1bc1365652772e9c66be9a7408b16c61962fa | 2
2014032710 | 00009c38834cedfb37bfd95355bba1a225aea6ee74f5ddc4ace820bfc33eb7a6 | 1
2014032710 | 0000a68de59092e0326b3ceff8d9a1167c7f5ea0aac804389c259f336956e520 | 1
2014032710 | 0000b0fed9e2f8f70e5e46f084be1872f0d1944c0e89a8850e6b7c3be17b8935 | 9
2014032710 | 0001204a0fb29d3a8ac7164e451662069d19307ea56e014215a64cc606cf4df9 | 1
2014032710 | 00015c165622a3c8b88d33e471d740088d9b6203dd81235d50ec129c40282229 | 1
2014032710 | 00019ed1b3287ed808c24146d1f2e145238478b49ad3740fb58cb46bc509965a | 10
2014032710 | 00019fa833cee60e7a1b8ed5d5c6fbef8c401a144e1537e15c9a5f65672d44fb | 1
2014032710 | 0001df8d8319524a93ed523382a6cce8de9234211d5f3dc46bb4c530d9385150 | 1
(10 rows)
cqlsh:db> SELECT * FROM hashes WHERE hour = '2014032710' AND hash > '0001df8d8319524a93ed523382a6cce8de9234211d5f3dc46bb4c530d9385150' LIMIT 10;
hour | hash | count
------------+------------------------------------------------------------------+----------
2014032710 | 000200428d93eb478c6a9ae0d9daa21fac88ca8dd4e536f60ae992dbea6155d4 | 2
2014032710 | 00024447d8983fc0f022df4301eb69eca4ccc7cf0fc2e9361046dbaedbe830bc | 1
2014032710 | 00025c6b3ef861fa3ef047d618f078927c9f8cf875e9b935c8e556189969bc17 | 1
2014032710 | 00026f67e525bd11b67062e3122eb625799c6878f7812da8f23f0c8e9bd9f9d5 | 2
2014032710 | 00028ded6dfe5d8616cc0eef559cfdf15fd51d5a36c17f2b9852785e8ca55c27 | 4
2014032710 | 00028f8fab859c702fe0cc51db390ce7ae85ca97807a751ddf12fed57639239f | 1
2014032710 | 0002f4046ef35e169fa79e2abf0b92212c1438487819dd8318301991ff99acac | 32
2014032710 | 000381054a59d46c87164fcfb69952afa1e77acd71f88b25e09eab3eacc1b21a | 1
2014032710 | 0003aca7fd2cab16a03d79fa7ac1505f144f9ba04fea87a050bef919aa628e74 | 1
2014032710 | 0003e6a549b01cf1634c1b2844618d4e96ac00d74be30b9401b3fbbbc5bdb7e2 | 1
(10 rows)
【问题讨论】:
【参考方案1】:请阅读有关排序宽行和聚类 ORDER KEY 的信息。 CQL 规范页面“分区键和集群列”的一些摘录
在 CQL 中,为 PRIMARY KEY 定义列的顺序很重要。键的第一列称为分区键。它的特性是所有共享相同分区键的行(甚至实际上跨表)都存储在同一个物理节点上。此外,对给定表共享相同分区键的行的插入/更新/删除是原子地和隔离地执行的。请注意,可以使用复合分区键,即由多个列组成的分区键,使用一组额外的括号来定义哪些列构成分区键。
PRIMARY KEY 定义的其余列(如果有)称为 __clustering 列。在给定的物理节点上,给定分区键的行按集群列的顺序存储,使得按集群顺序检索行特别有效(请参阅 SELECT)。
"
【讨论】:
【参考方案2】:尝试使用令牌功能和限制来滚动多行。由于您已经定义了一个复合键,这将确保排序顺序。您还可以在创建列族时查看 CLUSTERING KEY ORDER。
希望对您有所帮助。 -Vivek
【讨论】:
聚类顺序似乎很有趣;但是,我的问题是“为什么它似乎有效?”以上是关于Cassandra中的行排序的主要内容,如果未能解决你的问题,请参考以下文章
如何在 cassandra 中通过更新时间获得最后 n 个结果?
Spring Data Cassandra 中的分页和排序查询