Elasticsearch 带有大量的设置和配置,甚至可能让专家工程师感到困惑。 尽管它使用约定优于配置范例并且大部分时间使用默认值,但在将应用程序投入生产之前自定义配置是必不可少的。
在这里,我们将介绍属于不同类别的一些属性,并讨论它们的重要性以及如何调整它们。 我们可以调整三个配置文件:
- elasticsearch.yml - 这个配置文件是最常编辑的,我们可以在其中设置集群名称、节点信息、数据和日志路径,以及网络和安全设置。
- log4j2.properties - 让我们设置 Elasticsearch 节点的日志记录级别。
- jvm.options - 这里我们可以设置运行节点的堆内存。
这些文件位于 Elasticsearch 安装的如下目录中:
$ pwd
/Users/liuxg/elastic/elasticsearch-8.6.1
$ tree config/ -L 2
config/
├── certs
│ ├── http.p12
│ ├── http_ca.crt
│ └── transport.p12
├── elasticsearch-plugins.example.yml
├── elasticsearch.keystore
├── elasticsearch.yml
├── jvm.options
├── jvm.options.d
├── log4j2.properties
├── role_mapping.yml
├── roles.yml
├── users
└── users_roles
这些文件由 Elasticsearch 节点从 config 目录中读取,该目录基本上是 Elasticsearch 安装目录下的一个文件夹。 对于二进制(zip 或 tar.gz)安装,此目录默认为 $ES_HOME/config(ES_HOME 变量指向 Elasticsearch 的安装目录)。 如果你使用 Debian 或 RPM 发行版等包管理器进行安装,则情况会有所不同,默认为 /etc/elasticsearch/config。
如果你希望从不同的目录访问你的配置文件,你可以设置并导出一个名为 ES_PATH_CONF 的路径变量,它指向新的配置文件位置。 在接下来的几个小节中,我们将介绍一些需要理解的重要设置,不仅对管理员如此,对开发人员也是如此。
主配置文件
尽管 Elastic 的人们开发了 Elasticsearch 以使用默认值(约定优于配置)运行,但我们在将节点投入生产时不太可能依赖默认值。 我们应该调整属性以设置特定的网络信息、数据或日志路径、安全方面等。 为此,我们可以修改 elasticserch.yml 文件以设置我们正在运行的应用程序所需的大部分属性。
Elasticsearch 将网络属性公开为 network.* 属性。 我们可以使用此属性设置主机名和端口号。 例如,我们可以将 Elasticsearch 的端口号更改为 9900 而不是保留默认端口 9200:http.port :9900。 如果要更改节点内部通信的端口,也可以设置 transport.port。
根据你的要求,你可能需要更改许多属性。 如果你想详细了解这些属性,请参阅官方文档:Networking | Elasticsearch Guide [8.6] | Elastic
如果你想设置自己的 Elasticsearch 能被外部访问而不是以 localhost 的方式访问,你可以更改如下的设置:
network.host: 192.168.0.1
在上面,我们设置为电脑的私有地址,这样它可以被所在的局域网所访问。我们也可以这样设置:
network.host: 0.0.0.0
这样 Elasticsearh 会绑定于所有的 IP 接口上。我们通常可以使用如下的方式来得到所有的 IP:
ifconfig | grep inet
$ ifconfig | grep inet
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet6 fe80::acbc:f2ff:fe5e:d6e9%anpi0 prefixlen 64 scopeid 0x4
inet6 fe80::acbc:f2ff:fe5e:d6eb%anpi2 prefixlen 64 scopeid 0x5
inet6 fe80::acbc:f2ff:fe5e:d6ea%anpi1 prefixlen 64 scopeid 0x6
inet6 fe80::f4d4:88ff:fe6a:c36d%ap1 prefixlen 64 scopeid 0xe
inet6 fe80::c6b:334b:459e:a8fb%en0 prefixlen 64 secured scopeid 0xf
inet 192.168.0.101 netmask 0xffffff00 broadcast 192.168.0.255
inet6 fe80::a082:13ff:fe68:d82f%awdl0 prefixlen 64 scopeid 0x10
inet6 fe80::a082:13ff:fe68:d82f%llw0 prefixlen 64 scopeid 0x11
inet6 fe80::1699:5325:c1de:b41%utun0 prefixlen 64 scopeid 0x12
inet6 fe80::ce81:b1c:bd2c:69e%utun1 prefixlen 64 scopeid 0x13
inet6 fe80::c22c:882d:15c7:d083%utun2 prefixlen 64 scopeid 0x14
inet6 fe80::10cf:86ce:6771:979%en4 prefixlen 64 secured scopeid 0x1a
inet 192.168.0.3 netmask 0xffffff00 broadcast 192.168.0.255
如上所示,当我们设置 network.host 为 0.0.0.0 时,它绑定于上面所示的 127.0.0.1 及 192.168.0.3 及 192.168.0.101 上。除上面的配置之前,我们也可以使用如下的定义:
定义 | 描述 |
---|---|
_local_ | 系统上的任何 loopback 地址,例如 127.0.0.1。 |
_site_ | 系统上的任何站点本地地址,例如 192.168.0.1。这样我们就不用硬编码私有地址 |
_global_ | 系统上任何全局范围的地址,例如 8.8.8.8。 |
配置文件格式
配置格式为 YAML。 以下是更改数据和日志目录路径的示例:
path:
data: /var/lib/elasticsearch
logs: /var/log/elasticsearch
设置也可以展平如下:
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
在 YAML 中,你可以将非标量值格式化为序列:
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
虽然不太常见,但你也可以将非标量值格式化为数组:
discovery.seed_hosts: ["192.168.1.10:9300", "192.168.1.11", "seeds.mydomain.com"]
环境变量替换
配置文件中用 ${...} 表示法引用的环境变量将替换为环境变量的值。 例如:
node.name: ${HOSTNAME}
network.host: ${ES_NETWORK_HOST}
环境变量的值必须是简单的字符串。 使用逗号分隔的字符串提供 Elasticsearch 将解析为列表的值。 例如,Elasticsearch 会将以下字符串拆分为 ${HOSTNAME} 环境变量的值列表:
export HOSTNAME="host1,host2"
日志记录选项
Elasticsearch 是用 Java 开发的,与大多数 Java 应用程序一样,Elasticsearch 使用 Log4j 2 作为其日志记录库。 一个正在运行的节点将 INFO 级别的日志信息输出到控制台和文件(分别使用 Kibana 控制台和 RollingFile Appenders)。
Log4j 属性文件 (log4j2.properties) 包含一些系统变量(sys:es.logs.base_path、sys:es.logs.cluster_name 等),这些变量在应用程序运行时解析。 因为这些属性由 Elasticsearch 公开,所以它们可供 Log4j 使用,这让 Log4j 可以设置其日志文件目录位置、日志文件模式和其他属性。 例如 sys:es.logs.base_path 指向 Elasticsearch 写入日志的路径,解析为 $ES_HOME/logs 目录。
默认情况下,大部分 Elasticsearch 运行在 INFO 级别,但我们可以根据单个包自定义设置。 例如,我们可以编辑 log4j2.properties 文件并为索引包添加一个记录器,如下面的清单所示。
设置特定包的日志记录级别:
logger.index.name = org.elasticsearch.index
logger.index.level = DEBUG
通过这样做,我们允许 index package 在 DEBUG 级别输出日志。 我们可以在集群级别设置 DEBUG 日志级别,而不是在特定节点上编辑此文件并重新启动该节点(如果你在创建群之前没有设法这样做,则可能需要为每个节点执行此操作) 对于这个包。 下一个清单演示了此设置:
全局设置临时日志级别:
PUT _cluster/settings
{
"transient": { #A
"logger.org.elasticsearch.index":"DEBUG" #B
}
}
如查询所示,我们在 transient 块中将 index 包的记录器级别属性设置为 DEBUG。 transient block 表示该属性不持久(仅在集群启动并运行时可用)。 如果我们重启集群或者它崩溃了,设置就会丢失,因为它没有永久存储在磁盘上。
我们可以通过调用集群设置 API (_cluster/settings) 来设置此属性,如清单中的代码所示。 设置此属性后,将在 DEBUG 级别输出与 org.elasticsearch.index 源包中的索引相关的任何进一步日志记录信息。
Elasticsearch 也提供了一种持久存储集群属性的方法。 如果我们需要永久存储属性,我们可以使用 persistent 块。 以下清单用持久块替换了 transient 块。
永久设置日志级别:
PUT _cluster/settings
{
"persistent": {
"logger.org.elasticsearch.index":"DEBUG",
"logger.org.elasticsearch.http":"TRACE"
}
}
此代码在 org.elasticsearch.index 包上设置 DEBUG 级别,在 org.elasticsearch.http 包上设置 TRACE 级别。 因为两者都是持久属性,所以记录器会按照包上设置的这些级别写入详细的日志,这些级别也会在集群重新启动后继续存在。
请注意使用 persistent 属性永久设置的此类属性。 我的建议是在故障排除或调试期间启用日志记录级别 DEBUG 或 TRACE。 当你完成生产中的 “救火” 情节时,将其重置回 INFO 以避免将大量请求写入磁盘。
更多阅读,请参考文章 “Elastic:配置 Elasticsearch 服务器 logs”。
JVM 选项
因为 Elasticsearch 使用 Java 编程语言,所以可以在 JVM 级别进行大量优化调整。 出于显而易见的原因,在本文中讨论如此庞大的话题是不够公正的。 但是,如果你很好奇并想了解 JVM 的本质或想在较低级别微调性能,请参阅 Optimizing Java(Ben Evan 和 Jame Gough)或 Java Performance(Scott Oaks)等书籍。 我强烈推荐它们,因为它们不仅提供基础知识,还提供操作提示和技巧。
Elasticsearch 在 /config 目录中提供了一个 jvm.options 文件,其中包含 JVM 设置。 但是,此文件仅供参考(例如,检查节点的内存设置),不得编辑。 根据节点的可用内存,为 Elasticsearch 服务器自动设置堆内存。
警告:在任何情况下我们都不应该编辑 jvm.options 文件。 这样做可能会破坏 Elasticsearch 的内部运作。
如果我们想要升级内存或更改任何 JVM 设置,我们必须创建一个以 .options 作为文件扩展名的新文件,提供适当的调整参数,并将该文件放在 config 下一个名为 jvm.options.d 的目录中以便以存档形式进行安装(tar 或 zip)。 我们可以为我们的自定义文件指定任何名称,但我们需要在其文件名中包含固定的 .options 扩展名。
对于 RPM/Debian 软件包安装,此文件应位于 /etc/elasticsearch/jvm.options.d/ 目录下。 同样,将选项文件挂载在 /usr/share/elasticsearch/config 文件夹下以进行 Docker 安装。
我们可以编辑这个自定义 JVM 选项文件中的设置。 例如,要升级名为 jvm_custom.options 的文件中的堆内存,我们可以使用以下清单中的代码。
升级堆内存:
# Setting the JVM heap memory in jvm_custom.options file
-Xms4g
-Xmx4g
_Xms 标志设置初始堆内存,而 _Xmx 调整最大堆内存。 不成文的规则是不要让 _Xms 和 _Xmx 设置超过节点总 RAM 的 50% 以上。 在引擎盖下运行的 Apache Lucene 将内存的后半部分用于其分段、缓存和其他进程。