Cassandra 2.1 集群显示持续高 CPU 使用率和缓慢响应
Cassandra 2.1 Cluster Showing Consistently High CPU Usage and Slow Responses
5 月 3 日我们部署了。我们的 3 节点 cassandra 集群变得极其缓慢,许多 Web 请求都超时了。到 EOD 5 月 3 日,我们向集群启动了另一台 m1.large 机器,解决了超时问题。话虽如此,集群仍然非常慢; 5 月 4 日,我们启动了五个 i3.xLarge 节点。这极大地帮助了我们的应用程序响应时间,5 月 5 日我们从集群中删除了旧的 m1.large 框。截至 5 月 5 日 EOD,一切都快速且响应迅速。今天早上,应用程序又开始超时了。
我们注意到一些奇怪的 CPU 使用率行为 - CPU 使用率在 100% 和 200% 之间波动,无论负载如何(它们是四核机器)。我们的周末非常轻,完全没有负载,周一负载相对较重,但我们看到 CPU 使用率绝对没有变化。
正如您在下面的 2 周图表中所见,我们的数据库 CPU 使用量曾经与应用程序使用量绑定。您可以看到 3 日的大峰值,4 日新机器的引入,以及从 6 日开始稳定的高 CPU 使用率。
我们花了很多时间试图确定 CPU 用法的原因,并且能够确定(并随后排除)三个主要原因:
- High khugepaged CPU usage.
- 垃圾收集调整不当
- 压实调整不当
我们已经排除了所有这三种情况。
- 我们的服务器有 0.0% khugepaged CPU 使用率。
- 我们的 GC 吞吐量约为 96%。我们还调整了堆和新的堆大小,并切换到 G1 GC。我们的日志曾经显示与长时间 GC 暂停相关的警告,但现在不再显示了。此外,GC 线程仅占少量 CPU 使用量。
nodetool compactionstats
returns 0 个待处理任务。我们已经切换到 LeveledCompactionStrategy 并将 GC_GRACE_SECONDS 设置为 1 天。我们的日志曾经显示与大量墓碑相关的警告,但现在不再显示了。 nodetool compactionhistory
显示每小时大约一次压缩,根据日志,它们发生得非常快(< 1 秒)。
Cassandra 的 SharedPoolWorker
线程似乎有很高的使用率。这是一个节点的 CPU 使用线程类型(它们看起来都非常相似):
84.6 SharedPoolWorker
22.1 Thrift
13.5 CCompilerThread
11.9 MessagingServiceOutgoing
9.4 MessagingServiceIncoming
3.6 GangworkerParallelGCThreads
1.6 DestroyJavaVM
.3 VMThread
.1 Thread
.1 ScheduledTasks
.1 OptionalTasks
0 ...
检查 SharedPool-Worker 线程的状态表明绝大多数线程处于等待状态,堆栈跟踪如下:
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:85)
at java.lang.Thread.run(Unknown Source)
我认为这是问题所在,但我不确定为什么 CPU 等待时间可能很少(根据 dstat
始终为 0%)。
现在,有趣的是,任何给定节点上的 运行 nodetool tpstats
显示少量 ReadStage 线程处于活动状态,偶尔会有一两个处于待处理状态。有 none 被阻止,所有时间被阻止,或被丢弃。
这是 nodetool cfstats
的输出,这里是 nodetool netstats
:
Mode: NORMAL
Not sending any streams.
Read Repair Statistics:
Attempted: 12229
Mismatch (Blocking): 2
Mismatch (Background): 0
Pool Name Active Pending Completed Dropped
Commands n/a 0 707576 0
Responses n/a 0 859216 n/a
有人知道为什么会发生这种情况吗?我们可以研究任何潜在的东西吗?
这可能与为单次读取扫描的大量墓碑或大量 sstables 有关 - 由于每个请求需要执行大量读取,因此造成持续高 CPU 负载和缓慢响应.
这些症状可以显示,例如,将 STCS 与持续和频繁 更新(更新行,而不是添加新行)数据一起使用。
能否将您的主表的 nodetool tablestats/cfstats 添加到问题中?
问题实际上是我们的 API。它有 GC 问题,导致大量 db read/write 线程被冻结。
5 月 3 日我们部署了。我们的 3 节点 cassandra 集群变得极其缓慢,许多 Web 请求都超时了。到 EOD 5 月 3 日,我们向集群启动了另一台 m1.large 机器,解决了超时问题。话虽如此,集群仍然非常慢; 5 月 4 日,我们启动了五个 i3.xLarge 节点。这极大地帮助了我们的应用程序响应时间,5 月 5 日我们从集群中删除了旧的 m1.large 框。截至 5 月 5 日 EOD,一切都快速且响应迅速。今天早上,应用程序又开始超时了。
我们注意到一些奇怪的 CPU 使用率行为 - CPU 使用率在 100% 和 200% 之间波动,无论负载如何(它们是四核机器)。我们的周末非常轻,完全没有负载,周一负载相对较重,但我们看到 CPU 使用率绝对没有变化。
正如您在下面的 2 周图表中所见,我们的数据库 CPU 使用量曾经与应用程序使用量绑定。您可以看到 3 日的大峰值,4 日新机器的引入,以及从 6 日开始稳定的高 CPU 使用率。
我们花了很多时间试图确定 CPU 用法的原因,并且能够确定(并随后排除)三个主要原因:
- High khugepaged CPU usage.
- 垃圾收集调整不当
- 压实调整不当
我们已经排除了所有这三种情况。
- 我们的服务器有 0.0% khugepaged CPU 使用率。
- 我们的 GC 吞吐量约为 96%。我们还调整了堆和新的堆大小,并切换到 G1 GC。我们的日志曾经显示与长时间 GC 暂停相关的警告,但现在不再显示了。此外,GC 线程仅占少量 CPU 使用量。
nodetool compactionstats
returns 0 个待处理任务。我们已经切换到 LeveledCompactionStrategy 并将 GC_GRACE_SECONDS 设置为 1 天。我们的日志曾经显示与大量墓碑相关的警告,但现在不再显示了。nodetool compactionhistory
显示每小时大约一次压缩,根据日志,它们发生得非常快(< 1 秒)。
Cassandra 的 SharedPoolWorker
线程似乎有很高的使用率。这是一个节点的 CPU 使用线程类型(它们看起来都非常相似):
84.6 SharedPoolWorker
22.1 Thrift
13.5 CCompilerThread
11.9 MessagingServiceOutgoing
9.4 MessagingServiceIncoming
3.6 GangworkerParallelGCThreads
1.6 DestroyJavaVM
.3 VMThread
.1 Thread
.1 ScheduledTasks
.1 OptionalTasks
0 ...
检查 SharedPool-Worker 线程的状态表明绝大多数线程处于等待状态,堆栈跟踪如下:
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:85)
at java.lang.Thread.run(Unknown Source)
我认为这是问题所在,但我不确定为什么 CPU 等待时间可能很少(根据 dstat
始终为 0%)。
现在,有趣的是,任何给定节点上的 运行 nodetool tpstats
显示少量 ReadStage 线程处于活动状态,偶尔会有一两个处于待处理状态。有 none 被阻止,所有时间被阻止,或被丢弃。
这是 nodetool cfstats
的输出,这里是 nodetool netstats
:
Mode: NORMAL
Not sending any streams.
Read Repair Statistics:
Attempted: 12229
Mismatch (Blocking): 2
Mismatch (Background): 0
Pool Name Active Pending Completed Dropped
Commands n/a 0 707576 0
Responses n/a 0 859216 n/a
有人知道为什么会发生这种情况吗?我们可以研究任何潜在的东西吗?
这可能与为单次读取扫描的大量墓碑或大量 sstables 有关 - 由于每个请求需要执行大量读取,因此造成持续高 CPU 负载和缓慢响应.
这些症状可以显示,例如,将 STCS 与持续和频繁 更新(更新行,而不是添加新行)数据一起使用。
能否将您的主表的 nodetool tablestats/cfstats 添加到问题中?
问题实际上是我们的 API。它有 GC 问题,导致大量 db read/write 线程被冻结。