【问题标题】:Cassandra experiencing OutOfMemory issues (Java Heap Space) on long runsCassandra 长期运行时遇到 OutOfMemory 问题(Java 堆空间)
【发布时间】:2013-03-30 10:30:08
【问题描述】:

我们正在通过尝试一些长期运行的测试用例(压力测试)来对 Cassandra 进行一些试验,并且我们在任何给定时间都在集群的一个节点上遇到了一些内存问题(它可能是集群上的任何机器!)

我们正在一台装有 Windows Server 2008 和 8 GB RAM 的机器上运行带有 Cassandra 1.1.6 的 DataStax Community。此外,我们将堆大小配置为 2GB,而不是默认值 1GB。

日志中的一个 sn-p:

java.lang.OutOfMemoryError: Java 堆空间

将堆转储到 java_pid2440.hprof ...

已创建堆转储文件 [11.713 秒内 1117876234 个字节]

ERROR 22:16:56,756 线程异常 [CompactionExecutor:399,1,main]

java.lang.OutOfMemoryError: Java 堆空间

在 org.apache.cassandra.io.util.FastByteArrayOutputStream.expand(FastByteArrayOutputStream.java:104)

在 org.apache.cassandra.io.util.FastByteArrayOutputStream.write(FastByteArrayOutputStream.java:220)

在 java.io.DataOutputStream.write(Unknown Source)

调查和解决此问题的任何指示/帮助。??

【问题讨论】:

  • 您能否详细说明您要插入的内容以及插入的位置(键、列名等)?你用什么设置来声明你的集群和键空间?任何细节都可能是相关的。
  • 我正在使用以下命令创建键空间:CREATE KEYSPACE T_V_0 with placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' and strategy_options = {replication_factor:1};
  • 这些列基本上有一个 DateType、UUIDType、3 个 IntegerType、2 个 LongType 和 1 个 DoubleType,其中 WITH 比较器 = UTF8Type AND key_validation_class= UTF8Type AND default_validation_class= UTF8Type
  • 您是否总是在同一个地址(键+列名)插入?由于 UTF8Type 与其他验证不兼容,您不会在某些写入时遇到写入错误(您可能应该保留为字节......这是默认设置,允许您在一行中有多种类型的列)。
  • 不,我不在同一个地址插入。列名是 UTF8Type,我使用的唯一键是 UUID 和 TimeStamp 的组合,因此永远不会重叠。我能够成功插入数据。只有当我连续插入超过 10 亿条记录时,集群中的一个节点才会出现 OutOfMemory 异常。这可以是任何节点,但我相信它主要是接受来自客户端的最大连接的节点。

标签: cassandra datastax-enterprise


【解决方案1】:

长时间运行负载测试是正确的做法,但在生产用例中,您不会像这样编写数据。

当需要压缩它们时,您的行可能会变得太大而无法放入 RAM。压缩需要整行才能放入 RAM。

每行也有 20 亿列的硬性限制,但实际上您不应该让行增长到那么宽。通过将日期或服务器名称或数据集中常见的其他值添加到行键来存储它们。

对于“经常写入但几乎从不读取”的工作负载,您可以拥有非常宽的行,但不应接近 20 亿列标记。通过分桶保持数百万。

对于频繁读取整行的写入/读取混合工作负载,即使数百列也可能太多。

如果您正确对待 Cassandra,您将轻松处理每个节点每秒数千次的读写操作。我看到我的主集群上每个节点同时进行大约 2.5k 读取和写入。

【讨论】:

  • 我将 JAVA Heap 大小增加到 4GB 左右,并且写入吞吐量有所提高。另外,正如您正确提到的,我的行很宽(每天的时间戳数据)。我可能会考虑将粒度更改为每小时而不是 24 小时。否则行可能会变得非常大。
  • 你认为反向比较器在这种情况下会有所帮助吗?
  • 不要增加堆大小,除非你确定你明白你为什么这样做。增加堆大小首先会增加垃圾收集的暂停时间,这通常会使事情变得更糟,其次会从内核文件缓存中占用内存,至少在 Linux 上证明这比 Cassandra 缓存快得多,最后对于您的场景只会延迟 OOM ,而不是阻止它。除非您完全理解为什么要这样做,否则更改 cassandra-env 文件中的任何内容都是一个坏主意。
  • 另外,像您一样分桶是处理此类数据的正确方法,但是反向比较器不会对您的 OOM 问题产生影响,但可能对您的访问模式更好?只有你能告诉我。
  • 我在阅读有关 GC @oracle.com/technetwork/java/javase/gc-tuning-6-140523.html 的 Oracle 文档时偶然发现了 ParallelGC 的使用,我确信 DataStax Cassandra 已配置为:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多