/usr/share/elasticsearch/config
必须挂载出来,才方便自定义配置,
应该绑定挂载 /usr/share/elasticsearch/data
,原因如下:
首先配置文件 config 下必须为可读,若还要挂载其他的文件,也必须可读,所以 docker cp 之后 root 修改权限,然后再建立挂载即可。
此时多考虑为 es 分配的资源不够导致的,一般所用堆的大小至少要上 G,建议大小堆设置为等大,占用可用内存的一半。
两个堆大小应该一致,且不能超过可用内存的 50%,因为 es 的其他工作也需要消耗一定内存。
es 可用的堆越大,可以用于内部缓存的内存就越多,反之,留给其他工作的内存就越小,所以堆的设置并不是越大越好。比如,当堆过大的时候,甚至 es 的垃圾清理工作也会停止。
/usr/share/elasticsearch/config/jvm.options.d
,其中包含您所需的堆大小设置,默认是 1G,修改配置文件后就会覆盖。ES_JAVA_OPTS
环境变量来设置堆大小来配置它。例如,要使用 16 GB 可以指定 -e ES_JAVA_OPTS="-Xms16g -Xmx16g"
。docker run 时指定 ES_JAVA_OPTS 会覆盖配置文件。- Xms2g
- Xmx2g
es log 报错:
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
这是因为 es 默认使用 mmapfs 目录来存储 index,操作系统(主要是 linux)默认对 mmapfs 的设置太低了(65530),所以需要特意设置一下,防止内存不足。
linux 下修改 /etc/sysctl.conf
文件,添加 vm.max_map_count=262144
sysctl vm.max_map_count
永久生效即可。
设置后,es docker 稳定在线。
es 集群需要 docker compose 配置,若简单地建立单节点集群,可以指定单节点 discovery, -e "discovery.type=single-node"
docker run -it --name eslxd -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -p 9201:9200 -p 9301:9300 elasticsearch:7.7.0
为什么要设置单节点启动 es?
es 设计本身就是多节点集群的,多节点之间的配合尤为重要,尤其是生产环境。因此,es 有引导用户检查自己 es 配置信息的流程,若想跳过这些引导,就可以设置为单节点启动。
只有节点的 cluster.name 一致的时候,这些节点才会加入这个 cluster。默认的名字是 elasticsearch。另一方面,当集群和节点很多时,应注意 cluster.name 不会写错,否则集群中的节点就会错误。
默认情况下,es 只绑定到回环地址,如果在不同服务器的节点想形成集群,那么 network.host 应该特殊配置,比如 192.168.1.10 等。一旦 network.host 被自定义配置,es 就认为你已经从开发模式切换到生产环境中,因此系统启动过程中的一些检查,就从 warning 变成 exception 报错。
部署到生产环境前,下面这几项必须要正确配置:
noexec
一开始 es 默认是开发模式,所以只会提 warning;若 er 认为当前是生产模式,就会相应报错,无法启动。
Es 将绑定到可用的环回地址,并将扫描本地端口 9300 到 9305 以尝试连接到同一服务器上运行的其他节点。这提供了自动集群体验,而无需进行任何配置。
当与其他主机上的节点形成集群时,应该使用 discovery.seed_hosts
设置来提供集群中其他节点的列表。此设置应该是集群中所有符合主节点条件的节点的地址列表。每个地址可以是 IP 地址或主机名,通过 DNS 解析为一个或多个 IP 地址
第一次启动 es 集群的时候,有一个引导步骤来选择主节点。如果在开发模式,这个步骤会由节点自动执行。但是在生产模式下,需要自定义配置明确指定主节点。重启集群或者为现有集群添加节点时不需要再次设置。
es 使用很多的 file descriptors 和 file handles,如果用完就出错。所以尽可能将其设置为最大 65535(linux 和 Mac),可以在 /etc/security/limits.conf
中设置 nofile 为 65535。
* - nofile 65535
可以使用如下命令,查询某节点的最大描述符数量。我使用这个命令查询之后,发现是 1048576,比 65535 大 16 倍,所以不需要设置?还是 es 7.7.0 docker 镜像下来自带的设置就比较大?
# 查询
GET _nodes/stats/process?filter_path=**.max_file_descriptors
# 结果
{
"nodes" : {
"YcMqqwP1RX2zARKp_9Q7Ww" : {
"process" : {
"max_file_descriptors" : 1048576
}
}
}
}
大多数操作系统尝试将尽可能多的内存用于文件系统缓存,并急切地交换未使用的应用程序内存。这可能导致部分 JVM 堆甚至其可执行页面被换出到磁盘。
交换对性能和节点稳定性非常不利,应该不惜一切代价避免。它可能导致垃圾收集持续几分钟而不是几毫秒,并且可能导致节点响应缓慢甚至与集群断开连接。在弹性分布式系统中,让操作系统杀死节点更有效。
有三种方法可以禁用交换。首选选项是完全禁用交换。如果这不是一个选项,是否更喜欢最小化交换与内存锁定取决于您的环境。
通常 es 独立运行在一个服务器或 docker 中,它的内存使用由 JVM 来控制,不需要 swap。
Linux 下临时使 swap 失效,可以:
sudo swapoff -a
永久失效可以编辑 /etc/fstab
文件,将带有 swap 字样的行都注释掉。
es 消耗线程较大,至少要 4096。可以通过配置文件设置,在 /etc/security/limits.conf
中设置 nproc 为 4096。
* - nproc 65535
初始堆和最大堆,两个堆大小应该一致,否则影响效率。如果两个堆大小不一致,es 过程中可能会动态调整堆的大小,调整过程就很容易暂停。
当JVM执行主要的垃圾收集时,它会触及堆的每一页。如果这些页面中的任何一个被交换到磁盘,它们将不得不被交换回内存。这会造成大量的 disk thrashing。如果设置为不允许交换 swap,那么这里问题不大。如果需要设置,那么修改 bootstrap.memory_lock。
就是前面的虚拟内存,为了有效地使用mmap,Elasticsearch还需要能够创建许多内存映射区域。最大映射计数检查检查内核是否允许进程至少有262144个内存映射区域,并且仅在Linux上强制执行。要通过最大映射计数检查,必须配置至少为 262144。
在 /etc/security/limits.conf
中设置 fsize 为 unlimited。
* - fsize unlimited