Performance 对于Cassandra,为什么在下面的布局中1000次运算/秒会产生400MB/s的I/O?

Performance 对于Cassandra,为什么在下面的布局中1000次运算/秒会产生400MB/s的I/O?,performance,cassandra,performance-testing,Performance,Cassandra,Performance Testing,在一个3.3万亿的记录数据集上,这是一个读操作繁重的工作负载(85%读,15%写),我正在从SATA SSD(最大化控制器)中以450MB/秒的速度读取数据,但仅获得约1000次操作/秒。我不认为它应该做那么多的I/O,但我对Cassandra是新手,不太明白它为什么要这么做 Keyspace: stresscql Read Count: 81263974 Read Latency: 37.271172120563534 ms. Write Count: 18576806

在一个3.3万亿的记录数据集上,这是一个读操作繁重的工作负载(85%读,15%写),我正在从SATA SSD(最大化控制器)中以450MB/秒的速度读取数据,但仅获得约1000次操作/秒。我不认为它应该做那么多的I/O,但我对Cassandra是新手,不太明白它为什么要这么做

Keyspace: stresscql
    Read Count: 81263974
    Read Latency: 37.271172120563534 ms.
    Write Count: 18576806
    Write Latency: 0.01787069736315274 ms.
    Pending Flushes: 0
            Table: u
            SSTable count: 251
            SSTables in each level: [3, 0, 0, 0, 0, 0, 0, 0, 0]
            Space used (live): 1712307458381
            Space used (total): 1712307458381
            Space used by snapshots (total): 0
            Off heap memory used (total): 3358807452
            SSTable Compression Ratio: 0.6798834918759787
            Number of keys (estimate): 3354476152
            Memtable cell count: 0
            Memtable data size: 0
            Memtable off heap memory used: 0
            Memtable switch count: 10
            Local read count: 81263974
            Local read latency: 40.886 ms
            Local write count: 18576806
            Local write latency: 0.020 ms
            Pending flushes: 0
            Bloom filter false positives: 0
            Bloom filter false ratio: 0.00000
            Bloom filter space used: 2097321112
            Bloom filter off heap memory used: 2715609520
            Index summary off heap memory used: 633723580
            Compression metadata off heap memory used: 9474352
            Compacted partition minimum bytes: 51
            Compacted partition maximum bytes: 72
            Compacted partition mean bytes: 72
            Average live cells per slice (last five minutes): 1.0000004430007106
            Maximum live cells per slice (last five minutes): 10
            Average tombstones per slice (last five minutes): 1.0
            Maximum tombstones per slice (last five minutes): 1



### DML ###

keyspace: stresscql

keyspace_definition: |
   CREATE KEYSPACE stresscql WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};

table: u

table_definition: |
  CREATE TABLE IF NOT EXISTS u (
    c uuid,
    f bigint,
    i boolean,
    bl boolean,
    t timestamp,
    PRIMARY KEY(c,f, i)
  ) WITH compaction = { 'class': 'SizeTieredCompactionStrategy' }
  AND compression = { 'crc_check_chance' : 1.0, 'sstable_compression' : 'SnappyCompressor' }

### Column Distribution Specifications ###

columnspec:
  - name: c

  - name: f

  - name: i

  - name: bl

  - name: t

### Batch Ratio Distribution Specifications ###

insert:
  partitions: fixed(1)
  select:    fixed(1)/1
  batchtype: UNLOGGED

queries:
   selectuser:
      cql: select * from u where c = ? and f = ? and i = ?
      fields: samerow
   newselect:
      cql: select bl from u where c = ? and f = ? and i = ?
我也尝试过LeveledCompactionStrategy,这就是我得到的——仍然明显受到I/O的限制:

This row would've been cached (not using row-cache, but whatever other caching happens), since I had to select it to get the guid value for 'c'.

cqlsh> select * from stresscql.u where c = 2953e0ef-44fd-44fb-8d3e-8a2498ae694f;

 c                                    | f           | i    | bl   | t
