【问题标题】:Does Cassandra read the whole row when limiting the number of requested results?限制请求结果的数量时,Cassandra 是否会读取整行?
【发布时间】:2014-05-12 14:28:54
【问题描述】:

我正在使用 cassandra 2.0.6。并拥有这张桌子:

CREATE TABLE t (
    id text,
    idx bigint,
    data bigint,
    PRIMARY KEY (id, idx)
)

假设我得到了这些行:

id / idx / data
x    1     data1
x    2     data2
x    3     data3

....继续说 x 1000 行

如果我查询:

select * from t where id='x' order by idx limit 1

cassandra 会获取全部 1000 行,还是只获取其中的一小部分?

阅读http://www.ebaytechblog.com/2012/08/14/cassandra-data-modeling-best-practices-part-2/#.UzrvLKZx2PI 之类的文章,似乎只能获取其中的一小部分。但是运行一些压力测试并且我在表中拥有的数据越多,我获得的 MB/sec 磁盘 IO 就越多。

对于 8GB 的​​数据,我获得了 3MB/秒的 IO(读取) 对于 12GB 的数据,我获得了 15MB/秒的 IO(读取) 对于 20GB 的数据,我目前获得 35MB/秒的 IO(读取)

我没有在 cfhistograms 中看到任何奇怪的东西:

SSTables per Read
1 sstables: 421010
2 sstables: 552
3 sstables: 9
4 sstables: 0
5 sstables: 254
6 sstables: 3221
7 sstables: 3063
8 sstables: 1029
10 sstables: 143

Read Latency (microseconds)
12 us: 6
14 us: 36
17 us: 471
20 us: 2795
24 us: 10799
29 us: 18594
35 us: 24693
42 us: 43078
50 us: 67438
60 us: 68872
72 us: 70718
86 us: 47300
103 us: 23471
124 us: 11752
149 us: 4509
179 us: 1437
215 us: 832
258 us: 3444
310 us: 7883
372 us: 2374
446 us: 736
535 us: 624
642 us: 581
770 us: 1875
924 us: 1715
1109 us: 2889
1331 us: 3705
1597 us: 2197
1916 us: 1320
2299 us: 826
2759 us: 639
3311 us: 431
3973 us: 312
4768 us: 213
5722 us: 106
6866 us: 72
8239 us: 44
9887 us: 36
11864 us: 25
14237 us: 16
17084 us: 23
20501 us: 20
24601 us: 15
29521 us: 28
35425 us: 21
42510 us: 20
51012 us: 49
61214 us: 49
73457 us: 29
88148 us: 23
105778 us: 35
126934 us: 23
152321 us: 17
182785 us: 13
219342 us: 10
263210 us: 8
315852 us: 3
379022 us: 8
454826 us: 10

【问题讨论】:

    标签: cassandra column-family super-columns


    【解决方案1】:

    您可以在即时订购和限制时获得更多 I/O。如果您确定要获取数据的顺序,请在创建时对列族使用集群排序

    create table tablename(.......) with cluster order by (idx desc)

    通过这种方式,默认情况下,您的所有插入都按 idx 降序排列。因此,当你对其应用限制时,你应该减少磁盘 I/O

    【讨论】:

    • 我不是已经订购了 idx(对于相同的 id),因为 idx 是辅助主键吗?
    • 它将是但将始终按升序排列。如果这是您的要求,我已经给出了降序选项。如果您担心升序,那么您应该按照您的要求进行无序查询。
    • 啊哈,好的,我知道了,让我试试
    • 当我的数据大约为 10GB 时,我仍然获得比 1GB 更多的 I/O。 ~15GB/秒与 3GB/秒相比。虽然你的评论确实很有用,因为我的桌子应该是按 idx desc 排序的。
    • 有没有办法找出导致 I/O 的原因? (我注意在没有发生压实时进行测量)
    【解决方案2】:

    一旦您完成了聚类订购,您的订购时间就被保存下来了。如果您面临大量数据的问题,那将是由于使用了压缩策略。我觉得您在读取重列族上使用了大小分层压缩策略。使用 Leveled compaction 策略尝试相同的场景。

    当您使用大小分层压缩时,您会将数据分散到多个马厩中,并且每次都会从所有马厩中获取数据。因此,阅读繁重的列族对此并不好。

    【讨论】:

    • 谢谢,我会试一试(运行完整测试需要时间)。上面的“每次读取的 SSTables”数字怎么样,它们看起来还可以。但我也想知道当我运行一个不返回结果的查询时会发生什么(所以没有找到键)。它会尝试在所有 ss 表中查找值吗?这会产生 IO 影响吗?
    • 如果您运行的搜索没有返回任何结果,它不会对 I/O 产生影响。布隆过滤器会自动拒绝这种情况。对于您最新的 I/O 结果,如果您尝试将所有内容添加到单行,它肯定会增长。尝试拆分数据。宽行并不意味着良好的性能。它只是意味着可用性。
    • 谢谢,这只会产生更多问题:这是否意味着如果我在上面的“t”表上运行“select * from t where id='x' order by idx desc limit 1” id='x' 1.000.000 行,它会从磁盘读取大量数据吗?那么 idx 做次要 PK 有什么意义呢?在这种情况下,可用性优势是什么?无论如何,cassandra 都可以使用数据,不是吗?
    • "每个分区的数据由主键定义的剩余列或列聚集。在物理节点上,当分区键的行根据聚集列按顺序存储时,检索行数非常有效。” datastax.com/documentation/cql/3.1/cql/ddl/….
    • 在我的“t”表中,我得到了数百万行具有不同 id 的行,但也得到了数千行具有相同 id 但不同 idx 的行。
    【解决方案3】:

    我发现我实际上是不小心耗尽了结果集迭代器,修复了这个问题,现在 IO 是正常的。

    【讨论】:

      猜你喜欢
      • 2021-01-18
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多