【问题标题】:Cassandra read performance degrade as we increase data on nodes随着我们增加节点上的数据,Cassandra 读取性能下降
【发布时间】:2017-10-07 16:30:55
【问题描述】:
  • 使用的数据库:Datastax cassandra community 3.0.9
  • 集群:3 个(8 核 15GB AWS c4.2xlarge),300GB io1,3000iops。
  • 写入一致性:Quorum,读取一致性:ONE Replication 系数:3

问题: 我在我们的服务器上加载了 50,000 个用户,每个用户最初有 1000 条记录,一段时间后,每个用户又添加了 20 条记录。我想获取稍后添加的 20 条附加记录(查询:select * from table where userID='xyz' and timestamp > 123)这里 user_id 和时间戳是主键的一部分。当我只有 50,000 个用户时,它运行良好。但是,一旦我添加了另外 20GB 的虚拟数据,相同查询的性能(即为 50,000 个用户获取 20 条额外记录)的性能显着下降。读取性能随着数据的增加而下降。据我所知,这不应该发生,因为键被缓存并且其他数据不重要。

这可能是什么原因? CPU 和 RAM 利用率可以忽略不计,我无法找出导致查询时间增加的原因。 我尝试将压缩策略更改为“LeveledCompaction”,但这也不起作用。

编辑 1

编辑 2 堆大小为 8GB。添加 20GB 数据的方式类似于添加初始 4GB 数据(50k 用户 ID)的方式,这样做是为了模拟真实世界的场景。 20GB数据的“userID”和“timestamp”不同,是随机生成的。场景是我有 50k 个用户 ID 和 1020 行,其中首先添加了 1000 行,然后在某个时间戳之后添加了另外的 20 行,我正在获取这 20 条消息。如果只存在 50k 个用户 ID,它可以正常工作,但是一旦我有更多用户 ID(额外 20GB)并且我尝试获取相同的 20 条消息(对于初始 5 万个用户 ID),性能就会下降。

编辑 3 cassandra.yaml

【问题讨论】:

  • 在添加额外的 20 GB 虚拟数据之前,原始数据的大小是多少?
  • @Edmon:在添加 20GB 虚拟数据之前存在 4.2GB。
  • 查看这篇文章。它可能会帮助你。我认为您的单个节点超载:shareitexploreit.blogspot.com/2012/09/…
  • @Edmon:我的分区键将数据分布在集群中的所有 3 个节点上。所以排除了这种可能性。此外,当我读取 4.2GB 数据时读取吞吐量很好,但当我添加 20GB 数据时读取吞吐量下降。我的问题是,20GB 的虚拟数据与读取性能有什么关系?我有用户 ID 和时间戳作为主键,并且这些键被缓存。
  • @AtmeshMishra RF=3 表示所有 3 个节点都获得相同的数据,您的数据被复制 3 次。如果你想在你的集群中传播你的数据,你会使用 RF=1。缓存密钥这一事实意味着您只需保存一个 IOPS(并且您有 SSD,所以顺便说一句,这根本不是问题)。您的数据不会被缓存,而是必须被读取。

标签: cassandra


【解决方案1】:

读取性能随着数据的增加而下降。

只有在同一分区中添加大量记录时才会发生这种情况。

据我所知,您的表格可能如下所示:

CREATE TABLE tbl (
    userID text,
    timestamp timestamp,
    ....
    PRIMARY KEY (userID, timestamp)
);

当单个分区中的数据量是“绑定”的(例如,单个分区中最多有 10k 行)时,此模型已经足够了。原因是coordinator 在处理“未绑定”查询时会承受很大的压力(这就是为什么非常大的分区是一个很大的禁忌)。

这个“规则”很容易被忽视,最终结果是整体速度变慢,这可以简单地解释为:C* 需要读取越来越多的数据(并且所有数据都只能从一个节点读取)以满足您的查询,使协调器保持忙碌并减慢整个集群的速度。数据增长通常意味着查询响应缓慢,并且在某个阈值之后会出现臭名昭著的读取超时错误。

话虽如此,看看你的磁盘使用是“正常”还是有问题会很有趣。试试dstat -lrvn 来监控您的服务器。

最后一个提示:根据您使用 SELECT * 查询的字段数量以及检索到的数据量,由 SSD 提供服务可能不是什么大问题,因为您不会利用 SSD 的 IOPS。在这种情况下,选择普通硬盘可以降低解决方案的成本,并且您不会受到任何惩罚。

【讨论】:

  • 你的桌子是对的。对于每个 userId,不超过 1200 条记录,即在这种情况下,每个分区的数据是有界的。我每次查询获取的字段不超过 8 个。我附上了有问题的 dstat 输出的屏幕截图。
  • @AtmeshMishra 屏幕截图显示机器以大约 110MB/s 的速度不断读取数据。您是在查询期间截屏还是机器空闲(从您的角度来看)?机器可能耗尽了 IOPS 或吞吐量。
  • 我在作为负载测试的一部分运行查询时截取了屏幕截图。如上所述,我有 3000 iops 的磁盘,而 aws-cloudwatch 显示最大 1100-1400 读取操作/秒。顺便说一句,我有同样的想法,所以我将 iops 编辑为 15000(300GB 磁盘的最大值)结果仍然相同。这里的问题是,为什么额外的数据会影响读取性能?
  • @AtmeshMishra 你能告诉我们你用来插入这个虚拟数据的查询吗?还向我们展示一些虚拟数据值。顺便说一句,在这种情况下,如果不是 IOPS,那就是吞吐量恕我直言。
  • 我使用“插入到 tbl (userID, text, timestamp) values(?,?)错了,userID 是 PK 的一部分,而不是文本。
猜你喜欢
  • 2020-02-19
  • 2018-09-22
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2021-05-06
  • 2012-01-22
  • 2020-09-02
  • 2016-07-28
相关资源
最近更新 更多