Elasticsearch默认安装后设置的内存是1GB,对于任何一个业务部署来说,这个都太小了。如果你正在使用这些默认堆内存配置,你的集群配置可能有点问题。

这里有两种方式修改Elasticsearch的堆内存(下面就说内存好了),最简单的一个方法就是指定ES_HEAP_SIZE环境变量。服务进程在启动时候会读取这个变量,并相应的设置堆的大小。举例,你可以用下面的命令设置它

export ES_HEAP_SIZE=10g

此外,你也可以通过命令行参数的形式,在程序启动的时候把内存大小传递给它:

./bin/elasticsearch -Xmx10g -Xms10g

备注:确保Xmx和Xms的大小是相同的,防止程序在运行时改变大小,这个是很废的。

一般来说设置ES_HEAP_SIZE环境变量,比直接写-Xmx10g -Xms10g更好一点。

把你的内存的一半给Lucene

一个常见的问题是配置一个大内存,假设你有一个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

原文地址:https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html.

[翻译]Elasticsearch重要文章之二:堆内存的大小和swapping的更多相关文章

  1. [翻译]Elasticsearch重要文章之四:监控每个节点(jvm部分)

    http://zhaoyanblog.com/archives/753.html 操作系统和进程部分 操作系统和进程部分的含义是很清楚的,这里不会描述的很详细.他们列出了基本的资源统计,例如CPU和负 ...

  2. 关于ElasticSearch的堆内存设置与优化

    1.什么是堆内存?Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象.在 Java 中,堆被划分成两个不同的区域:- 新生代 ( Young ).- 老年代 ( Ol ...

  3. docker启动 elasticsearch 修改 xmx xms 堆内存大小修改

    用docker 安装的elasticsearch 5.6版本默认堆内存最大设置的2G 可以通过如下方法修改 [root@nova-92 logs]# find /var/lib/docker/ -na ...

  4. 求你了,别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  5. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

  6. JVM知识(一) 求你了,别再说Java对象都是在堆内存上分配空间的了!

    求你了,别再说Java对象都是在堆内存上分配空间的了! https://baijiahao.baidu.com/s?id=1661296872935371634&wfr=spider& ...

  7. Java虚拟机的内存组成以及堆内存介绍

    一.java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启 ...

  8. 浅析JAVA中堆内存与栈内存的区别

    Java把内存划分成两种:一种是栈内存,一种是堆内存. 一.栈内存 存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则.     栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都 ...

  9. Java堆内存的十个要点

    Java中的堆空间是什么? 当Java程序开始运行时,JVM会从操作系统获取一些内存.JVM使用这些内存,这些内存的一部分就是堆内存.堆内存通常在存储地址的底层,向上排列.当一个对象通过new关键字或 ...

随机推荐

  1. (转)linux内存源码分析 - 内存回收(lru链表)

    原文:http://www.cnblogs.com/tolimit/p/5447448.html 概述 对于整个内存回收来说,lru链表是关键中的关键,实际上整个内存回收,做的事情就是处理lru链表的 ...

  2. ps中的常用功能与技巧

    1.如何将多个png图片合成一个? 首先,打开ps,新建一个透明色画布,然后再将两张图片拖入(注意:回车拖入),然后再选中这三个图层,右键选择合并图层,最后快速导出为png即可. 2.如何快速找到ps ...

  3. sencha touch extend 单继承 和 mixins 实现多继承

    继承可以达到代码的复用,利于维护和扩展. sencha touch 中可以通过 extend 实现单继承,通过 mixins 实现多继承. mixins 也很像实现接口,不过这些接口的方法已经实现了, ...

  4. MyBatis Mapper XML 文件 的学习详解

    MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JDBC 代码来比较,你会发现映射文件节省了大约 ...

  5. IDE vscode识别webpack中alias配置路径

    引言网上看到一篇关于 ctrl+鼠标左键无法识别别名路径的问题,最后有人回复的方法只能在ts项目中可以识别 https://segmentfault.com/q/1010000011911879 最后 ...

  6. 阿里云 maven 地址

    http://maven.aliyun.com/nexus/content/groups/public/ 阿里云的 maven 地址

  7. Autofac +webapi 配置

    Autofac配置 using Autofac; using System; using System.Collections.Generic; using System.Linq; using Sy ...

  8. jquery ui dialog弹出窗 清空缓存Cache或强制刷新

    我用jquery ui 弹出一个购物车的对话,通过AJAX加载的数据.发现购物车被缓存,一直看到是旧数据.为了刷新购物车更新,我必须去加一个刷新按钮,点击后更新购物车页面.有没有一种方法来自动刷新加载 ...

  9. C#基础:传入URL,获得Http Post

    #region 传入url,获得Http Post public string HttpGet(string url) { string result = string.Empty; try { va ...

  10. [android] 切换界面的通用处理

    实现不改变activity,只切换View 抽取View界面的基类 利用面向对象多态的思路,实现通用 TitleManager.java 管理标题 package com.tsh.lottery.vi ...