我从最近几天开始使用Casandra,这就是我想要做的事情。
我有大约2百万个+对象来维护用户的个人资料。我将这些对象转换为json,压缩并将它们存储在blob列中。平均压缩json大小约为10KB。这就是我的表在cassandra中的样子,
表:
dev.userprofile (uid varchar primary key, profile blob);
选择查询: 从dev.userprofile中选择配置文件,其中uid ='';
更新查询:
update dev.userprofile set profile='<bytebuffer>' where uid = '<uid>'
每小时,我从队列中获取事件,我将其应用于我的userprofile对象。每个事件对应一个userprofile对象。我得到大约1百万个这样的事件,所以我必须在短时间内更新大约1M的userprofile对象,即更新我的应用程序中的对象,压缩json并更新cassandra blob。我必须在几分钟内完成更新所有1百万个用户配置文件对象。但我注意到它现在需要更长的时间。
在运行我的应用程序时,我注意到平均每秒可以更新大约400个配置文件。我已经看到很多CPU iowait - 在cassandra实例上70%以上。此外,最初的负载在16左右(在8 vcpu实例上)相当高,然后下降到4左右。
我做错了什么?因为,当我更新大小为2KB的较小对象时,我注意到cassandra operations / sec要快得多。我能够获得大约3000运转/秒。关于如何改善表现的任何想法?
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-extras</artifactId>
<version>3.1.0</version>
</dependency>
我在m4.2xlarge aws实例中只有一个cassandra设置节点用于测试
Single node Cassandra instance
m4.2xlarge aws ec2
500 GB General Purpose (SSD)
IOPS - 1500 / 10000
nodetool cfstats输出
Keyspace: dev
Read Count: 688795
Read Latency: 27.280683695439137 ms.
Write Count: 688780
Write Latency: 0.010008401811899301 ms.
Pending Flushes: 0
Table: userprofile
SSTable count: 9
Space used (live): 32.16 GB
Space used (total): 32.16 GB
Space used by snapshots (total): 0 bytes
Off heap memory used (total): 13.56 MB
SSTable Compression Ratio: 0.9984539538554672
Number of keys (estimate): 2215817
Memtable cell count: 38686
Memtable data size: 105.72 MB
Memtable off heap memory used: 0 bytes
Memtable switch count: 6
Local read count: 688807
Local read latency: 29.879 ms
Local write count: 688790
Local write latency: 0.012 ms
Pending flushes: 0
Bloom filter false positives: 47
Bloom filter false ratio: 0.00003
Bloom filter space used: 7.5 MB
Bloom filter off heap memory used: 7.5 MB
Index summary off heap memory used: 2.07 MB
Compression metadata off heap memory used: 3.99 MB
Compacted partition minimum bytes: 216 bytes
Compacted partition maximum bytes: 370.14 KB
Compacted partition mean bytes: 5.82 KB
Average live cells per slice (last five minutes): 1.0
Maximum live cells per slice (last five minutes): 1
Average tombstones per slice (last five minutes): 1.0
Maximum tombstones per slice (last five minutes): 1
nodetool cfhistograms输出
Percentile SSTables Write Latency Read Latency Partition Size Cell Count
(micros) (micros) (bytes)
50% 3.00 9.89 2816.16 4768 2
75% 3.00 11.86 43388.63 8239 2
95% 4.00 14.24 129557.75 14237 2
98% 4.00 20.50 155469.30 17084 2
99% 4.00 29.52 186563.16 20501 2
Min 0.00 1.92 61.22 216 2
Max 5.00 74975.55 4139110.98 379022 2
Dstat输出
---load-avg--- --io/total- ---procs--- ------memory-usage----- ---paging-- -dsk/total- ---system-- ----total-cpu-usage---- -net/total-
1m 5m 15m | read writ|run blk new| used buff cach free| in out | read writ| int csw |usr sys idl wai hiq siq| recv send
12.8 13.9 10.6|1460 31.1 |1.0 14 0.2|9.98G 892k 21.2G 234M| 0 0 | 119M 3291k| 63k 68k| 1 1 26 72 0 0|3366k 3338k
13.2 14.0 10.7|1458 28.4 |1.1 13 1.5|9.97G 884k 21.2G 226M| 0 0 | 119M 3278k| 61k 68k| 2 1 28 69 0 0|3396k 3349k
12.7 13.8 10.7|1477 27.6 |0.9 11 1.1|9.97G 884k 21.2G 237M| 0 0 | 119M 3321k| 69k 72k| 2 1 31 65 0 0|3653k 3605k
12.0 13.7 10.7|1474 27.4 |1.1 8.7 0.3|9.96G 888k 21.2G 236M| 0 0 | 119M 3287k| 71k 75k| 2 1 36 61 0 0|3807k 3768k
11.8 13.6 10.7|1492 53.7 |1.6 12 1.2|9.95G 884k 21.2G 228M| 0 0 | 119M 6574k| 73k 75k| 2 2 32 65 0 0|3888k 3829k
修改
切换到LeveledCompactionStrategy&amp;在sstables上禁用压缩,我没有看到很大的改进:
更新的配置文件/秒有一些改进。现在550-600个配置文件/秒。但是,cpu峰值仍然是iowait。
gcstats
Interval (ms) Max GC Elapsed (ms)Total GC Elapsed (ms)Stdev GC Elapsed (ms) GC Reclaimed (MB) Collections Direct Memory Bytes
755960 83 3449 8 73179796264 107 -1
dstats
---load-avg--- --io/total- ---procs--- ------memory-usage----- ---paging-- -dsk/total- ---system-- ----total-cpu-usage---- -net/total-
1m 5m 15m | read writ|run blk new| used buff cach free| in out | read writ| int csw |usr sys idl wai hiq siq| recv send
7.02 8.34 7.33| 220 16.6 |0.0 0 1.1|10.0G 756k 21.2G 246M| 0 0 | 13M 1862k| 11k 13k| 1 0 94 5 0 0| 0 0
6.18 8.12 7.27|2674 29.7 |1.2 1.5 1.9|10.0G 760k 21.2G 210M| 0 0 | 119M 3275k| 69k 70k| 3 2 83 12 0 0|3906k 3894k
5.89 8.00 7.24|2455 314 |0.6 5.7 0|10.0G 760k 21.2G 225M| 0 0 | 111M 39M| 68k 69k| 3 2 51 44 0 0|3555k 3528k
5.21 7.78 7.18|2864 27.2 |2.6 3.2 1.4|10.0G 756k 21.2G 266M| 0 0 | 127M 3284k| 80k 76k| 3 2 57 38 0 0|4247k 4224k
4.80 7.61 7.13|2485 288 |0.1 12 1.4|10.0G 756k 21.2G 235M| 0 0 | 113M 36M| 73k 73k| 2 2 36 59 0 0|3664k 3646k
5.00 7.55 7.12|2576 30.5 |1.0 4.6 0|10.0G 760k 21.2G 239M| 0 0 | 125M 3297k| 71k 70k| 2 1 53 43 0 0|3884k 3849k
5.64 7.64 7.15|1873 174 |0.9 13 1.6|10.0G 752k 21.2G 237M| 0 0 | 119M 21M| 62k 66k| 3 1 27 69 0 0|3107k 3081k
您可能会注意到cpu峰值。
在我进一步增加负载之前,我主要担心的是iowait。有什么特别的东西,我应该寻找那导致这个?因为600条简介/秒(即600条读取+写入)对我来说似乎很低。
答案 0 :(得分:1)
你能试试LeveledCompactionStrategy吗?在这样的大型对象上进行1:1读/写操作时,读取时保存的IO可能会抵消在更昂贵的压缩上花费的IO。
如果您在发送数据之前已经压缩了数据,则应该关闭表格上的压缩。它将其分解为64kb块,这将主要由6个值组成,这些值不会受到太多压缩(如可怕的压缩比SSTable Compression Ratio: 0.9984539538554672
所示)。
ALTER TABLE dev.userprofile
WITH compaction = { 'class' : 'LeveledCompactionStrategy' }
AND compression = { 'sstable_compression' : '' };
400个配置文件/秒非常非常慢,并且您的客户端可能还有一些工作可能会成为瓶颈。如果你在8核系统上有4负载,那么Cassandra可能不会放慢速度。确保并行化请求并异步使用它们,顺序发送请求是一个常见问题。
对于更大的blob,会对GC产生影响,因此监控它们并添加该信息可能会有所帮助。我会惊讶于10kb对象会影响它,但需要注意的事情可能需要更多的JVM调优。
如果有帮助,我会建议调整堆并升级到至少3.7或最新的3.0行。