diff --git a/.idea/modules/elasticsearch.iml b/.idea/modules/elasticsearch.iml index e8fa1fb441d..e7325437173 100644 --- a/.idea/modules/elasticsearch.iml +++ b/.idea/modules/elasticsearch.iml @@ -38,6 +38,15 @@ + + + + + + + + + diff --git a/build.gradle b/build.gradle index 66fdc8a1eb7..be644b38088 100644 --- a/build.gradle +++ b/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/' } } diff --git a/modules/elasticsearch/build.gradle b/modules/elasticsearch/build.gradle index 0a2603fd828..e22d7bb392e 100644 --- a/modules/elasticsearch/build.gradle +++ b/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') } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/modules/elasticsearch/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java index 8f0d9033ec8..a3d9e0a01a5 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java +++ b/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 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); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/jna/CLibrary.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/jna/CLibrary.java new file mode 100644 index 00000000000..2ff27762bee --- /dev/null +++ b/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() { + } +} diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/jna/Natives.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/jna/Natives.java new file mode 100644 index 00000000000..5150a030c7e --- /dev/null +++ b/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); + } + } + } +}