== 配置Elasticsearch ==
【Java(JVM)版本】
Elasticsearch基于java,为了能让它运行至少须要Java 8,只支持Oralce官方Java和OpenJDK
在所有的Elasticsearch节点和客户端上,应该使用同一版本的JVM
推荐安装的Java是1.8.0_73及更新的版本,如果使用的Java是一个已知的错误版本,Elasticsearch将拒绝启动
Elasticsearch会使用设置在环境变量JAVA_HOME里的Java版本
== 用.tar.gz包安装Elasticsearch ==
Elasticsearch支持多种安装方法,这里只翻译用.tar.gz包安装的部分
Elasticsearch提供.zip和.tar.gz安装包,用这二种包可以在任何系统上安装Elasticsearch,Elasticsearch的最新稳定版可在官方下载页面找到
注意:
Elasticsearch需要至少Java8及以上版本,使用Oracle官方发布版或开源发布版OpenJDK
【下载和安装.tar.gz包】
Elasticsearch v5.1.2的.tar.gz安装包可以用下列步骤下载和安装:
$ wget
$ tar -xzf elasticsearch-5.1.2.tar.gz
$ cd elasticsearch-5.1.2/
$ pwd
将完整路径设置成环境变量$ES_HOME
【从命令行运行Elasticsearch】
使用以下命令启动Elasticsearch:
$ ./bin/elasticsearch
Elasticsearch默认在前台运行,在屏幕(stdout)输出日志,能用 Ctrl+C 停掉
使用-q或--quiet选项启动Elasticsearch可禁止在stdout输出日志
【检查Elasticsearch是否运行】
可以通过向发送请求,以检查Elasticsearch是否运行:
$ curl -XGET
返回内容如下:
{
"name" : "wjtchji",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "9SwgwhN-TbSKLR6iW9tFgg",
"version" : {
"number" : "5.1.2",
"build_hash" : "c8c4c16",
"build_date" : "2017-01-11T20:18:39.146Z",
"build_snapshot" : false,
"lucene_version" : "6.3.0"
},
"tagline" : "You Know, for Search"
}
【以守护进程运行】
以守护进程运行Elasticsearch,在命令行中指定-d选项,用-p选项指定pid文件:
$ ./bin/elasticsearch -d -p ./es.pid
日志文件能在目录$ES_HOME/logs下找到
要关闭Elasticsearch,杀掉es.pid文件中的进程ID即可:
$ kill `cat ./es.pid`
【在命令行配置Elasticsearch】
Elasticsearch默认从$ES_HOME/config/elasticsearch.yml文件读取配置项,该文件中的任何配置都可以在命令行使用-E选项指定,如下:
$ ./bin/elasticsearch -d -Ecluster.name=my_cluster -Enode.name=node_1
一般,把集群类的配置(cluster.*)放在elasticsearch.yml文件中,而节点类的配置(node.*)在命令行中指定
【.tar.gz包的目录布局】
.tar.gz安装包是完全“自包含(self-contained)”的,所有文件和目录都包含在$ES_HOME下,即安装包解压生成的目录下
这是非常方便的,不必为了启动Elasticsearch而创建任何目录,要卸载Elasticsearch也只需删除$ES_HOME目录即可,然而,为了以后不会因误删而丢失重要数据,改变配置目录、数据目录和日志目录的位置是很明智的做法
类 型:home
描 述:即$ES_HOME
默认位置:安装包解压生成的目录
配 置 名:无
类 型:bin
描 述:可执行脚本目录,例如启动节点的elasticsearch和安装插件的elasticsearch-plugin等
默认位置:$ES_HOME/bin
配 置 名:无
类 型:conf
描 述:配置文件目录,例如elasticsearch.yml等
默认位置:$ES_HOME/config
配 置 名:path.conf
类 型:data
描 述:数据文件目录,即节点的索引和分片的存放目录,可以指定多个路径
默认位置:$ES_HOME/data
配 置 名:path.data
类 型:logs
描 述:日志文件目录
默认位置:$ES_HOME/logs
配 置 名:path.logs
类 型:plugins
描 述:插件文件目录,每个插件一个子目录
默认位置:$ES_HOME/plugins
配 置 名:无
类 型:repo
描 述:系统资源库共享文件的目录,可以指定多个路径,一个系统资源库文件可以位于任何路径下的任何子目录里
默认位置:无
配 置 名:path.repo
类 型:script
描 述:脚本文件目录
默认位置:$ES_HOME/scripts
配 置 名:path.scripts
== 配置Elasticsearch ==
Elasticsearch只需要较少的设置即可运行良好
配置文件中应该包含的配置有节点类的(例如node.name和各项路径),以及为了能让节点加入集群所需的配置(例如cluster.name和network.host等)
【配置文件位置】
Elasticsearch有二个配置文件:
- elasticsearch.yml 用于配置Elasticsearch
- log4j2.properties 用于配置日志
这些文件位于配置目录,默认为$ES_HOME/config,RPM包安装的Elasticsearch配置目录为/etc/elasticsearch
当然,配置目录也可用path.conf选项指定,例如:
$ ./bin/elasticsearch -Epath.conf=/path/to/my/config/
【配置文件格式】
YAML格式,例如:
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
【环境变量替换】
配置文件中可使用${...}符号引入环境变量,例如:
node.name: ${HOSTNAME}
network.host: ${ES_NETWORK_HOST}
== 日志配置 ==
Elasticsearch使用Log4j 2.x记录日志,通过log4j2.properties文件进行配置
Elasticsearch公开了一个属性${sys:es.logs},用于引用配置文件中指定的日志文件路径和文件名前缀,例如,用path.logs指定的日志目录为/var/log/elasticsearch,集群名为production,那么${sys:es.logs}的值为"/var/log/elasticsearch/production"
配置项说明:
appender.rolling.type = RollingFile
日志文件滚动切换
appender.rolling.fileName = ${sys:es.logs}.log
日志文件路径及文件名
appender.rolling.filePattern = ${sys:es.logs}-%d{yyyy-MM-dd}.log
滚动切换出的文件名
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
使用基于时间的滚动规则
appender.rolling.policies.time.interval = 1
日志文件按天滚动切换
appender.rolling.policies.time.modulate = true
以天为边界滚动日志文件
如果在appender.rolling.filePattern选项值加上.gz和.zip后缀,则滚动出的日志文件会被自动压缩
【废弃日志】
除了常规日志外,Elasticsearch还可以记录下在当前版本中被定义为废弃作为(deprecated action)的操作,这可以更早的决定是否在代码中移除某个功能,废弃日志默认被启用在WARN级别,该级别的所有废弃日志信息都会被记录
logger.deprecation.level = warn
将在日志目录里创建每天滚动的废弃日志文件,在打算升级到新版本前,定时检查该日志,确认不再有新的废弃操作
废弃日志会在达到1GB后切换并压缩,并保留5个日志文件(4个切换出的压缩文件,1个当前日志)
可以在config/log4j2.properties里将logger.deprecation.level设置为error以关闭废弃日志
== 重要的Elasticsearch配置 ==
尽管Elasticsearch只需要很少的设置,这里给出一些在进入生产环境使用前需要手动设置的配置项:
- path.data
- path.logs
- cluster.name
- node.name
- bootstrap.memory_lock
- network.host
- discovery.zen.ping.unicast.hosts
- discovery.zen.minimum_master_nodes
【path.data和path.logs】
如果使用.zip或.tar.gz包安装,data和logs目录即是$ES_HOME的子目录,如果这些重要的目录放在默认位置,当升级Elasticsearch到新版本时会有很高的误删风险
在生产环境使用,几乎总是应该改变数据和日志目录的位置:
path.logs: /var/log/elasticsearch
path.data: /var/data/elasticsearch
path.data可以设置多个路径,所有路径下都会存储数据(属于单个分片的文件会被存放在同一路径下)
【cluster.name】
一个节点只能加入一个集群中,默认的集群名为elasticsearch,应该设置为一个可描述集群用途的适当的名称
cluster.name: logging-prod
确保不会在不同的环境中重用相同的集群名,否则可能会导致节点加入错误的集群中
【node.name】
Elasticsearch会在第一次启动时生成随机的UUID,并默认的用UUID前7个字符作为节点名,节点名是永久的,不会因节点重启而改变
应该设置一个更有意义的名字,有利于识别该节点:
node.name: prod-data-2
也能设置为主机名,如下:
node.name: ${HOSTNAME}
【bootstrap.memory_lock】
确保JVM不会被一直交换到磁盘,对于节点的健康是非常重要的,一个可实现该目标的方法是将bootstrap.memory_lock设置为true,要让该配置真正起效,还需先对系统进行相应设置,将在后续章节介绍如何正确配置内存锁定的详细信息
【network.host】
Elasticsearch默认只绑定在回路地址,即127.0.0.1和[::1]上,这对一个用于开发环境的单节点来说是足够了
但为了组成集群,并与集群中的其它节点进行通信,必须将Elasticsearch绑定到一个非回路地址上,如:
network.host: 192.168.1.10
network.host还能设置一些特殊值(如_local_、_site_和_global_)和修饰符(如:ip4和:ip6)
一旦设置了network.host,Elasticsearch认为该节点运行在生产环境下,会对一些系统配置进行检查,如检查不合格将启动失败
【discovery.zen.ping.unicast.hosts】
当要与其他服务器上运行的节点组成集群时,须要设置集群成员的探索列表,如:
discovery.zen.ping.unicast.hosts: ["172.16.88.31", "172.16.88.32"]
默认的集群消息发送端口为transport.profiles.default.port(9300),消息接收端口为transport.tcp.port(9305)
【discovery.zen.minimum_master_nodes】
为防止数据丢失,将discovery.zen.minimum_master_nodes设置为集群的最少节点数是非常重要的,集群中能够互联通信的节点数达到该配置值,也是判断集群有效“存活”的标志
如没有这项设置,一个集群在遭受网络故障时会有分裂成二个独立集群的风险,即脑裂,这会导致数据的丢失
为防止脑裂,该配置项须要设置为 nodes_in_cluster/2+1,例如集群中共有3个节点,该配置值须为2,如有4个节点,要为3
discovery.zen.minimum_master_nodes: 2
== 启动检查 ==
在先前版本的Elasticsearch启动时,若不对上节提到的重要配置项进行设置,只会以警告(warning)信息记录在日志文件中,很多时候这容易被忽视,为了确保这个配置项得到应有的关注,最新版本的Elasticsearch在启动时将会进行检查
这些启动检查包含Elasticsearch和系统的多项配置,并将它们与Elasticsearch要求的值进行比较,如果Elasticsearch运行在开发模式,启动检查失败将只是以警告信息记录在日志文件中,如果Elasticsearch以生产模式运行,只要有任何检查项失败都会拒绝启动
有些检查项总是被强制执行,以防止Elasticsearch运行在不适合的配置下,以下分别对这些检查项进行介绍
【开发与生产模式】
Elasticsearch默认绑定在本地回路上,这对学习使用Elasticsearch是足够了,但不适合用在生产环境上,若要组建集群,Elasticsearch实例须能通过网络进行互相通信,所以必须绑定在有IP地址的外部网卡上
因此,当Elasticsearch实例未被绑定在外部网卡上时,认为是运行在开发模式,绑定外部网卡时,则认为运行在生产模式下,通过配置项network.host绑定Elasticsearch用以通信的IP
【JVM内存大小】
在config/jvm.options文件中设置了JVM运行的配置,其中包括JVM内存堆(heap)的初始(-Xms)和最大(-Xmx)大小,Elasticsearch要求这二项配置值相同,以保证性能
因为,如果bootstrap.memory_lock设置为true,JVM将在启动时锁定初始大小的内存堆,如果-Xms与-Xmx大小不同,在JVM使用的内存量超过-Xms后就要扩展,而在扩展后将会出现JVM堆不能被全部锁定在内存中的情况
【文件描述符检查】
Elasticsearch需要大量的文件描述符,例如组成分片的多个数据文件、与其它节点通信的网络连接符,等,该检查项在Linux上是强制的
# ulimit -n 655360
或
# vi /etc/security/limits.conf
-----
* - nofile 655360
-----
【内存锁检查】
当JVM进行完全垃圾回收时,会操作内存堆(heap)中的所有数据页(page),如果有数据页已被换出到磁盘,它们将不得不被交换回内存,这会引起磁盘颠簸,影响Elasticsearch对访问请求的响应
有多种系统配置的方法来避免数据页被换出到磁盘,一种是使用mlockall(Unix)将JVM堆锁定在内存中,即将Elasticsearch的bootstrap.memory_lock配置设为true,但是,如果系统的memlock未设置成unlimited,Elasticsearch仍可能无法锁定全部JVM内存堆
# ulimit -l unlimited
或
# vi /etc/security/limits.conf
-----
* - memlock unlimited
-----
【最大线程数检查】
Elasticsearch执行请求时会将请求分成数个阶段,并将每个阶段交给不同的线程池执行器,不同的线程池执行器又对应多种不同的任务,因此,Elasticsearch需要能够创建大量线程的能力
最大线程数检查用以确保Elasticsearch进程在正常使用下能有创建足够多线程的能力,该检查项在Linux上是强制的,如果Elasticsearch运行在Linux上,要通过此项检查就必须配置系统允许Elasticsearch进程创建至少2048个线程
# ulimit -u 655360
或
# vi /etc/security/limits.conf
-----
* - nproc 655360
-----
【最大虚拟内存检查】
Elasticsearch使用mmap将索引有效地分配到地址空间里,这能使索引数据不占用JVM内存堆,又能在内存中非常快速的存取
为了能实现该效果,Elasticsearch需要有不受限的地址空间大小,最大虚拟内存大小检查确保Elasticsearch进程有无限的地址空间,且该检查项在Linux上是强制的,必须对系统进行相应配置
# ulimit -v unlimited
或
# vi /etc/security/limits.conf
-----
* - as unlimited
-----
【最大映射数检查】
除了虚拟内存,要想有效使用mmamp,还需给Elasticsearch创建大量内存映射区的能力,最大映射数检查要求系统内核允许一个进程有至少262144bit大小的内存映射区,且该检查项在Linux上是强制的
# vi /etc/sysctl.conf
-----
vm.max_map_count = 524288
-----
# sysctl -p
【JVM运行模式检查】
有两种不同的JVM模式:client和server,二者以不同的方式将Java字节码编译成可执行的机器码,client模式对启动用时和内存占用调优,而server模式对最大化性能调优,两种JVM的运行性能差异巨大
JVM运行模式检查确保Elasticsearch不会运行在client模式,要通过此项检查就必须对Elasticsearch的JVM进行配置
$ vi config/jvm.options
-----
-server
-----
在当前版本的Elasticsearch里,配置文件jvm.options中默认加上了该选项
【串行收集器检查】
JVM为不同工作负载提供多种垃圾收集器,其中串行收集器最适用于单核CPU或非常小的JVM内存堆,但无论如何都不适用于Elasticsearch,使用串行垃圾收集器会严重影响Elasticsearch的运行性能
串行收集器检查确保Elasticsearch不使用串行垃圾回收方法,例如误用了JVM的-XX:+UseSerialGC选项启动Elasticsearch,当前版本的Elasticsearch默认使用CMS收集器
$ vi config/jvm.options
-----
-XX:+UseConcMarkSweepGC
-----
【系统调用过滤器检查】
Elasticsearch根据所在操作系统运行不同的系统调用过滤器,例如在Linux上是安装seccomp,用于阻止执行与fork()相关的系统调用,作为一种防御机制抵挡恶意代码执行对Elasticsearch的攻击
如果启用了Elasticsearch的系统调用过滤器功能,该检查项用以确保过滤器成功运行,要通过此项检查就必须修复所有妨碍系统调用过滤器运行的操作系统配置错误,或将bootstrap.system_call_filter设置为false以关闭此项检查
【OnError和OnOutOfMemoryError检查】
JVM的OnError和OnOutOfMemoryError选项能够让其在遭遇致命错误或内存溢出时执行预设命令,然而,Elasticsearch默认开启的系统调用过滤功能会阻止fork()操作,因此,OnError和OnOutOfMemoryError与其不相容,该检查项就是检测OnError或OnOutOfMemoryError是否与bootstrap.system_call_filter同时启用,如果是就终止Elasticsearch启动
此项检查是强制的,所以,在Elasticsearch的默认配置下,既不能启用OnError,也不能启用OnOutOfMemoryError,但是,当前版本的Elasticsearch支持-XX:+HeapDumpOnOutOfMemoryError选项(Java版本须在8u92以上)
【G1GC检查】
在与JDK8配套的HotSpot JVM早期版本上有一个已知问题,当启用G1GC收集器时会导致索引损坏,JDK 8u40之前的版本都有该问题
G1GC检查就是检测当前使用的JDK是否为早期有问题的版本
== 重要的系统配置 ==
理想情况下,Elasticsearch应该单独运行在一台服务器上,并且使用服务器上所有的可用资源,为了实现这个效果,需要调优操作系统以允许Elasticsearch能比默认情况下操作更多的资源
在投入生产环境前,以下配置项必须被妥当设置:
- 设置JVM内存堆大小
- 禁用换入换出(swapping)
- 增大文件描述符
- 确保足够的虚拟内存
- 确保足够的线程数
【开发模式和生产模式】
Elasticsearch默认配置是运行在开发模式下,如果上述配置未正确设置,只会在日志文件中记录警告信息,不影响Elasticsearch的启动和运行
一旦设置了network.host这类的网络配置项,Elasticsearch就会以生产模式运行,所有警告都会提升为异常,如这些异常存在,会阻止Elasticsearch节点的启动,这是一个重要的安全措施,以保障不会因错误的配置而丢失数据或影响性能
【设置系统配置】
注意:
这里只翻译了使用.tar.gz包安装的配置方法
如使用.tar.gz包安装,有以下两种设置方式:
- 临时生效,使用ulimit命令
- 永久有效,写入/etc/security/limits.conf文件
【ulimit】
在Linux系统,ulimit命令可用于临时调整系统资源限制,先以root用户调优限制,再切换到运行Elasticsearch的用户,例如,设置最大打开文件数为65536:
$ sudo su
提升为root用户,或直接以root用户登录
$ ulimit -n 65536
调整最大打开文件数为65536
$ su elasticsearch
切换到elasticsearch用户启动Elasticsearch
该新限制只在当前会话有效,可以用以下命令查看所有当前生效的限制:
$ ulimit -a
【limits.conf】
在Linux系统,可以在/etc/security/limits.conf文件中为指定用户设置永久限制,例如,为elasticsearch用户设置最大打开文件数为65536,增加该行到limits.conf文件中:
# vi /etc/security/limits.conf
-----
elasticsearch - nofile 65536
-----
该调优将在elasticsearch用户打开新会话时生效
【设置JVM选项】
设置JVM选项的优先方法是编辑Elasticsearch的jvm.options配置文件,该文件默认位置为config/jvm.options(以.tar.gz包安装)或/etc/elasticsearch/jvm.options(以RPM包安装),文件中每行一个JVM参数,且必须以减号(-)开头,可以在该文件中加入想要的JVM参数
另一个设置JVM选项的方法是设置环境变量$ES_JAVA_OPTS,例如:
$ export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
$ ./bin/elasticsearch
先生效环境变量,再启动Elasticsearch
【设置JVM内存堆大小】
Elasticsearch默认的JVM内存堆大小为2GB,当在生产环境使用时,加大内存堆大小以保障Elasticsearch有足够的内存可用是非常重要的
Elasticsearch会按在jvm.options文件中用Xms(最小)和Xmx(最大)指定的内存堆大小一次性分配到手
该配置值取决于服务器的内存大小,推荐的分配规则是:
- 最小内存堆(Xms)和最大内存堆(Xmx)大小必须设置相同
- Elasticsearch有越多的内存可用,就有越多的数据可被缓存,但垃圾回收引起的停顿时间也越长
- 设置Xmx不超过50%的物理内存大小,确保有足够的物理内存留给内核文件系统缓存
- 不要将Xmx设置为高于JVM用于压缩对象指针(compressed oops)的截断值,截断值不是固定的,但接近32GB
可以通过查看日志文件中是否有类似下行信息来验证Xmx是否在截断值之下:
heap size [1.9gb], compressed ordinary object pointers [true]
- 更好的,保持Xmx在零基压缩对象指针阈值之下,阈值不是固定的,大多数系统为26GB,也有30GB的系统
要验证Xmx是否在零基压缩之下,可以使用以下JVM选项启动Elasticsearch:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode
并查找日志文件中是否有类似下行信息:
heap address: 0x000000011be00000, size: 27648 MB, zero based Compressed Oops
如超过了零基压缩阈值,即零基压缩对象指针被启用,则信息类似于这样:
heap address: 0x0000000118400000, size: 28672 MB, Compressed Oops with base: 0x00000001183ff000
在当前Elasticsearch版本的jvm.options文件中,最小和最大内存堆设置如下:
-Xms2g
-Xmx2g
也可通过环境变量设置内存堆大小,注释jvm.options文件中的Xms和Xmx选项,用以下命令启动Elasticsearch:
$ ES_JAVA_OPTS="-Xms2g -Xmx2g" ./bin/elasticsearch
【禁用换入换出(swapping)】
多数操作系统倾向于为文件系统缓存使用尽可能多的内存,而积极换出不在使用的应用内存,这会导致Elasticsearch的部分JVM内存堆被换出到磁盘
换入换出对节点的性能和稳定性有非常坏的影响,应该极力避免,会使垃圾回收持续数分钟而不是几毫秒,也会使节点响应缓慢,甚至断开与集群的连接
这里介绍三种禁止换入换出的方法:
- 启用bootstrap.memory_lock
第一种方法是使用Linux/Unix的mlockall系统调用,尝试把进程的地址空间锁定在内存中,阻止任何Elasticsearch数据被从内存中换出,设置方法是在config/elasticsearch.yml中增加以下行:
bootstrap.memory_lock: true
注意:
mlockall可能导致JVM在尝试分配比可用内存更多的内存时退出
在启动Elasticsearch后,可通过以下请求检查mlockall值以确认设置是否成功生效:
$ curl -XGET '**.mlockall&pretty'
如果返回mlockall为false,则意为mlockall请求失败,同时还会在日志文件中找到类似如下的信息:
Unable to lock JVM Memory
最可能的原因是,运行Elasticsearch的用户没用锁定内存的权限(能力),可以按如下方法赋予:
在启动Elasticsearch前,以root用户执行 ulimit -l unlimited,或在/etc/security/limits.conf文件中设置memlock为unlimited
另一个可能的原因是,mlockall需要的临时目录(默认为/tmp)以noexec选项挂载,可用环境变量ES_JAVA_OPTS指定一个单独的临时目录:
$ export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
$ ./bin/elasticsearch
当然,也可以设置在config/jvm.options配置文件里
- 禁用所有Swap文件
第二种方法是完全禁用Swap,如果一台服务器上只运行Elasticsearch,JVM可以掌控所有的内存使用,那么就不需要启用Swap了
在Linux系统上,临时禁用Swap可以执行以下命令:
# swapoff -a
要永久禁用,须编辑/etc/fstab文件,注释掉所有包含'swap'字眼的行,然后重启系统
- 设置swappiness
每三种方法是设置sysctl的vm.swappiness值为1,降低内核交换数据的倾向,在正常情况下不进行数据交换
【增大文件描述符】
Elasticsearch需要使用大量文件描述符或文件句柄,文件描述符不足将有较大可能引发数据丢失,确保提升运行Elasticsearch的用户的最大打开文件数到65536或更高
在启动Elasticsearch前,以root用户执行 ulimit -n 65536,或在/etc/security/limits.conf文件中设置nofile为65536
执行以下请求,检查每个节点的max_file_descriptors设置是否正确:
$ curl -XGET '**.max_file_descriptors&pretty'
【确保足够的虚拟内存】
Elasticsearch默认使用“mmapfs/niofs混合型”目录存储数据(即索引),而操作系统默认的mmap总数限制很低,这会导致内存溢出异常
在Linux上,可用root用户执行以下命令提升mmap总数限制:
# sysctl -w vm.max_map_count=262144
要永久提升,须设置/etc/sysctl.conf文件中的vm.max_map_count参数,并重启
【确保足够的线程数】
Elasticsearch为不同类型的操作使用多个线程池,能按需随时创建新线程是非常重要的,确保运行Elasticsearch的用户能创建的线程数不少于2048个
可在启动Elasticsearch前,以root用户执行 ulimit -u 2048,或在/etc/security/limits.conf文件中设置nproc为2048
== 升级Elasticsearch ==
在升级前,必须完成以下五件事:
- 查阅《重大改变(breaking changes)》文档
- 使用Elasticsearch迁移插件检测潜在的问题
- 在开发环境下测试升级
- 如果使用其他插件,确认新版本兼容
- 升级前必须备份数据
Elasticsearch具有滚动升级(rolling upgrade)的能力,在特定条件下升级过程中不会中断服务
本章详细介绍滚动升级和全集群重启升级(full cluster restart)的方法,请参照下表确定采取的升级方法:
From To Upgrade Type
1.x 5.x 重建索引升级(reindex to upgrade)
2.x 2.y 滚动升级(y>x)
2.x 5.x 全集群重启升级
5.0.0 5.x 全集群重启升级
5.x 5.y 滚动升级(y>x)
注意:
Elasticsearch只能读取上一主版本创建的索引,例如,5.x能使用2.x创建的索引,但能使用1.x或更早版本的索引
这个限制也适用于使用Elasticsearch自带的“快照和恢复(snapshot and restore)”功能,如果一个索引起初是1.x创建,它将不能恢复到5.x里,即使快照是用2.x生成的
如果存在太旧的索引,Elasticsearch 5.x节点将启动失败
【滚动升级】
滚动升级只允许Elasticsearch集群一次升级一个节点,但无宕机时间,只支持升级期间短暂的在同一集群中运行多个版本的Elasticsearch,因为新版本上的数据分片不会被复制到旧版本上
在执行滚动升级前,请务必确认当前版本的集群是否支持滚动升级到目标版本
执行滚动升级的步骤:
1. 禁止分片分配
当关闭一个节点后,为满足分片的复本数,集群会复制关闭节点里所含分片的复本到其他节点上,这是不必要的,因为节点升级后即会恢复,并不是真的丢失复本,也会带来不必要的IO开销,可在关闭节点前禁止分片分配:
$ curl -XPUT '' -d '{ "transient": { "cluster.routing.allocation.enable": "none" } }'
2. 停止非关键的索引(vt.),并执行磁盘同步刷新(sync-flush)
在升级期间可以继续欢乐的索引(vt.)数据,但是如果临时停止非关键的索引(vt.)并执行同步刷新,可使分片恢复速度更快:
$ curl -XPOST ''
同步刷新是一个“尽力而为”的操作,有任何挂起(pending)的索引操作都将导致失败,但是如有必要,执行多次同步刷新也是安全
3. 关闭并升级单个节点
每次只操作集群中的一个节点,先关闭再升级
注意:
在使用.tar.gz安装的Elasticsearch上,config、data、logs和plugins目录都被放置在默认路径下,最好的作法是将这些目录放置在非默认路径下,在升级Elasticsearch时才不会被删除,可用path.conf、path.logs和path.data指定这些目录位置,并用环境变量ES_JVM_OPTIONS指定jvm.options文件路径
使用.tar.gz包升级:
- 解压.tar.gz包到新目录下,确保不会覆盖config和data目录
- 可以拷贝原来的config目录到新安装位置下,也可以设置环境变量ES_JVM_OPTIONS指定jvm.options文件路径,并用elasticsearch启动选项'-E path.conf='指定到原来的config目录
- 可以拷贝原来的data目录到新安装位置下,也可以在config/elasticsearch.yml文件中用path.data参数设置数据目录位置
4. 升级所有插件
当升级Elasticsearch节点时,插件必须被一起升级,使用elasticsearch-plugin脚本安装所需插件的正确版本
5. 启动该待升级节点
正常启动该待升级节点,并确认它加入集群,检查日志文件内容,并执行以下请求查看返回,确认节点健康状态:
$ curl -XGET ''
6. 重启分片分配
只要节点正常回归集群,就可以重启分片分配:
$ curl -XPUT '' -d '{ "transient": { "cluster.routing.allocation.enable": "all" } }'
7. 等待节点恢复
必须等待集群完成分片分配后,再升级下一个节点,如此才能保证数据不会丢失且不影响服务,执行以下请求确认集群状态:
$ curl -XGET ''
等待status列的值从yellow变成green,表示所有主分片和复本分片都已完成分配
注意:
在滚动升级期间,被分配到高版本节点的主分片将不能复制到低版本节点上,因为新版本可能使用旧版本无法理解的新数据格式
如果尚无第二台新版本节点可分配给复本分片,例如目前集群中只有一台新版本节点,那么复本分片将暂缓分配,且集群健康状态保持为'yellow'
在这种情况下,在继续升级其他节点前,检查init和relo列是否为0,即没有正在初始化或迁移的分片
一旦有第二台节点被升级到新版本,这些复本分片就应该被分配,并且集群健康将达到green
未被同步刷新的分片会花较多时间来恢复,这些分片的恢复状态可使用以下请求监控:
$ curl -XGET ''
如果之前停掉了数据索引(vt.),一旦分片恢复完成即可安全的重新开始索引(vt.)
8. 重复
当节点恢复和集群稳定后,重复上述7步,完成对集群中所有节点的升级
【全集群重启升级】
当跨主版本升级Elasticsearch时,须要全集群重启,滚动升级还不支持跨主版本升级
以下介绍全集群重启升级步骤:
1. 禁止分片分配
当关闭一个节点后,为满足分片的复本数,集群会复制关闭节点里所含分片的复本到其他节点上,这是不必要的,因为节点升级后即会恢复,并不是真的丢失复本,也会带来不必要的IO开销,可在关闭节点前禁止分片分配:
$ curl -XPUT '' -d '{ "transient": { "cluster.routing.allocation.enable": "none" } }'
2. 执行磁盘同步刷新(sync-flush)
如果停止索引(vt.)数据并执行同步刷新,可使分片恢复速度更快:
$ curl -XPOST ''
同步刷新是一个“尽力而为”的操作,有任何挂起(pending)的索引操作都将导致失败,但是如有必要,执行多次同步刷新也是安全
3. 关闭并升级所有节点
停掉集群中所有的Elasticsearch服务,按上节“滚动升级”中的第3步更新所有节点的Elasticsearch版本
4. 升级所有插件
当升级节点时,Elasticsearch插件也必须被升级,使用elasticsearch-plugin脚本安装所需插件的正确版本
5. 启动集群
如果集群中有专用的master节点(节点的node.master设为true,且node.data设为false),那么最先启动这类节点是最好的做法,等待它们形成集群并选举出master后再启动数据节点,可以通过日志信息检查各master节点的当前进度
一旦相互通信的master节点个数达到“最小master节点数”,它们就会形成集群并选举出master,从这一刻起,_cat/health和_cat/nodes请求即可用于监控集群和节点状态,通过这些请求检查所有节点是否成功加入集群
6. 等待yellow
当所有节点都加入到集群后,各节点就会开始恢复存储在本地的主分片,一开始,_cat/health会报告集群status为red,意为并非所有的主分片都被分配
当所有节点都恢复完本地的主分片后,集群的status会转变成yellow,这意为所有主分片都已恢复完成,但并非所有复本分片都被分配,这是因为分片分配仍被禁止
7. 重启分片分配
只有当所有节点已经加入集群,并完成本地主分片恢复,准备向其他节点分配复本分片时,才能重启分片分配:
$ curl -XPUT '' -d '{ "transient": { "cluster.routing.allocation.enable": "all" } }'
集群将开始分配复本分片到所有数据节点,此时已经可以安全的索引(vt.)和搜索数据了,但这会影响到集群恢复的速度,所以最好还是等到所有分片都恢复完成后,再开放索引(vt.)和搜索数据
使用以下两个请求可以监控恢复进度:
$ curl -XGET ''
$ curl -XGET ''
当_cat/health的status列的值变为green时,即表示所有主分片和复本分片已经全部被成功分配
【重建索引升级】
Elasticsearch只能兼容上一个主版本的索引,例如,5.x能使用2.x创建的索引,但不能使用1.x或更早版本创建的索引
注意:
当存在过旧版本的索引时,Elasticsearch 5.x节点会启动失败
如果运行的Elasticsearch 2.x集群包含1.x版本创建的索引,则必须以2.x版本重建这些索引,然后才能升级到5.x
如果运行的是Elasticsearch 1.x集群,则有两个可选方法:
- 先升级到2.4.x,重建所有索引,再升级到5.x
- 搭建一个新的5.x集群,使用远程重建索引(reindex-from-remote)直接从1.x集群中导入索引
【本地重建索引】
重建索引最简单的方式是使用Elasticsearch的迁移插件(Migration Plugin),但首先得升级到2.3.x或2.4.x版本
该迁移插件的操作步骤为:
1. 创建一个新索引,索引名为旧索引名后加Elasticsearch版本号,如my_index-2.4.1,拷贝旧索引的映射(mapping)和设置(setting)
新索引上禁止刷新数据(refresh_interval),且将复本数(number_of_replicas)设置为0可提升重建索引的速度
2. 设置旧索引为只读,以确保无新数据写入旧索引
3. 从旧索引里索引(vt.)所有文档到新索引
4. 使用旧索引的refresh_interval和number_of_replicas的值重设新索引,并等待新索引状态变成green
5. 将旧索引上的别名(aliase)指向新索引
6. 删除旧索引
7. 将旧索引名做成新索引的别名,如别名my_index指向新索引my_index-2.4.1
至此,得到一个新的可用于Elasticsearch 5.x集群的2.x索引
【远程重建索引】
如果想直接从1.x集群迁移到5.x,可以使用远程重建索引,搭建一个新的5.x集群,并能够通过REST API访问1.x集群
对每个要迁移到5.x集群的1.x索引,执行以下步骤:
1. 在5.x中,以合适的映射(mapping)和设置(setting)创建一个新索引,并设置refresh_interval为-1、number_of_replicas为0,以加快索引重建
2. 在5.x上,使用_reindex方法从1.x中拉取所有文档,例如:
$ curl -XPOST '' -d '{
"source": {
"remote": { "host": "", "username": "user", "password": "pass" },
"index": "source"
},
"dest": {
"index": "dest"
}
}'
3. 如果将重建任务放置在后台(请求中包含wait_for_completion=false),重建请求会返回一个task_id,可以使用以下请求监控该任务的执行进度:
$ curl -XGET ''
4. 当重建索引完成后,设置新索引的refresh_interval和number_of_replicas为需要的值,默认分别为30(秒)和1
5. (可选)当新索引在5.x集群中完成复制后,即可删除旧索引了
新的5.x集群可以开始时很小,随着索引陆续从1.x迁移到5.x,空出的节点也可在重装Elasticsearch 5.x版本后加入到新集群中
== 关闭Elasticsearch ==
正确地关闭Elasticsearch可确保其能够完成清理工作和关闭重要资源,例如,一个被正确关闭的节点会把自己从集群中移除,同步传输日志(translog)到磁盘,执行其他相关清理操作
如果作为一个服务(service)运行Elasticsearch,可以通过安装包提供的服务管理功能关闭Elasticsearch
用elasticsearch命令直接启动的Elasticsearch,如果运行在控制台(前台),可以发送Ctrl-C关闭,如果以-d选项以守护进程运行,需要发送SIGTERM信号,使用ps或jps命令获得Elasticsearch进程的PID:
$ jps | grep Elasticsearch
如果在启动Elasticsearch时使用了-p选项指定PID文件,也可直接查看该文件获得PID
使用带SIGTERM信号的kill命令关闭Elasticsearch:
$ kill -SIGTERM
【关闭时的致命错误】
在Elasticsearch虚拟机的存活期内,可能发生了某些致命错误,并将虚拟机带入了一个有问题的状态,这些致命错误包括内存溢出错误、虚拟机内部错误和严重的IO错误等
当Elasticsearch发现虚拟机遭遇这些错误时,会尝试在日志文件中记录下这些信息,并停止(halt)虚拟机,当Elasticsearch发起关闭操作时,将不能经历上述的正确关闭,则会返回一个象征这些错误的特殊状态码
JVM内部错误 JVM internal error 128
内存溢出错误 Out of memory error 127
堆栈溢出错误 Stack overflow error 126
未知的虚拟机错误 Unknown virtual machine error 125
严重的IO错误 Serious I/O error 124
未知的致命错误 Unknown fatal error 1
阅读(704) | 评论(0) | 转发(0) |