3

首先请原谅我可能是一个非常幼稚的问题。我的任务是为我的项目确定正确的 nosql 数据库。我以高度并发的方式在表(列族)中插入和更新记录。

然后我遇到了这个。

INFO 11:55:20,924 Writing Memtable-scan_request@314832703(496750/1048576 serialized/live bytes, 8204 ops)
 INFO 11:55:21,084 Completed flushing /var/lib/cassandra/data/mykey/scan_request/mykey-scan_request-ic-14-Data.db (115527 bytes) for commitlog position ReplayPosition(segmentId=1372313109304, position=24665321)
 INFO 11:55:21,085 Writing Memtable-scan_request@721424982(1300975/2097152 serialized/live bytes, 21494 ops)
 INFO 11:55:21,191 Completed flushing /var/lib/cassandra/data/mykey/scan_request/mykey-scan_request-ic-15-Data.db (304269 bytes) for commitlog position ReplayPosition(segmentId=1372313109304, position=26554523)
 WARN 11:55:21,268 Heap is 0.829968311377531 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
 WARN 11:55:21,268 Flushing CFS(Keyspace='mykey', ColumnFamily='scan_request') to relieve memory pressure
 INFO 11:55:25,451 Enqueuing flush of Memtable-scan_request@714386902(324895/843149 serialized/live bytes, 5362 ops)
 INFO 11:55:25,452 Writing Memtable-scan_request@714386902(324895/843149 serialized/live bytes, 5362 ops)
 INFO 11:55:25,490 Completed flushing /var/lib/cassandra/data/mykey/scan_request/mykey-scan_request-ic-16-Data.db (76213 bytes) for commitlog position ReplayPosition(segmentId=1372313109304, position=27025950)
 WARN 11:55:30,109 Heap is 0.9017950505664833 full.  You may need to reduce memtable and/or cache sizes.  Cassandra will now flush up to the two largest memtables to free up memory.  Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically



java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid8849.hprof ...
Heap dump file created [1359702396 bytes in 105.277 secs]
 WARN 12:25:26,656 Flushing CFS(Keyspace='mykey', ColumnFamily='scan_request') to relieve memory pressure
 INFO 12:25:26,657 Enqueuing flush of Memtable-scan_request@728952244(419985/1048576 serialized/live bytes, 6934 ops)

值得注意的是,在我得到这个之前,我能够插入和更新大约 600 万条记录。我在单个节点上使用 cassandra。尽管日志中有提示,但我无法决定要更改什么配置。我确实检查了 bin/cassandra shell 脚本,我发现他们在提出 -Xms 和 -Xmx 值之前已经做了很多操作。

友善的建议。

4

2 回答 2

9

首先,你可以运行

ps -ef|grep cassandra

查看 Cassandra 中 -Xmx 的设置。-Xms 和 -Xmx 的默认值基于系统内存量。

检查此以获取详细信息: http ://www.datastax.com/documentation/cassandra/1.2/index.html?pagename=docs&version=1.2&file=index#cassandra/operations/ops_tune_jvm_c.html

您可以尝试增加 MAX_HEAP_SIZE(在 conf/cassandra-env.sh 中)以查看问题是否会消失。

例如,您可以替换

MAX_HEAP_SIZE="${max_heap_size_in_mb}M"

MAX_HEAP_SIZE="2048M"
于 2013-06-27T14:13:11.160 回答
2

我假设为 Cassandra 调整垃圾收集器可能会解决 OOM 错误。当我们使用默认设置时,Cassandra 对垃圾收集器使用并发标记和清除 (CMS) JVM 实现。CMS 垃圾收集器通常只会在堆几乎完全填充后才会启动。但是 CMS 进程本身需要一些时间才能完成,问题是 JVM 在 CMS 进程完成之前就耗尽了空间。我们可以在 bin/cassandra.in 中使用以下选项设置触发 CMS 的已用老年代空间的百分比JAVA_OPTS 变量下的 .sh 文件

-XX:CMSInitiatingOccupancyFraction={percentage} - 当 CMS 被触发时,它控制老年代的百分比,我们可以设置这个较低的值以保持直到 CMS 进程完成。

-XX:+UseCMSInitiatingOccupancyOnly - 此参数确保百分比保持固定

此外,通过以下选项,我们可以实现增量 CMS

-XX:+UseConcMarkSweepGC \ -XX:+CMSIncrementalMode \ -XX:+CMSIncrementalPacing \ -XX:CMSIncrementalDutyCycleMin=0 \ -XX:+CMSIncrementalDutyCycle=10

考虑 CPU 的核心数,我们可以增加并行 CMS 线程

-XX:ParallelCMSThreads={numberOfTreads}

此外,我们可以调整年轻代的垃圾收集,以使流程优化。这里我们要控制重用对象的数量

  1. 增加年轻代的规模
  2. 延迟老年代的年轻代对象提升

为此,我们可以设置以下参数

  1. -XX:NewSize={size} - 确定年轻代的大小
  2. -XX:NewMaxSize={size} - 这是年轻代的最大尺寸
  3. -Xmn{size} - 修正最大尺寸
  4. -XX:NewRatio={n} - 设置年轻代与老年代的比例

在对象从年轻代迁移到老年代之前,它们被置于称为“年轻幸存者”的阶段。所以我们可以使用以下参数控制对象到老年代的迁移

  1. -XX:SurvivorRatio={n} - “年轻伊甸园”与“年轻幸存者”的比例
  2. -XX:MaxTenuringThreshold={age} 迁移到老年代的对象个数
于 2014-01-05T20:47:07.987 回答