Lain's Blog

Elasticsearch配置及优化

环境变量

在es启动脚本里(elasticsearch.in.sh或elasticsearch.in.bat),内置了传递给JVM的启动参数JAVA_OPTS。其中最重要的参数是 -Xmx 和 -Xms,分别用来控制分配给es进程的最大内存、最小内存。(一般来说内存越多越好)

通常来说,JAVA_OPTS使用默认值不要修改,而是通过ES_JAVA_OPTS环境变量来设置和修改JVM配置参数。

ES_HEAP_SIZE环境变量用来设置分配给es的java进程的堆内存,设置了ES_HEAP_SIZE变量它也会同事设置最小、最大内存。也可以单独分别设置ES_MIN_MEM、ES_MAX_MEM参数来决定分配的最小、最大内存。

推荐最小、最大内存设置成相同值,并且打开mlockall开关。

系统配置

文件描述符(File Description)

确保把机器的(或当前运行es用户的)打开文件描述符数量设置成32k或者推荐的64k。
设置完成后,可以通过增加 -Des.max-open-files=true启动参数,打印出进程能打开的文件数,测试是否生效。
或者通过Nodes Info Api来获取max_file_descriptors参数:

1
curl localhost:9200/_nodes/process?pretty

虚拟内存(Virtual memory)

es默认使用 hybrid mmapfs / niofs 目录来存储索引。默认操作系统对mmap技术的限制太低,可能引发内存不足的异常。在Linux中,可以通过root账户运行下面的明亮来放开限制:

1
sysctl -w vm.max_mapcount=262144

永久生效需要更新系统文件 /etc/sysctl.conf 的 vm.max_map_count 字段。
如果是通过deb或是rpm包安装的话,会自动更新这个设置,可以通过下面的命令查看:

1
sysctl vm.max_map_count

内存设置

大部分的操作系统会对文件系统使用尽可能多的内存,并且容易换出一些未使用的应用内存,导致es进程内存被换出。这种操作对性能和节点的稳定性影响很大,应尽量避免。避免方法如下:

关闭swap

这是最简单的方法。因为通常来说,es是机器上面唯一的服务,它的内存使用由ES_HEAP_SIZE环境变量来控制,没有必要打开swap。

在linux系统,可以通过运行 sudo swapoff -a 命令来临时关闭swap。如果想永久关闭,需要修改 /etc/fstab 文件,注释掉swap的相关配置。

在windows系统,可以通过系统属性->高级->性能->高级->虚拟内存 来关闭分页文件

配置swappiness

通过设置使得sysctl 的 vm.swappiness 为0。这会减少内核交换操作,在通过情况下不会触发swapping,除非在紧急情况下。

注意:从内核版本3.5-rc1开始,swappiness为0将导致OOM killer杀死进程而不是允许交换。你必须把swappiness设为1,使得在紧急情况下可以swapping。

mlockcall

通过使用Linux的 mlockcall 或者 Windows的VirtualLock来把进程地址空间锁在内存里面,防止es的内存被换出。通过配置文件 config/elasticsearch.yml 中增加如下配置:

1
bootstrp.mlockall: true

启动es后,你可以观察这个设置是否生效,通过以下放大检查mlockall:

1
curl http://localhost:9200/_nodes/process?pretty

如果mlockall为false,则mlockcall失败。最可能的原因是,在Linux/Unix系统中,运行es的用户没有权限来锁住内存,需要在启动es前铜鼓root账户运行 ulimit -l unlimited。

另一个可能的原因是,临时目录(通常是/tmp)被以 noexec 情况下挂载,需要通过以下方法重新指定一个临时目录:

1
./bin/elasticsearch -Djna.tmpdir=/path/to/new/dir

警告: mloackall可能导致JVM或者shell退出,如果尝试分配多余可用内存的空间。

elasticsearch 配置

es配置文件在ES_HOME/config目录下面。elasticsearch.yml用于配置es的不同模块,logging.yml用于配置es的日志。
配置文件格式是YAML。下面是一个用于绑定和发布的网络模块的配置:

