我正在构建一个处理非常大的数据的应用程序(超过300万)。我是cassandra的新手,我使用5节点cassandra集群来存储数据。我有两个列族
Table 1 : CREATE TABLE keyspace.table1 (
partkey1 text,
partkey2 text,
clusterKey text,
attributes text,
PRIMARY KEY ((partkey1, partkey2), clusterKey1)
) WITH bloom_filter_fp_chance = 0.01
AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
AND comment = ''
AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99.0PERCENTILE';
Table 2 : CREATE TABLE keyspace.table2 (
partkey1 text,
partkey2 text,
clusterKey2 text,
attributes text,
PRIMARY KEY ((partkey1, partkey2), clusterKey2)
) WITH bloom_filter_fp_chance = 0.01
AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
AND comment = ''
AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99.0PERCENTILE';
注意:clusterKey1和clusterKey2是随机生成的UUID的
我关注的是nodetool cfstats 我在Table1上获得了具有统计数据的良好吞吐量:
对于table2,我使用stats读取性能非常糟糕:
我想知道为什么table2正在创建33个SSTables,为什么它的读取性能非常低。谁能帮助我弄清楚我在这里做错了什么?
这是我查询表格的方式:
BoundStatement selectStamt;
if (selectStamt == null) {
PreparedStatement prprdStmnt = session
.prepare("select * from table2 where clusterKey1 = ? and partkey1=? and partkey2=?");
selectStamt = new BoundStatement(prprdStmnt);
}
synchronized (selectStamt) {
res = session.execute(selectStamt.bind("clusterKey", "partkey1", "partkey2"));
}
在另一个主题中,我正在以不同的方式对此表进行一些更新操作。
在测量吞吐量的情况下,我测量每秒处理的记录数,其处理仅为50-80 rec。
答案 0 :(得分:3)
当您拥有大量SSTable时,在这些SSTable中分发数据非常重要。由于您使用的是SizeTieredCompactionStrategy,因此当有4个相同大小的SSTable时,SSTables会被压缩和合并。
如果您经常在不同时间更新同一分区内的数据,那么您的数据很可能会分散在许多SSTable上,这会降低性能,因为您的SSTable会有多次读取。
在我看来,确认这一点的最佳方法是执行cfhistograms on your table:
nodetool -h localhost cfhistograms keyspace table2
根据您安装的cassandra版本,输出会有所不同,但它将包含为给定读取操作读取的SSTable数量的直方图。
如果您经常在不同时间更新同一分区中的数据,可以考虑使用LeveledCompactionStrategy(When to use Leveled Compaction)。 LCS会将同一分区中的数据保存在同一个SSTable中,从而大大提高读取性能,代价是更多的磁盘I / O进行压缩。根据我的经验,如果你的读写比率很高,那么额外的压缩磁盘I / O会比读取性能更好。
编辑:关于您关于吞吐量问题的问题,有许多因素限制了您的吞吐量。
答案 1 :(得分:2)
除了switching compaction strategies(这很贵,你会在改变后坚持一段时间),正如Andy建议肯定会帮助你的阅读表现,你也可以调整你当前的压缩策略试图摆脱一些碎片:
有关2和3的详细信息,请查看compaction subproperties
注意:不要使用nodetool compact。这将把整个表格放在一个巨大的sstable中,你将一次松开压缩切片的好处。
答案 2 :(得分:0)
你有很多SSTable和慢读。您应该做的第一件事是找出每个SELECT读取多少SSTable。
最简单的方法是检查相应的MBean:在MBean域" org.apache.cassandra.metrics"你找到你的密钥空间,在它下面是你的表,然后是SSTablesPerReadHistorgram MBean。 Cassandra记录最小值,最大值,平均值和百分位数。
SSTablesPerReadHistorgram中第99个百分位数的一个非常好的值是1,这意味着您通常只能从一个表中读取。如果数量与SSTable的数量一样高,Cassandra正在检查所有SSTable。在后一种情况下,您应该仔细检查您的SELECT,无论您是否对整个主键进行选择。