--------------------------------------+-------------+------+------+--------------------------
 2953e0ef-44fd-44fb-8d3e-8a2498ae694f | 58180117557 | True | True | 2016-05-07 09:43:07+0000

(1 rows)

Tracing session: dd78f580-32ff-11e6-8746-45b1db7c6f51

 activity                                                                                                                                  | timestamp                  | source       | source_elapsed
-------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+--------------+----------------
                                                                                                                        Execute CQL3 query | 2016-06-15 15:48:39.512000 | 10.7.137.139 |              0
 Parsing select * from stresscql.u where c = 2953e0ef-44fd-44fb-8d3e-8a2498ae694f; [SharedPool-Worker-1] | 2016-06-15 15:48:39.512000 | 10.7.137.139 |             92
                                                                                                 Preparing statement [SharedPool-Worker-1] | 2016-06-15 15:48:39.512000 | 10.7.137.139 |            208
                                             Executing single-partition query on u [SharedPool-Worker-2] | 2016-06-15 15:48:39.513000 | 10.7.137.139 |           1626
                                                                                        Acquiring sstable references [SharedPool-Worker-2] | 2016-06-15 15:48:39.513000 | 10.7.137.139 |           1677
                                                              Partition index with 0 entries found for sstable 15405 [SharedPool-Worker-2] | 2016-06-15 15:48:39.514000 | 10.7.137.139 |           1944
                                           Skipped 0/1 non-slice-intersecting sstables, included 0 due to tombstones [SharedPool-Worker-2] | 2016-06-15 15:48:39.514000 | 10.7.137.139 |           2401
                                                                          Merging data from memtables and 1 sstables [SharedPool-Worker-2] | 2016-06-15 15:48:39.514000 | 10.7.137.139 |           2445
                                                                                                                          Request complete | 2016-06-15 15:48:39.543778 | 10.7.137.139 |          31778


Keyspace: stresscql
        Read Count: 115672739
        Read Latency: 37.24272796733031 ms.
        Write Count: 25113006
        Write Latency: 0.016802926260599788 ms.
        Pending Flushes: 0
                Table: user_identified_caller_by_telephone
                SSTable count: 847
                SSTables in each level: [1, 10, 100, 736, 0, 0, 0, 0, 0]
                Space used (live): 2032182537714
                Space used (total): 2032182537714
                Space used by snapshots (total): 0
                Off heap memory used (total): 2540382332
                SSTable Compression Ratio: 0.6868674726322842
                Number of keys (estimate): 3361569503
                Memtable cell count: 1162671
                Memtable data size: 42639539
                Memtable off heap memory used: 0
                Memtable switch count: 12
                Local read count: 115672739
                Local read latency: 40.854 ms
                Local write count: 25113006
                Local write latency: 0.019 ms
                Pending flushes: 0
                Bloom filter false positives: 1
                Bloom filter false ratio: 0.00000
                Bloom filter space used: 2115703120
                Bloom filter off heap memory used: 2115696344
                Index summary off heap memory used: 418366956
                Compression metadata off heap memory used: 6319032
                Compacted partition minimum bytes: 51
                Compacted partition maximum bytes: 72
                Compacted partition mean bytes: 72
                Average live cells per slice (last five minutes): 1.0000007348317013
                Maximum live cells per slice (last five minutes): 50
                Average tombstones per slice (last five minutes): 1.0
                Maximum tombstones per slice (last five minutes): 1

----------------

我可能读错了,但我认为你只创建了一个巨大的分区,这将是非常缓慢的压缩。在新版本(3.6,3.7)中有很多这样的功能,所以一定要使用最新的,因为最近有一些改进会有所帮助。您可能需要更改压力配置文件中的
分区:固定(1)
选择
,以使数据分布更广

可能有一点被压缩所束缚(低默认吞吐量),导致每次读取都必须接触很多SSTABLE。251对于STC来说太多了,因为对于宽分区,它可能必须从每个分区读取