1
2
network:
host: 10.0.0.4

Paths(路径)

在使用过程中,一般会改变数据和日志的存放路径

1
2
3
path:
logs: /var/log/elasticsearch
data: /var/data/elasticsearch

Cluster name(集群名)

记住要设置集群名,集群名用于发现和自动连接其他节点:

1
2
cluster:
name: 集群名

确保不要在不同的环境使用相同的集群名,否则将导致节点连接进错误的集群。例如:
你可以分别使用logging-dev,logging-stage,logging-prod作为开发、测试、正式发布集群。

Node name(节点名)

你可能需要修改默认的节点名,比如修改成主机名。如果没有设置的话,es将从3000个名字中随机选一个作为节点名。

1
2
node:
name: <节点名>

极其的主机名存于环境变量HOSTNAME中。如果集群中,你只运行单节点的es服务,可以把节点设置成主机名:

1
2
node:
name: ${HOSTNAME}

在内部,所有设置都变成基于命名空间的设置。例如,上述节点配置编程node.name。这意味着可以很容易支持一些其他配置格式,如JSON。如果要使用json配置,只要把elasticsearch.yml文件改成elasticsearch.json并添加:
配置格式:

1
2
3
4
5
{
"network": {
"host": "10.0.0.4"
}
}

也可以很容易地通过外部采纳数ES_JAVA_OPT或者elasticsearch启动参数来设置,例如:

1
$ elasticsearch -Des.network.host=10.0.0.4

另外一种选项是设置 es.default. 前缀来代替 es. 前缀,这样使得默认配置只有当前配置文件中没有明确设置时才生效。
另外一种选项是在配置文件中使用 $(…) 符号,这些符号与环境设置中变量相对应的,例如:

1
2
3
4
5
{
"network": {
"host": "${ES_NET_HOST}"
}
}

另外,如果你不想把一些参数保存在配置文件中,你可以使用${prompt.text} 或者 ${prompt.secret},然后前台重启es。${prompt.text}会被显示出来,例如:

1
2
node:
name: ${prompt.text}

在启动es时,你需要输入对应的值:

1
Enter value for [node.name]:

说明: 如果配置中使用了${prompt.text} 或者 ${prompt.secret}, es就不能以服务或者后台启动的方式运行。

索引配置

集群中的索引可以有自己的配置。例如,一下语句创建一个基于内存的索引,而不是默认基于文件的(可以是YAML或者JSON格式):

1
2
3
4
5
$ curl -XPUT http://localhost:9200/kimchy/ -d \
'
index :
refresh_interval: 5s
'

索引级配置也可以在节点上设置,例如,在elasticsearch.yml文件中,可以配置如下:

1
2
index:
refresh_interval: 5s

这表明这个节点上创建的索引都是存储在内存中的,除非重新设置。换句话说,索引级配置会覆盖节点级配置。当然上面也可以使用这种格式的配置:

1
$ elasticsearch -Des.indexrefresh_interval=5s

所有索引级配置都可以在每个索引模块中找到。

日志配置

es使用一种内部日志,有点儿像log4j。它通过使用YAML简化了log4j配置,配置文件中config/logging.yml.支持JSON和属性格式。可以加载多个配置文件,只要文件以logging. 前缀开头以.yml,.yaml, .json或者.properties结尾,它们将被合并。logger段中包含了java包和相应的日志级别,可以忽略org.elasticsearch前缀。appender段中包含日志的路径。更多资料在log4j.documentation.
其它Appenders和其他的log4j-extras提供的日志类也可用。

废弃日志

除了正常日之外,es也允许打开已经弃用的行为日志,默认这个日志是关闭的。可以通过config/loggin.yml文件中的日志级别设置成DEBUG来打开:

1
deprecation: DEBUG, deprecation_log_file

这将在日志记录下生成一个每天滚动的日志。定期检查这个文件,特鄙视准备升级到新版本的时候。

扫二维码
扫一扫,用手机访问本站

扫一扫,用手机访问本站