故障排除和修复 Cassandra OOM 问题
Troubleshooting and fixing Cassandra OOM issue
尽管有多个关于 OOM 问题的线程想要澄清某些事情。我们是 运行 K8 中的 36 节点 Cassandra 集群 3.11.6 版本,为容器分配了 32gigs。
容器正在 OOM 终止(注意:- 不是 java 堆 OOM 错误而是 linux cgroup OOM 杀手)因为它达到了其 cgroup 的 32 gig 内存限制。
统计和配置
map[limits:map[ephemeral-storage:2Gi memory:32Gi] requests:map[cpu:7 ephemeral-storage:2Gi memory:32Gi]]
Cgroup内存限制
34359738368 -> 32 Gigs
JVM spaces 由 Cassandra 自动计算 -Xms19660M -Xmx19660M -Xmn4096M
Grafana Screenshot
Cassandra Yaml --> https://pastebin.com/ZZLTc1cM
JVM 选项 --> https://pastebin.com/tjzZRZvU
已消耗 98% 内存的节点上的 Nodetool 信息输出
nodetool info
ID : 59c53bdb-4f61-42f5-a42c-936ea232e12d
Gossip active : true
Thrift active : true
Native Transport active: true
Load : 179.71 GiB
Generation No : 1643635507
Uptime (seconds) : 9134829
Heap Memory (MB) : 5984.30 / 19250.44
Off Heap Memory (MB) : 1653.33
Data Center : datacenter1
Rack : rack1
Exceptions : 5
Key Cache : entries 138180, size 99.99 MiB, capacity 100 MiB, 9666222 hits, 10281941 requests, 0.940 recent hit rate, 14400 save period in seconds
Row Cache : entries 10561, size 101.76 MiB, capacity 1000 MiB, 12752 hits, 88528 requests, 0.144 recent hit rate, 900 save period in seconds
Counter Cache : entries 714, size 80.95 KiB, capacity 50 MiB, 21662 hits, 21688 requests, 0.999 recent hit rate, 7200 save period in seconds
Chunk Cache : entries 15498, size 968.62 MiB, capacity 1.97 GiB, 283904392 misses, 34456091078 requests, 0.992 recent hit rate, 467.960 microseconds miss latency
Percent Repaired : 8.28107989669628E-8%
Token : (invoke with -T/--tokens to see all 256 tokens)
做了什么
- 我们已经确保 cassandra 进程没有内存泄漏,因为我们有自定义触发代码。 Gc 日志 analytics 显示我们占用了大约 14 GB 的 jvm space.
问题
尽管我们知道 cassandra 确实占用堆 spaces(Bloom 过滤器、Memtables 等)
- grafana 截图显示节点占用了 32 个 gig 的 98%。 JVM heap = 19.5 gigs + offheap space in nodetool info output = 1653.33 MB (1Gigs) (JVM heap + off heap = 22 gigs)。剩余内存(10 gigs)在哪里?如何准确计算占用剩余内存的内容。 (由于抱怨原因,Nodetool tablestats 和 nodetool cfstats 输出未共享)?
我们的生产集群需要大量批准,因此使用 jconsole 远程部署它们很困难。考虑此内存使用情况的任何其他方式。
- 一旦我们计算了内存使用情况,下一步是什么来解决这个问题并避免 OOM 终止?
SSTables 很有可能被映射到内存(使用 mmap()
缓存)。如果是这种情况,它不会立即生效,并且内存使用量会随着时间的推移而增长,具体取决于何时读取 SSTables,然后将其缓存。我在 https://community.datastax.com/questions/6947/.
中写过这个问题
称为“磁盘访问模式”的 not-so-well-known 配置 属性 存在问题。如果未设置 cassandra.yaml
,它默认为 mmap
,这意味着所有 SSTables 都会 mmap
ed 到内存。如果是这样,您将在启动时在 system.log
中看到一个条目,如下所示:
INFO [main] 2019-05-02 12:33:21,572 DatabaseDescriptor.java:350 - \
DiskAccessMode 'auto' determined to be mmap, indexAccessMode is mmap
解决方案是通过设置将磁盘访问模式配置为仅缓存 SSTable 索引文件(而不是 *-Data.db
组件):
disk_access_mode: mmap_index_only
有关详细信息,请参阅我上面发布的 link。干杯!
尽管有多个关于 OOM 问题的线程想要澄清某些事情。我们是 运行 K8 中的 36 节点 Cassandra 集群 3.11.6 版本,为容器分配了 32gigs。
容器正在 OOM 终止(注意:- 不是 java 堆 OOM 错误而是 linux cgroup OOM 杀手)因为它达到了其 cgroup 的 32 gig 内存限制。
统计和配置
map[limits:map[ephemeral-storage:2Gi memory:32Gi] requests:map[cpu:7 ephemeral-storage:2Gi memory:32Gi]]
Cgroup内存限制
34359738368 -> 32 Gigs
JVM spaces 由 Cassandra 自动计算 -Xms19660M -Xmx19660M -Xmn4096M
Grafana Screenshot
Cassandra Yaml --> https://pastebin.com/ZZLTc1cM
JVM 选项 --> https://pastebin.com/tjzZRZvU
已消耗 98% 内存的节点上的 Nodetool 信息输出
nodetool info
ID : 59c53bdb-4f61-42f5-a42c-936ea232e12d
Gossip active : true
Thrift active : true
Native Transport active: true
Load : 179.71 GiB
Generation No : 1643635507
Uptime (seconds) : 9134829
Heap Memory (MB) : 5984.30 / 19250.44
Off Heap Memory (MB) : 1653.33
Data Center : datacenter1
Rack : rack1
Exceptions : 5
Key Cache : entries 138180, size 99.99 MiB, capacity 100 MiB, 9666222 hits, 10281941 requests, 0.940 recent hit rate, 14400 save period in seconds
Row Cache : entries 10561, size 101.76 MiB, capacity 1000 MiB, 12752 hits, 88528 requests, 0.144 recent hit rate, 900 save period in seconds
Counter Cache : entries 714, size 80.95 KiB, capacity 50 MiB, 21662 hits, 21688 requests, 0.999 recent hit rate, 7200 save period in seconds
Chunk Cache : entries 15498, size 968.62 MiB, capacity 1.97 GiB, 283904392 misses, 34456091078 requests, 0.992 recent hit rate, 467.960 microseconds miss latency
Percent Repaired : 8.28107989669628E-8%
Token : (invoke with -T/--tokens to see all 256 tokens)
做了什么
- 我们已经确保 cassandra 进程没有内存泄漏,因为我们有自定义触发代码。 Gc 日志 analytics 显示我们占用了大约 14 GB 的 jvm space.
问题
尽管我们知道 cassandra 确实占用堆 spaces(Bloom 过滤器、Memtables 等)
- grafana 截图显示节点占用了 32 个 gig 的 98%。 JVM heap = 19.5 gigs + offheap space in nodetool info output = 1653.33 MB (1Gigs) (JVM heap + off heap = 22 gigs)。剩余内存(10 gigs)在哪里?如何准确计算占用剩余内存的内容。 (由于抱怨原因,Nodetool tablestats 和 nodetool cfstats 输出未共享)?
我们的生产集群需要大量批准,因此使用 jconsole 远程部署它们很困难。考虑此内存使用情况的任何其他方式。
- 一旦我们计算了内存使用情况,下一步是什么来解决这个问题并避免 OOM 终止?
SSTables 很有可能被映射到内存(使用 mmap()
缓存)。如果是这种情况,它不会立即生效,并且内存使用量会随着时间的推移而增长,具体取决于何时读取 SSTables,然后将其缓存。我在 https://community.datastax.com/questions/6947/.
称为“磁盘访问模式”的 not-so-well-known 配置 属性 存在问题。如果未设置 cassandra.yaml
,它默认为 mmap
,这意味着所有 SSTables 都会 mmap
ed 到内存。如果是这样,您将在启动时在 system.log
中看到一个条目,如下所示:
INFO [main] 2019-05-02 12:33:21,572 DatabaseDescriptor.java:350 - \
DiskAccessMode 'auto' determined to be mmap, indexAccessMode is mmap
解决方案是通过设置将磁盘访问模式配置为仅缓存 SSTable 索引文件(而不是 *-Data.db
组件):
disk_access_mode: mmap_index_only
有关详细信息,请参阅我上面发布的 link。干杯!