Elasticsearch默认安装后设置的内存是1GB,对于任何一个业务部署来讲,这个都过小了。若是你正在使用这些默认堆内存配置,你的集群配置可能有点问题。java
这里有两种方式修改Elasticsearch的堆内存(下面就说内存好了),最简单的一个方法就是指定ES_HEAP_SIZE环境变量。服务进程在启动时候会读取这个变量,并相应的设置堆的大小。举例,你能够用下面的命令设置它node
export ES_HEAP_SIZE=10gbootstrap
此外,你也能够经过命令行参数的形式,在程序启动的时候把内存大小传递给它:缓存
./bin/elasticsearch -Xmx10g -Xms10g服务器
备注:确保Xmx和Xms的大小是相同的,防止程序在运行时改变大小,这个是很废的。app
通常来讲设置ES_HEAP_SIZE环境变量,比直接写-Xmx10g -Xms10g更好一点。jvm
把你的内存的一半给Luceneelasticsearch
一个常见的问题是配置一个大内存,假设你有一个64G内存的机器,个人天,你想把64G内存给Elasticsearch吗? 越大越好!性能
固然,内存对于Elasticsearch来讲绝对是重要的,用于更多的内存数据提供更快的操做。并且还有一个内存消耗大户-Lucene编码
Lucene的设计目的是把底层OS里的数据缓存到内存中。Lucene的段是分别存储到单个文件中的,这些文件都是不会变化的,因此很利于缓存,同时操做系统也会把这些段文件缓存起来,以便更快的访问。
Lucene的性能取决于和OS的交互,若是你把全部的内存都分配给Elasticsearch,不留一点给Lucene,那你的全文检索性能会不好的。
最后标准的建议是把50%的内存给elasticsearch,剩下的50%也不会没有用处的,Lucene会很快吞噬剩下的这部份内存。
不要超过32G
这里有另一个缘由不分配大内存给Elasticsearch,事实上jvm在内存小于32G的时候会采用一个内存对象指针压缩技术。
在java中,全部的对象都分配在堆上,而后有一个指针引用它。指向这些对象的指针大小一般是CPU的字长的大小,不是32bit就是64bit,这取决于你的处理器,指针指向了你的值的精确位置。
对于32位系统,你的内存最大可以使用4G。对于64系统可使用更大的内存。可是64位的指针意味着更大的浪费,由于你的指针自己大了。浪费内存不算,更糟糕的是,更大的指针在主内存和缓存器(例如LLC, L1等)之间移动数据的时候,会占用更多的带宽。
java 使用一个叫内存指针压缩的技术来解决这个问题。它的指针再也不表示对象在内存中的精确位置,而是表示偏移量。这意味着32位的指针能够引用40亿个对象,而不是40亿个字节。最终,也就是说堆内存长到32G的物理内存,也能够用32bit的指针表示。
一旦你越过那个神奇的30-32G的边界,指针就会切回普通对象的指针,每一个对象的指针都变长了,就会使用更多的CPU内存带宽,也就是说你实际上失去了更多的内存。事实上当内存到达40-50GB的时候,有效内存才至关于使用内存对象指针压缩技术时候的32G内存。
这段描述的意思就是说:即使你有足够的内存,也尽可能不要超过32G,由于它浪费了内存,下降了CPU的性能,还要让GC应对大内存。
*我有一个1TB内存的机器
这个32GB的线是很很重要的,那若是你的机器有很大的内存怎么办呢?如今的机器内存广泛增加,你如今均可以看到有300-500GB内存的机器。
首先,咱们建议编码使用这样的大型机
其次,若是你已经有了这样的机器,你有两个可选项:
>你主要作全文检索吗?考虑给Elasticsearch 32G内存,剩下的交给Lucene用做操做系统的文件系统缓存,全部的segment都缓存起来,会加快全文检索。
>你须要更多的排序和聚合?你但愿更大的堆内存。你能够考虑一台机器上建立两个或者更多ES节点,而不要部署一个使用32+GB内存的节点。仍然要坚持50%原则,假设 你有个机器有128G内存,你能够建立两个node,使用32G内存。也就是说64G内存给ES的堆内存,剩下的64G给Lucene。
若是你选择第二种,你须要配置cluster.routing.allocation.same_shard.host:true。这会防止同一个shard的主副本存在同一个物理机上(由于若是存在一个机器上,副本的高可用性就没有了)。
swapping是性能的坟墓
这是显而易见的,可是仍是有必要说的更清楚一点,内存交换到磁盘对服务器性能来讲是致命的。想一想看一个内存的操做必须是快速的。
若是内存交换到磁盘上,一个100微秒的操做可能变成10毫秒,再想一想那么多10微秒的操做时延累加起来。不难看出swapping对于性能是多么可怕。
最好的办法就是在你的操做系统中彻底禁用swapping。这样能够暂时禁用:
sudo swapoff -a
为了永久禁用它,你可能须要修改/etc/fstab文件,这要参考你的操做系统相关文档。
若是彻底禁用swap,对你来讲是不可行的。你能够下降swappiness 的值,这个值决定操做系统交换内存的频率。这能够预防正常状况下发生交换。但仍容许os在紧急状况下发生交换。
对于大部分Linux操做系统,能够在sysctl 中这样配置:
vm.swappiness = 1
备注:swappiness设置为1比设置为0要好,由于在一些内核版本,swappness=0会引起OOM(内存溢出)
最后,若是上面的方法都不能作到,你须要打开配置文件中的mlockall开关,它的做用就是运行JVM锁住内存,禁止OS交换出去。在elasticsearch.yml配置以下: bootstrap.mlockall: true