有了这个数据模型和工作负载(撇开压力配置文件问题不谈),您可能应该尝试LeveledCompactionStrategy并提高压缩吞吐量(可以使用
nodetool SetCompactionThroughts
进行不同的测试,我会从64开始,但可以上下移动它,看看它如何影响您的工作负载)。压缩将占用更多的IO,但读取将占用更少的IO,这对于您的工作负载来说是更好的。

我可能读错了,但我认为您只创建了一个巨大的分区,这将是非常缓慢的压缩。在新版本(3.6,3.7)中有很多这样的功能,所以一定要使用最新的,因为最近有一些改进会有所帮助。您可能需要更改压力配置文件中的
分区:固定(1)
选择
,以使数据分布更广

可能有一点被压缩所束缚(低默认吞吐量),导致每次读取都必须接触很多SSTABLE。251对于STC来说太多了,因为对于宽分区,它可能必须从每个分区读取


有了这个数据模型和工作负载(撇开压力配置文件问题不谈),您可能应该尝试LeveledCompactionStrategy并提高压缩吞吐量(可以使用
nodetool SetCompactionThroughts
进行不同的测试,我会从64开始,但可以上下移动它,看看它如何影响您的工作负载)。压缩将占用更多的IO,但读取将占用更少的IO,这对于您的工作负载来说是更好的。

根据分区:固定(1)部分,意味着在插入批处理期间,一次只插入一个分区键。实际的分区应该基于主键的第一个元素(称为“c”的列)的值/基数,对吗?测试时未运行任何压实。我还使用LeveledCompressionStrategy进行了测试,性能非常相似,但压实时间大大增加了—一次主要压实耗时超过一周!还有一件事需要注意。主要压实后,sstables组合为3个,性能仍如上所述。至于分区——这是单个节点上cassandra的一个实例——分区发挥作用了吗?啊,你说得对(就在统计数据中,我只是看得不够近)。因此,实际上
本地写入延迟:0.020 ms
写入似乎很好,它只是读取:
本地读取延迟:40.886 ms
。巨型布卢姆过滤器可能是个问题,切换到LCS可以让你基本上摆脱它。甚至可能与索引摘要过于分散的太多分区有关,以mb为单位增加索引摘要容量可能会提供更多空间(我会在BF减少后再做)。除此之外(以及可能的jvm调优),我可能会建议使用像yourkit这样的性能工具。可能不应该在测试中进行重大压缩,因为您永远不会(不应该)在生产中使用它们。(是的,分区位于
c
btw)。关于bloom过滤器,它们不是全部存储在内存中吗?对于0%的FP速率和内存中的bloom筛选器,这并不能解释I/O。对于1000 op/s,450MB/s似乎很高。对于宽度小于63字节的列,每次读取约450k。这是我不明白的事情。表示主I/O将扫描分区摘要,然后扫描pkey索引的一小部分,然后根据索引获取数据。我改为“水平”,总吞吐量仍然是~1000 op/s。现在,我将为有关计时/cfstats的问题添加更多信息。根据分区:固定(1)部分,意味着在插入批处理期间,一次只插入一个分区键。实际的分区应该基于主键的第一个元素(称为“c”的列)的值/基数,对吗?测试时未运行任何压实。我还使用LeveledCompressionStrategy进行了测试,性能非常相似,但压实时间大大增加了—一次主要压实耗时超过一周!还有一件事需要注意。主要压实后,sstables组合为3个,性能仍如上所述。至于分区——这是单个节点上cassandra的一个实例——分区发挥作用了吗?啊,你说得对(就在统计数据中,我只是看得不够近)。因此,实际上
本地写入延迟:0.020 ms
写入似乎很好,它只是读取:
本地读取延迟:40.886 ms
。巨型布卢姆过滤器可能是个问题,切换到LCS可以让你基本上摆脱它。甚至可能与索引摘要过于分散的太多分区有关,以mb为单位增加索引摘要容量可能会提供更多空间