From a2231415eb3363d2ea60081ed0386de983d0f5a4 Mon Sep 17 00:00:00 2001 From: Jonathan Ellis Date: Wed, 18 Aug 2010 20:02:21 +0000 Subject: [PATCH] use mlockall via JNA, if present, to prevent Linux from swapping out parts of the JVM (CASSANDRA-1214) git-svn-id: https://svn.apache.org/repos/asf/cassandra/branches/cassandra-0.6@986896 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 2 + bin/cassandra.in.sh | 2 +- .../cassandra/thrift/CassandraDaemon.java | 3 ++ .../apache/cassandra/utils/FBUtilities.java | 47 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 172019c866..ef975a3af7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,8 @@ so slow reads/writes don't block gossip processing (CASSANDRA-1358) * faster UUIDType, LongType comparisons (CASSANDRA-1386, 1393) * add jmx port configuration to Debian package (CASSANDRA-1202) + * use mlockall via JNA, if present, to prevent Linux from swapping + out parts of the JVM (CASSANDRA-1214) 0.6.4 diff --git a/bin/cassandra.in.sh b/bin/cassandra.in.sh index 9d66ab016c..8ad2f4fb77 100644 --- a/bin/cassandra.in.sh +++ b/bin/cassandra.in.sh @@ -39,7 +39,7 @@ done # Arguments to pass to the JVM JVM_OPTS=" \ -ea \ - -Xms256M \ + -Xms1G \ -Xmx1G \ -XX:+UseParNewGC \ -XX:+UseConcMarkSweepGC \ diff --git a/src/java/org/apache/cassandra/thrift/CassandraDaemon.java b/src/java/org/apache/cassandra/thrift/CassandraDaemon.java index 0d47f3af73..262f2e35b9 100644 --- a/src/java/org/apache/cassandra/thrift/CassandraDaemon.java +++ b/src/java/org/apache/cassandra/thrift/CassandraDaemon.java @@ -42,6 +42,7 @@ import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.TProcessorFactory; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.utils.CLibrary; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.db.Table; import org.apache.cassandra.db.CompactionManager; @@ -62,6 +63,8 @@ public class CassandraDaemon private void setup() throws IOException, TTransportException { + FBUtilities.tryMlockall(); + // log4j String file = System.getProperty("storage-config") + File.separator + "log4j.properties"; PropertyConfigurator.configure(file); diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java index 5b4538cfdd..983518dffb 100644 --- a/src/java/org/apache/cassandra/utils/FBUtilities.java +++ b/src/java/org/apache/cassandra/utils/FBUtilities.java @@ -37,6 +37,7 @@ import org.apache.log4j.Logger; import org.apache.commons.collections.iterators.CollatingIterator; +import com.sun.jna.Native; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.db.marshal.AbstractType; @@ -549,4 +550,50 @@ public class FBUtilities throw new RuntimeException(e); } } + + public static void tryMlockall() + { + int errno = Integer.MIN_VALUE; + try + { + int result = CLibrary.mlockall(CLibrary.MCL_CURRENT); + if (result != 0) + errno = Native.getLastError(); + } + catch (UnsatisfiedLinkError e) + { + // this will have already been logged by CLibrary, no need to repeat it + return; + } + catch (Exception e) + { + logger_.debug("Unable to mlockall", e); + // skipping mlockall doesn't seem to be a Big Deal except on Linux. See CASSANDRA-1214 + if (System.getProperty("os.name").toLowerCase().contains("linux")) + { + logger_.warn("Unable to lock JVM memory (" + e.getMessage() + ")." + + " This can result in part of the JVM being swapped out, especially with mmapped I/O enabled."); + } + else if (!System.getProperty("os.name").toLowerCase().contains("windows")) + { + logger_.info("Unable to lock JVM memory: " + e.getMessage()); + } + return; + } + + if (errno != Integer.MIN_VALUE) + { + if (errno == CLibrary.ENOMEM && System.getProperty("os.name").toLowerCase().contains("linux")) + { + logger_.warn("Unable to lock JVM memory (ENOMEM)." + + " This can result in part of the JVM being swapped out, especially with mmapped I/O enabled." + + " Increase RLIMIT_MEMLOCK or run Cassandra as root."); + } + else if (!System.getProperty("os.name").toLowerCase().contains("mac")) + { + // OS X allows mlockall to be called, but always returns an error + logger_.warn("Unknown mlockall error " + errno); + } + } + } }