Elasticsearch 配置详解
ES在默认的配置下就能很好的工作, 只需要很少的配置, 并且大部分的配置都可以在运行的集群上动态设置,
使用使用集群更新API。
配置文件应该包含两部分: node本身的设置(例如node.name
以及 paths) 以及 集群的设置(例如cluster.name
以及 network.host
)。
配置文件的位置
ES有两个配置文件:
elasticsearch.yml
用来配置ES本身log4j2.properties
用来配置ES的日志
这两个文件位于config
文件夹下, 默认在$ES_HOME/config/
. Debian 和 RPM包安装的话, 配置目录位于 /etc/elasticsearch
.
配置目录可以在运行的时候通过path.conf
设置更改:
./bin/elasticsearch -Epath.conf=/path/to/my/config/
配置文件格式
配置文件格式为YAML. 下面以一个例子来展示修改数据和日志的路径:
path:
data: /var/lib/elasticsearch
logs: /var/log/elasticsearch
也可以用下面扁平化的配置:
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
环境变量替换
在配置文件里面使用${...}
来引用环境变量, 例如:
node.name: ${HOSTNAME}
network.host: ${ES_NETWORK_HOST}
提示设置
提示设置, 叫做启动的时候设置 可能更准确一些。对于不想存储在配置文件中的配置, 你可以使用${prompt.text}
或者${prompt.secret}
并且前台启动ES。
${prompt.secret}
不会再终端上显示你输入的内容, 而${prompt.text}
则会把你的输入显示在终端上面。 例如:
node:
name: ${prompt.text}
然后在启动ES的时候, ES会提示你输入真实的值:
Enter value for [node.name]:
如果ES是后台启动的,但是配置文件中使用了
${prompt.text}
或${prompt.secret}
, ES将不会启动。
设置默认设置
新的默认值可以在命令行通过default.
前缀设置。 这个指定的值会被用作默认值, 除非配置文件中配置了。 例如:
./bin/elasticsearch -Edefault.node.name=My_Node
node.name
的值就是 My_Node
, 除非在命令行中使用es.node.name
或者 配置文件中使用node.name
覆盖了此值。
日志配置
ES使用Log4j2
记录日志。 Log4j2可以通过log4j2.properties
来配置。 ES在配置文件中暴露了一个属性${sys:es.logs}
可以用来指定ES的日志, 这个值在运行的时候将被解析为日志文件的前缀。
例如, 如果你的日志目录path.logs
是 /var/log/elasticsearch
并且你的集群名是production
那么${sys:es.logs}
将被解析为/var/log/elasticsearch/production
.
appender.rolling.type = RollingFile
appender.rolling.name = rolling
# /var/log/elasticsearch/production.log
appender.rolling.fileName = ${sys:es.logs}.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %.10000m%n
# /var/log/elasticsearch/production-yyyy-MM-dd.log
appender.rolling.filePattern = ${sys:es.logs}-%d{yyyy-MM-dd}.log
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
如果你在appender.rolling.filePattern
的值上添加.gz
或者.zip
, 日志在滚动的时候会被按照格式压缩。
日志文件可以有多个(加载的时候会被合并)。 只要他们名字为log4j2.properties
并且在ES的config目录的子孙目录下面即可,
这对于一些插件暴露的其他logger很有用。logger
节点包含了java的包以及对应的日志级别。 appender
节点包含了日志的输出目标,
其他关于如何配置logging以及支持的appender可以参考log4j文档.
废弃日志
除了常规的日志, ES还允许指定废弃日志的行为(即用于告诉你哪一项特性将在未来版本中被废弃)。
这个特性可以用于提前确定未来是否需要迁移某些功能。默认情况下废弃日志级别为WARN
,
logger.deprecation.level = warn
这个配置将会在日志目录里创建一个废弃日志文件。 你需要经常检查此文件,尤其当你想升级一个新的主版本的时候。
默认的日志滚动策略是在1GB后压缩, 并且保持5份之日冗余(4份归档后的, 1份当前正在用的)。
可以通过将config/log4j2.properties
配置废弃日志级别为ERROR
.
ES重要配置
尽管ES只需要很少的配置, 但是将ES投入到生产环境之前还是需要人工手动的配置很多属性。主要有:
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
的一个子目录。 如果这些重要的目录
就在默认的位置,当你升级ES版本时很容易把他们删除掉。 所以在生产环境中, 你应该修改这两个目录到其他位置:
path:
logs: /var/log/elasticsearch
data: /var/data/elasticsearch
RPM
以及 Debian
包已经为data
和 logs
使用了自定义路径。
path.data
可以配置为使用多个路径, 这种情况下所有的路径都会用于存储数据(同一个分片的文件会在同一个目录下):
path:
data:
- /mnt/elasticsearch_1
- /mnt/elasticsearch_2
- /mnt/elasticsearch_3
cluster.name
一个节点只有设置自己的cluster.name
与其他节点相同才能加入一个集群。 默认的集群名是elasticsearch
, 但是你应该将此值修改为
描述集群目的的值:
cluster.name: logging-prod
注意集群名没有与其他集群冲突, 否则你可能会加入到错误的集群。
node.name
默认情况下, ES使用随机生成的UUID的前7位作为节点id。 注意节点id会持久化, 节点重启的时候不会改变, 因此默认的节点名也不会改变。
所以最好为node.name
设置一个更有意义的名字。
node.name: prod-data-2
node.name
也可以设置为服务器的hostname:
node.name: ${HOSTNAME}
bootstrap.memory_lock
对于一个节点的健康状态来说,让jvm的内存不被写到磁盘是极其重要的。 达到这个目的的方式之一就是设置bootstrap.memory_lock
为true
.
为了使此设置生效, 需要先配置一些其他系统设置。 详情参考
启用bootstrap.memory_lock
.
network.host
默认情况下, ES仅仅绑定在本地的回环地址(loopback address) - 例如 127.0.0.1
以及 ::1
. 如果在服务器上运行一个开发节点已经足够了。
TIP: 事实上,在同一个服务器节点上的相同的
$ES_HOME
可以启动多个节点。 这个特性可以用来测试ES的集群能力, 但是不推荐用在生产环境。
为了与其他服务器上的节点形成集群通讯, 需要把你的节点上ES绑定到其他非回环地址上。 尽管有很多网络设置
, 但是通常情况下你只需要配置network.host
:
network.host: 192.168.1.10
network.host
配置项还能理解一些其他的特殊值, 比如_local_
,_site_
,_global_
以及其他修饰词例如:ipv4
和 :ipv6
, 更多特殊值可以参考这里
network.host
的特殊值.
Important: 一旦你提供了
network.host
的自定义配置, ES就认为你正在讲开发节点升级为生产环境节点, 然后将一系列系统启动时候的检查由警告升级为异常。
可以看这一章开发模式 VS 生产模式了解更多信息。
discovery.zen.ping.unicast.hosts
ES提供了开箱即用的功能, 在不设置任何网络配置的情况下, ES将绑定在本机可用的回环地址然后扫描本机的9300 - 9305 端口来尝试连接同样运行在本机上的其他ES实例。
这就提供了在不需要任何配置的自动集群的功能。
然而在需要与其他服务器上面的ES实例进行集群的时候, 你需要提供一个种子列表, 这些种子是在集群中的活跃并且可以连接的节点实例。可以如下设置:
discovery.zen.ping.unicast.hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
上面如果不填端口, 则默认是transport.profiles.default.port
和 transport.tcp.port
。
如果主机名可以被解析为多个ip, 那么每个ip都会被尝试连接。
discovery.zen.minimum_master_nodes
为了防止数据丢失, 生产环境下非常有必要配置discovery.zen.minimum_master_nodes
, 告诉ES集群至少有几个master节点可用才能形成集群。
如果没有配置此项, 那么在网络不好的情况下, 集群就存在脑裂的风险 - 一个集群可能会分成两个独立的集群, 这就导致了数据丢失。 更详细的解决方案请参考
使用minimum_master_nodes避免脑裂
为了避免脑裂问题, 这个值应该按照如下规则设置:
(master_eligible_nodes / 2) + 1
即如果集群种有三个master节点, 那么那么最小master节点应该设置为(3 / 2) + 1 = 2
:
discovery.zen.minimum_master_nodes: 2
系统重要配置
理想情况下, ES应该单独运行在一台服务器上面, 尽可能的充分利用服务器上面的资源。 但是默认情况下ES能使用资源有限, 的所以我们需要一些系统级别的配置来使ES
突破默认限制。
在上生产环境之前, 必须配置以下项目:
- 设置jvm堆大小
- 禁用交换内存
- 增加文件描述符
- 保证足够的虚拟内存
- 保证足够的线程
开发模式 VS 生产模式
默认情况下, ES认为工作在开发模式下。 如果上面的任何一项没有配置好, 那么ES会将日志以WARN
级别记录在日志文件。 但是ES实例是可以启动的。
一旦你配置了网络设置, 例如network.host
, ES就会认为工作在了生产模式下, 会将上述的WARN
日志升级为异常。 抛出异常ES的实例就无法启动。
这是一个很重要的安全措施, 保证在错误的配置下不会丢失数据。
配置操作系统设置
如何配置操作系统设置取决于你的ES是用什么方式安装的以及你的操作系统版本。
当使用.zip
以及 .tar.gz
的时候, 系统设置可以在下面的位置配置:
- 临时的
ulimit
. - 永久的
/etc/security/limits.conf
.
如果使用的RPM或者Debian安装包,
大部分的系统设置位于下面说的sysconfig文件中
, 不过如果使用的systemd
来管理服务的, 需要在下面说的sysconfig 文件里面配置。
ulimit
在linux系统, ulimit
命令可以临时修改资源限制。 通常需要先切换到root用户配置好这些限制, 然后切换到elasticsearch用户启动ES。 例如
要设置打开文件的句柄数(ulimit -n
)为65536, 你可以这么做:
//切换为root
sudo su
// 修改句柄数量
ulimit -n 65536
// 切换回elasticsearch用户
su elasticsearch
这个配置只对当前的会话有效。 可以使用 ulimit -a
查看当前的所有限制。
/etc/security/limits.conf
在Linux系统, 可以编辑/etc/security/limits.conf
持久化对每个用户的限制。 例如将elasticsearch用户最大打开的文件句柄数修改为65536, 只需要在
limits.conf
文件加一行:
elasticsearch - nofile 65536
这个修改在elasticsearch用户打开一个新的会话的时候生效。
NOTE. Ubuntu与
limits.conf
, 对于通过init.d
启动起来的进程, ubuntu系统会忽略limits.conf
. 如果要启用这个文件,
需要打开/etc/pam.d/su
然后将下面一行取消注释:
# session required pam_limits.so
sysconfig 文件
当使用RPM以及Debian包的时候, 系统设置以及环境设置可以在下面的文件中配置:
/etc/sysconfig/elasticsearch
RPM/etc/default/elasticsearch
Debian
但是由systemd
管理的服务, 需要通过systemd
来配置。
systemd 配置
systemd的服务描述文件(/usr/lib/systemd/system/elasticsearch.service)包含了默认情况下的限制。
可以通过添加一个文件/etc/systemd/system/elasticsearch.service.d/elasticsearch.conf
来重写这些配置, 例如:
[Service]
LimitMEMLOCK=infinity
设置JVM参数
设置JVM参数比较推荐的方式是修改jvm.options
文件。 此文件的默认位置位于config/jvm.options
(.zip或者tar安装的)
或者/etc/elasticsearch/jvm.options
(RPM或者Debian安装的)。 这个文件包含了以行为分隔符的jvm配置,每行都要以-
开头。
你可以自定义JVM参数, 并且将此文件放在版本管理系统中(git/svn)。
另外一种设置JVM参数的方式就是通过环境变量ES_JAVA_OPTS
来设置:
export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
./bin/elasticsearch
当使用RPM或者Debian的时候, ES_JAVA_OPTS
可以通过上面说的方式设置。
continue: https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html
Q.E.D.