【问题标题】:Cassandra Map collection type read latencyCassandra Map 集合类型读取延迟
【发布时间】: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


【解决方案1】:

所以至少在周末之前提供一些理论,让我简单谈谈几件事。

JDK 16

所以 Cassandra 3.11 不会在高于 JDK 8 的任何东西上运行,所以我猜这是来自客户端?

总内存 18GB(堆 5GB)

我怀疑节点使用更大的堆会表现得更好。在 18GB 的​​实例上,我会将其提高到 8GB-10GB 左右。 9GB 将为您提供 50% 的快乐内存,所以这可能会很好。

如果堆大小最终超过 8GB,我会选择 G1GC(Cassandra 3 仍然默认使用 CMS GC)。如果您觉得留在 CMS 上更舒服,那么我会将堆的新大小 (Xmn) 设置为最大 (Xmx) 和初始 (Xms) 大小的 40% 到 50% 左右。

复制因子为 3 的三节点 Cassandra 集群

您也很可能需要 3 个以上的节点来处理此负载。 Cassandra 节点可能会被写背压填满,并慢慢死亡。在增加堆大小之后,我会尝试下一个。

您是否查看过磁盘 I/O 指标(尤其是 IOPS)?分区大小不错,查询也不错,可能是磁盘慢了?

不确定您是否在共享基础设施上运行(例如:OpenStack),但我过去遇到的一件事是嘈杂的邻居。您有要与之共享计算或存储的实例,这占用了所有带宽。我会与您的基础架构团队核实,看看这是否有问题。

此外,在处理该共享基础架构环境时,我曾经遇到过一个问题,我们发现存储调度程序已将一个集群的所有驱动器放在同一个物理卷上。因此,我们没有任何真正的硬件可用性,再加上集群的高写入吞吐量基本上让自己窒息。

看看其中的一些,看看你是否发现了什么。

编辑 20211114

是的,在 SAN 上配置 Cassandra 的驱动器将很难收集性能。我可以想到两件事来尝试:

  • 将您的提交日志定向到与数据不同的驱动器(希望是本地的非 SAN)。
  • 将每个节点的数据驱动器配置到不同的 SAN。

【讨论】:

  • 我已经编辑了我的任务。请看一下。
  • @Ikatiforis 已编辑。
猜你喜欢
  • 2018-01-04
  • 2022-07-05
  • 2016-11-18
  • 2015-08-17
  • 1970-01-01
  • 2021-04-12
  • 2017-01-29
  • 2018-04-15
  • 2019-04-21
相关资源
最近更新 更多