【问题标题】:Cassandra Nodes dying frequently with Heap Space ErrorCassandra 节点经常因堆空间错误而死机
【发布时间】:2015-06-29 22:19:03
【问题描述】:

我遇到了 Cassandra 节点因“java.lang.OutOfMemoryError: Java heap space”异常而定期死亡的问题。

我的设置包含在 5 个虚拟机上运行的 5 个 Cassandra 2.0.11 节点。 每个 VM 都有 8GB RAM、100GB 磁盘容量和相当快的 CPU。

我已经尝试过增加堆大小。目前它设置为默认值(8GB 的​​ 1/4=2GB)。

内存填充得非常快,接缝成为限制因素。如何强制 cassandra 使用更少的内存?我可以容忍较慢的写入操作以换取稳定性。

目前我只写没有更新、读取或删除。 我编写每个文件约 100000 个值的时间序列。并发级别为 QUORUM,复制因子为 3。我使用 datastax 中的 java-driver。

表是这样创建的:

"CREATE TABLE IF NOT EXISTS %s.%s(\n" +
        "ts_type text,\n" +
        "ts_name text,\n" +
        "year int,\n" +
        "time timestamp,\n" +
        "value double,\n" +
        "PRIMARY KEY((ts_type, ts_name), year, time));"

数据是这样写的:

for (final Double value : data) {
    final Insert insertStatement = (Insert) QueryBuilder.insertInto(keyspace, tableName)
            .value("ts_type", tsType)
            .value("ts_name", tsName)
            .value("time", timestampAsDate)
            .value("year", timestamp.getYear())
            .value("value", value)
            .setConsistencyLevel(consistencyLevel);
    batch.add(insertStatement);
    zeitpunkt = zeitpunkt.plus(period);
    if (index++ % 200 == 0) {
        sets.add(client.executeAsync(batch));
        batch = (Batch) QueryBuilder.unloggedBatch().setConsistencyLevel(consistencyLevel);
    }
}

这是一个垂死节点的堆栈跟踪: http://pastebin.com/tTNRgJMP

如您所见,GC 在这里花了很长时间。

这是一个死节点的堆转储: http://i.imgur.com/rOJ3MIl.jpg

知道我做错了什么吗?

提前感谢您的帮助。

【问题讨论】:

  • 您是否控制了一次正在处理的请求数量的速率?如果您提交请求的速度超过了完成的速度,最终您将在某个时候压倒您的集群。知道集群的容量总是好的,你可能会超过它。

标签: java cassandra


【解决方案1】:

插入应该只是被刷新到磁盘,而不是导致 OOM 异常。

Cassandra 确实需要大量内存,2GB 似乎非常低。它的性能不仅来自每个节点的大量内存,还来自大量节点,创造了一个非常大的缓存。

我建议您每个节点有一个 8GB 的​​堆,并且您的 VMS 应该增加到 ~32GB 的内存。确保您已安装 JNA,以便 Cassandra 可以利用额外的堆外内存。

【讨论】:

  • 感谢您的回复。可悲的是,目前无法选择添加更多内存。运行虚拟机的机器本身只有大约 16GB。您认为在给定的设置下可以在负载下运行稳定的 cassandra 吗?
  • 您可以在 16GB VMS 上运行。不确定你在这些盒子上还有什么,但你的虚拟机应该是专用的。因此,如果您有 16GB,请将 8GB 给 Cassandra,并确保您正确安装了 JNA。额外的 8GB 将通过 JNA 提供给 Cassandra。但是不要让你的堆 > 8GB,超过 8GB 的​​ javas 堆管理不是很好。
  • 正如我所说,目前无法添加内存。虚拟机在需要保持可用的同事的工作站上运行。我知道这种设置远非完美,但它仅用于在我们投资更好的基础设施之前对 cassandra 进行试验。 datastax 的 Cassandra 文档指出,最低系统要求是 8GB 内存。所以我希望应该可以在这个硬件上运行一个稳定的系统。
  • 在这种设置中确实无法知道有多少 CPU 或内存可用。为此,您最好在 AWS 上托管。他们有一个“免费套餐”检查一下。或者,如果性能对您来说不是问题,请延迟加载脚本。
【解决方案2】:

我刚刚在堆空间问题上与 Cassandra (2.0) 进行了角力。我一直在运行 3 个 VM 节点,每个节点 8GB RAM,复制 1。不用说,不是最佳的。

这是我使用它并发现的: 我正在存储一个很长的多部分键((uuid),文本,文本,文本,int)来引用一个值(文本)和一些其他的跟踪信息,这确实不是必需的,但很高兴拥有,采取另外两个整数的形式。我还(过去时)对其中一个特别好的字段进行了索引。 Cassandra 经常抱怨说,处理我的批量插入需要花费太多时间,每分钟一次处理大约 4000 个。如果/当我尝试进行 nodetool 修复时,它通常会因堆空间错误而崩溃。我做的第一件事就是放弃那个不错但最终没有必要的索引。停止修复崩溃,但修复需要几天才能完成。其次,我将 8GB 提升到 24GB。听起来这不是你所拥有的奢侈品,但这就是它所需要的。这将修复时间从几天更改为几小时,比如 8 个。第三,我从2.0升级到2.2。一旦我在所有三个节点上运行修复,花了 24 小时,我升级了每个节点,一次一个,然后在所有节点都升级后再次运行修复。现在修复,不仅不崩溃,而且在大约两个小时内完成整个集群。更快,更稳定。我已经添加了第四个节点和第二个副本。仍然没有问题。我认为最大的问题是二级索引。我还发现安装 jemalloc 可以极大地提高速度。

【讨论】:

  • 这是一篇很有味道的帖子,但是很难挖掘出它们的关键点。尝试添加一些格式并总结您的要点:删除不必要的索引,添加内存,升级。现在需要一些时间来弄清楚你的主要观点是什么。
猜你喜欢
  • 2013-11-15
  • 2014-06-24
  • 2019-06-20
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 2016-08-07
  • 1970-01-01
相关资源
最近更新 更多