Browse Source

When on linux, force it not to swap elasticsearch process (jvm), closes #464.

kimchy 15 years ago
parent
commit
96a1ad6335

+ 9 - 0
.idea/modules/elasticsearch.iml

@@ -38,6 +38,15 @@
         </SOURCES>
       </library>
     </orderEntry>
+    <orderEntry type="module-library" exported="">
+      <library name="jna">
+        <CLASSES>
+          <root url="jar://$GRADLE_REPOSITORY$/net.java.dev.jna/jna/jars/jna-3.2.7.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
     <orderEntry type="library" scope="TEST" name="testng" level="project" />
     <orderEntry type="library" scope="TEST" name="hamcrest" level="project" />
     <orderEntry type="module" module-name="test-testng" scope="TEST" />

+ 1 - 0
build.gradle

@@ -49,6 +49,7 @@ allprojects {
         mavenRepo urls: 'http://elasticsearch.googlecode.com/svn/maven'
         mavenRepo urls: 'http://oss.sonatype.org/content/repositories/releases'
         mavenRepo urls: 'http://oss.sonatype.org/content/repositories/snapshots'
+        mavenRepo urls: 'http://download.java.net/maven/2/'
     }
 }
 

+ 3 - 0
modules/elasticsearch/build.gradle

@@ -35,6 +35,8 @@ dependencies {
     compile('org.slf4j:slf4j-log4j12:1.5.11') { transitive = false }
     compile('log4j:log4j:1.2.15') { transitive = false }
 
+    compile('net.java.dev.jna:jna:3.2.7') { transitive = false }
+
     compile 'org.apache.lucene:lucene-core:3.0.2'
     compile 'org.apache.lucene:lucene-analyzers:3.0.2'
     compile 'org.apache.lucene:lucene-queries:3.0.2'
@@ -130,6 +132,7 @@ uploadArchives {
 
         pom.whenConfigured {pom ->
             pom.dependencies = pom.dependencies.findAll {dep -> dep.scope != 'test' } // removes the test scoped ones
+            pom.dependencies = pom.dependencies.findAll {dep -> !dep.artifactId.contains('jna') } // remove jna, its optional
             pom.dependencies = pom.dependencies.findAll {dep -> !dep.artifactId.contains('jarjar') }
             pom.dependencies = pom.dependencies.findAll {dep -> !dep.artifactId.contains('log4j') }
             pom.dependencies = pom.dependencies.findAll {dep -> !dep.artifactId.contains('slf4j') }

+ 3 - 0
modules/elasticsearch/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java

@@ -26,6 +26,7 @@ import org.elasticsearch.common.collect.Tuple;
 import org.elasticsearch.common.inject.CreationException;
 import org.elasticsearch.common.inject.spi.Message;
 import org.elasticsearch.common.jline.ANSI;
+import org.elasticsearch.common.jna.Natives;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 import org.elasticsearch.common.logging.log4j.LogConfigurator;
@@ -57,6 +58,8 @@ public class Bootstrap {
     private static volatile CountDownLatch keepAliveLatch;
 
     private void setup(boolean addShutdownHook, Tuple<Settings, Environment> tuple) throws Exception {
+//        Loggers.getLogger(Bootstrap.class, tuple.v1().get("name")).info("heap_size {}/{}", JvmStats.jvmStats().mem().heapCommitted(), JvmInfo.jvmInfo().mem().heapMax());
+        Natives.tryMlockall();
         tuple = setupJmx(tuple);
 
         NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder().settings(tuple.v1()).loadConfigSettings(false);

+ 55 - 0
modules/elasticsearch/src/main/java/org/elasticsearch/common/jna/CLibrary.java

@@ -0,0 +1,55 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.common.jna;
+
+import com.sun.jna.Native;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.Loggers;
+
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class CLibrary {
+
+    private static ESLogger logger = Loggers.getLogger(CLibrary.class);
+
+    public static final int MCL_CURRENT = 1;
+    public static final int MCL_FUTURE = 2;
+
+    public static final int ENOMEM = 12;
+
+    static {
+        try {
+            Native.register("c");
+        } catch (NoClassDefFoundError e) {
+            logger.debug("JNA not found. Native methods will be disabled.");
+        } catch (UnsatisfiedLinkError e) {
+            logger.debug("Unable to link C library. Native methods will be disabled.");
+        }
+    }
+
+    public static native int mlockall(int flags);
+
+    public static native int munlockall();
+
+    private CLibrary() {
+    }
+}

+ 55 - 0
modules/elasticsearch/src/main/java/org/elasticsearch/common/jna/Natives.java

@@ -0,0 +1,55 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.common.jna;
+
+import com.sun.jna.Native;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.Loggers;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class Natives {
+
+    private static ESLogger logger = Loggers.getLogger(Natives.class);
+
+    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;
+        }
+
+        if (errno != Integer.MIN_VALUE) {
+            if (errno == CLibrary.ENOMEM && System.getProperty("os.name").toLowerCase().contains("linux")) {
+                logger.debug("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.debug("Unknown mlockall error " + errno);
+            }
+        }
+    }
+}