我遇到了一个问题,Cassandra Nodes定期与`java.lang.OutOfMemoryError:Java堆空间'异常。
我的设置包含5个VM上运行的5个Cassandra 2.0.11节点。 每个VM都有8GB RAM,100GB磁盘容量和相当快的CPU。
我已经尝试过增加堆大小。目前它被设置为默认值(8GB的1/4 = 2GB)。
内存填充速度非常快,接缝成为限制因素。我怎样才能强迫cassandra使用更少的内存?我可以容忍较慢的写操作以换取稳定性。
目前我只写没有更新,读取或删除。 我写的时间序列每个文件大约有100000个值。并发级别为QUORUM,复制因子为3.我使用来自datastax的java驱动程序。
表格是这样创建的:
"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
知道我做错了吗?
提前感谢您的帮助。
答案 0 :(得分:1)
插入应该只是刷新到磁盘,不会导致OOM异常。
Cassandra确实需要大量内存,2GB似乎非常低。它的性能不仅来自每个节点的大量内存,而且还有很多节点,创造了非常大的缓存。
我建议你每个节点有8GB的堆,而你的VMS应该升到大约32GB的内存。确保安装了JNA,以便Cassandra可以利用额外的堆内存。
答案 1 :(得分:0)
我刚刚在堆空间问题上与Cassandra(2.0)进行了摔跤。我一直在运行3个VM节点,每个节点8GB,复制1.不用说,不是最佳。
以下是我使用它并找到的内容: 我存储了一个非常长的多部分键((uuid),文本,文本,文本,int)来引用一个值(文本)和一些其他跟踪信息,这些实际上是不必要的,但很高兴,采取两个更多的形式。我也有(过去时)一个索引,其中一个特别好的有字段。 Cassandra经常抱怨说,处理我的批量插页需要花费太多时间,每分钟大约有4000个。如果/当我尝试进行nodetool修复时,它通常会因堆空间错误而崩溃。我做的第一件事就是放弃那个好的,但最终不必要的索引。停止修复崩溃,但修复需要数天才能完成。其次,我将8GB提升到24GB。听起来这不是你的奢侈品,但这就是它所花的。这将修复时间从几天改为几小时,就像其中的八个一样。第三,我从2.0升级到2.2。一旦我在所有三个节点上运行修复,花了24小时,我一次升级每个节点,然后在升级后在每个节点上再次运行修复。现在修复,不仅不会崩溃,而是在大约两个小时内在整个群集中完成。更快,更稳定。我已经添加了第四个节点和第二个副本。仍然没有问题。我认为最大的问题是二级指数。我还发现安装jemalloc是一个巨大的速度提升。