Elasticsearch是Java开发的,所以JVM的环境变量JAVA_OPTS对Elasticsearch也是非常重要的。在JAVA_OPTS中对Elasticsearch最重要的参数是-Xmx最大可以使用内存的参数,一般情况下大内存更能发挥Elasticsearch作用,建议-Xmx设置为物理内存的一半,为了减少内存分配带来的性能损耗,最好一开始就设置初始内存和最大内存都为物理内存的一半。及Xms和Xmx这两个参数。
由于JAVA_OPTS大多数时候对整个机器环境起作用,所以最好是保留默认的JAVA_OPTS,最好用ES_JAVA_OPTS环境变量设置来作为JAVA_OPTS参数。
默认的配置文件在elasticsearch/bin/elasticsearch.in.sh中
if [ "x$ES_MIN_MEM" = "x" ]; then ES_MIN_MEM=256m fi if [ "x$ES_MAX_MEM" = "x" ]; then ES_MAX_MEM=1g fi if [ "x$ES_HEAP_SIZE" != "x" ]; then ES_MIN_MEM=$ES_HEAP_SIZE ES_MAX_MEM=$ES_HEAP_SIZE fi JAVA_OPTS="$JAVA_OPTS -Xms${ES_MIN_MEM}" JAVA_OPTS="$JAVA_OPTS -Xmx${ES_MAX_MEM}"
ES_HEAP_SIZE环境变量允许设置被分配到Elasticsearch java进程中堆内存大小。最小和最大值将分配相同的值到,可以通过设置 ES_MIN_MEM(默认为256M)和ES_MAX_MEM(默认为1G)对堆内存进行设置(不推荐)。
文件描述符(File Descriptor)
文件描述符,是一个简单的整数,用以标明每一个被进程所打开的文件和socket。第一个打开的文件是0,第二个是1,依此类推。要增加打开的文件描述符的数量,建议设置为32K或64K。
为了测试有多少个文件在进程中可以被打开,环境变量-Des.max-open-files设置为true。 Elasticsearch将在启动时打印打开文件描述符的数量。或者,您可以通过查看每个节点信息的API进行查看。执行:
GET localhost:9200/_nodes/stats/process?pretty
文件存储:
Elasticsearch采用混合mmap fs /nio fs为默认的方式存储索引。默认的操作系统mmap设置可能是太低,这可能会导致内存溢出异常。在Linux系统中,您可以用root账户通过以下命令来增加限制:
sysctl -w vm.max_map_count=262144
如果要想使设置永久生效,可以设置/etc/sysctl.conf中的vm.max_map_count值。
注意:如果使用安装包(.deb, .rpm)来进行安装,此值会自动进行设置。
有不同的文件系统的有不同存储类型。这个参数一般会自动选择:Windows 64bit操作系统一般是mmapfs,在Windows 32位操作系统一般是simplefs,Elasticsearch默认为(niofs/mmapfs混合方式)。这个参数可以配置使所有的索引生效,配置文件为config/elasticsearch.yml。
配置项:index.store.type: niofs
也可以在建索引的时候指定类型:
PUT localhost:9200/my_index{ "settings": { "index.store.type": "niofs" } }
注意:这个设置有可能在未来被删除。
可选择的参数
Simple FS(简单文件系统)
Simplefs类型是一个简单的实现随机访问文件的文件存储系统(映射到Lucene SimpleFsDirectory的)。该实现的并发性能较差(多线程是个瓶颈)。当你需要将索引持久化时,最好使用niofs。
NIO FS(NIO文件系统)
niofs类型是通过NIO将分片索引文件写到文件系统上(映射到Lucene NIOFSDirectory)。它允许多线程同时读取文件。不建议在Windows系统上使用,由于JAVA在实现上有一个错误。
MMap FS(内存映射文件系统)
mmapfs类型通过映射文件到内存中(MMAP)存储分片索引到文件系统上(映射到Lucene MMapDirectory)。内存映射的过程中将划分出与被映射文件大小一样的虚拟内存空间。使用这个类之前,请确保您有足够的虚拟地址空间。
default_fs
默认类型是混合NiO FS和mmapfs,系统会自动选择操作系统匹配最好的文件系统。目前只有Lucene的term dictionary和doc values采用内存映射的方式来减少对操作系统的影响。所有其他的方式都使用Lucene niofsdirectory打开。
本文由赛克蓝德(secisland)原创,转载请标明作者和出处。
现代操作系统大多数使用尽可能多的内存来作为文件系统缓存,并通过交换分区(swap)来移走程序中暂时不用的内存。这可能会导致Elasticsearch进程内存被过多的切换。交换分区(swap)对性能和稳定性都有一定的影响,所以在Elasticsearch中应该尽量避免使用交换分区。
在Elasticsearch设置中有三种方式可以选择:
1、禁用交换分区
这是一种最简单的方式:
在linux系统中,可以通过命令:sudo swapoff -a暂时禁止.如果要永久禁用,需要编辑/etc/fstab文件,注释掉包含swap的行。
在windows系统中可以通过控制面板->系统->高级系统设置->高级->性能设置->高级->虚拟内存中进行设置。
2、配置swappiness
要确保sysctl设置vm.swappiness参数为0,在通常情况下会降低交换的频率,同时在紧急情况下会启用交换。
注意:在内核3.5-rc1及以上版本中,如果设置vm.swappiness为零,OOM将会采用杀进程的方式来代替内存交换,需要设置vm.swappiness为1,会在紧急情况下会启用交换。
3、使用mlockall
在Unix或Linux系统中或者设置了virtuallock 的Windows,可以试图锁定进程地址空间到RAM中,防止任何Elasticsearch内存被交换出去。 可以在config/elasticsearch.yml进行设置:
bootstrap.mlockall: true
启动后Elasticsearch后,你可以通过api检查mlockall是否成功应用:
如果返回值中的mlockall为false,这就意味着mlockall设置失败。最有可能的原因是,在Linux/Unix系统中,运行Elasticsearch的用户没有权限设置。这可以通过root用户运行ulimit -l unlimited进行设置。另一个可能的原因是,mlockall不能在临时目录中(通常是/tmp)生效。这可以通过指定一个新的临时目录解决,在启动Elasticsearch时指定:
./bin/elasticsearch -Djna.tmpdir=/path/to/new/dir
注意:当系统没有可用内存时,在Elasticsearch尝试分配更多的内存时,mlockall可能导致JVM或shell会话的退出。
赛克蓝德(secisland)后续会逐步对Elasticsearch的最新版本的各项功能进行分析,近请期待。