【发布时间】:2021-11-27 15:14:21
【问题描述】:
我有一个三节点 Cassandra 集群,复制因子为 3,一致性级别为 LOCAL_QUORUM。我的表由MAP<BLOB, BLOB> 类型的两列组成。 Εach map 最多包含 100 个条目。我正在写入(追加)到两个映射中,并且正在读取一个映射(每个事务 1R/1W)。
经过50万个分区的几个小时的读写,表统计如下:
Percentile SSTables Write Latency Read Latency Partition Size Cell Count
(micros) (micros) (bytes)
50% 10.00 35.43 2346.80 1597 60
75% 10.00 51.01 4055.27 2299 72
95% 12.00 105.78 17436.92 6866 215
98% 12.00 182.79 36157.19 6866 215
99% 12.00 454.83 52066.35 8239 215
Min 5.00 3.31 379.02 104 3
Max 14.00 186563.16 322381.14 9887 310
到目前为止,一切都很好。下一步是创建 3000 万个新分区。 经过大约 15 小时的写入(在随机分区中),我注意到 TPS 大幅下降(大约 2k):
Percentile SSTables Write Latency Read Latency Partition Size Cell Count
(micros) (micros) (bytes)
50% 2.00 51.01 20924.30 1916 50
75% 3.00 73.46 43388.63 1916 60
95% 4.00 126.93 89970.66 1916 60
98% 4.00 219.34 107964.79 2299 72
99% 4.00 379.02 129557.75 6866 179
Min 0.00 3.97 51.01 104 3
Max 8.00 186563.16 322381.14 9887 310
再次跨 500k 分区执行第一次测试,读取延迟仍然很高:
Percentile SSTables Write Latency Read Latency Partition Size Cell Count
(micros) (micros) (bytes)
50% 5.00 51.01 30130.99 1916 60
75% 6.00 73.46 62479.63 1916 60
95% 7.00 152.32 129557.75 1916 60
98% 8.00 263.21 155469.30 3311 103
99% 8.00 545.79 186563.16 6866 179
Min 3.00 3.97 454.83 104 3
Max 10.00 107964.79 557074.61 9887 310
当工作负载涉及将计数器列写入(到另一个表中)时,读取延迟会增加:
Percentile SSTables Write Latency Read Latency Partition Size Cell Count
(micros) (micros) (bytes)
50% 10.00 42.51 62479.63 1916 50
75% 10.00 61.21 107964.79 1916 60
95% 12.00 105.78 186563.16 1916 60
98% 12.00 182.79 223875.79 3311 103
99% 12.00 379.02 268650.95 6866 179
Min 6.00 4.77 545.79 104 3
Max 14.00 129557.75 557074.61 9887 310
可能的原因是什么? map 列类型可能是根本原因吗?有什么建议(配置或架构更改)?
我正在使用准备好的语句:
- 按分区 ID 获取行
SELECT id,attr,uids FROM user_profile WHERE id=:id
- 更新地图条目
UPDATE user_profile SET attr=attr+:attr, attr=attr-:attrstoremove, uids=uids+:newuserids, md=md+:metadata, md=md-:attrstoremove, up=:up WHERE id=:id
- 增加计数器
UPDATE user_profile_counter SET cnt=cnt+:cnt WHERE cnt_id=:cnt_id AND id=:id;
这是我的架构:
CREATE TABLE IF NOT EXISTS PROFILING.USER_PROFILE
(
-- PARTITION KEY
ID TEXT, -- PROFILE ID
-- DATA
ATTR MAP<BLOB, BLOB>, --USER ATTRIBUTES
MD MAP<BLOB, BLOB>, --METADATA PER ATTRIBUTE
UIDS SET<TEXT>,
UP TIMESTAMP, --LAST_UPDATE
PRIMARY KEY (ID)
) WITH caching = {
'keys' : 'ALL',
'rows_per_partition' : '1'
};
CREATE TABLE IF NOT EXISTS PROFILES.USER_PROFILE_COUNTER
(
-- PARTITION KEY
ID TEXT, -- PROFILE ID
-- CLUSTERING KEY
CNT_ID BLOB, -- COUNTER ID
-- DATA
CNT COUNTER, -- COUNTER VALUE
PRIMARY KEY (ID, CNT_ID)
) WITH caching = {
'keys' : 'ALL',
'rows_per_partition' : '10' };
数据已加密。这是一个行示例(由三个映射条目组成):
YkceUdD6qEvOLw3Wgd8zWA |{0x95f56f594522: 0xacb7f42c7f0ac8187f17a8f2c04e5065、0xa365a3dc007d: 0x24252727706b5065f9e1f65efec7ced8、0xf0d55b110f87: 0x5a5ef3b0a041af8c7acf4040333afc96} | {0x95f56f594522: 0x000d31363333333334363636323639,0xa365a3dc007d: 0x000d31363333333431323938363735,0xf0d55b110f87: 0x000d31363333333431323938363735} | {'46TyNYCKTplibRyAfFsNRPQbvfQINNIIY4WmItuPayfvjDjEp49bnXSXLmD9hAm9'} | 2021-10-04 09:54:58.675000+0000
集群信息(每个节点)
- 总内存18GB(堆5GB)
- 6 个 CPU 内核
版本
- 卡桑德拉 3.11
- DataStax Java 驱动程序 4.11.3
- JDK 16
编辑
经过几次测试,观察到大量磁盘 IOPS,其中大部分是读取操作。更具体地说,观察到 20k IOPS 和 1500MBps 带宽。我尝试通过使用LeveledCompactionStrategy 并将chunk_length_in_kb 参数降低到4KB 来减少所触及的SSTable 的数量,但差别不大。
请注意,使用的是 SAN 存储。我知道这是一种反模式,但不幸的是,我们别无选择。有什么想法吗?
【问题讨论】:
-
你能显示查询正在运行吗?
-
@Aaron 我已经编辑了我的问题。
-
您查看过磁盘 I/O 指标(尤其是 IOPS)吗?分区大小不错,查询也不错,可能是磁盘慢了?
-
另外,在此期间每秒发生了多少次读写?
-
最初,当数据库为空时,我们有 4.5k TPS。随着数据库填满,TPS 下降到 1k。每个事务执行一次读取和一次写入。每个事务执行一次读取,TPS 仍然很低。我将检查磁盘指标。谢谢!
标签: cassandra nosql performance-testing database-performance cassandra-3.0