MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

ElasticSearch启动脚本的编写与优化

2021-02-024.1k 阅读

ElasticSearch 启动脚本的编写基础

了解 ElasticSearch 启动需求

ElasticSearch 是一个基于 Lucene 的分布式搜索和分析引擎,它运行在 Java 虚拟机(JVM)之上。要编写有效的启动脚本,首先要明白 ElasticSearch 启动所需的环境和参数。

ElasticSearch 依赖 Java 环境,因此在启动脚本中,必须确保 Java 路径正确设置。此外,ElasticSearch 自身也有一系列可配置的参数,如集群名称、节点名称、数据目录、日志目录等。这些参数对于 ElasticSearch 的正常运行以及性能优化都至关重要。

编写简单的启动脚本(以 Linux 为例)

以下是一个简单的 ElasticSearch 启动脚本示例,假设 ElasticSearch 安装在 /usr/local/elasticsearch 目录下:

#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

在这个脚本中:

  1. 首先定义了 ES_HOME 变量,指定 ElasticSearch 的安装路径。
  2. 然后设置 JAVA_HOME 变量,确定 Java 的安装位置,并将 Java 路径添加到系统 PATH 中,确保系统能找到 Java 可执行文件。
  3. 进入 ElasticSearch 安装目录后,使用 ./bin/elasticsearch -d 命令启动 ElasticSearch,-d 参数使 ElasticSearch 在后台运行,不占用当前终端会话。

ElasticSearch 启动脚本的配置参数优化

内存参数优化

ElasticSearch 对内存的使用非常敏感,合理配置内存参数能显著提升性能。主要涉及的参数是 ES_HEAP_SIZE,它用于设置 JVM 堆内存大小。

一般建议将堆内存的最小值(Xms)和最大值(Xmx)设置为相同的值,以避免 JVM 在运行过程中频繁调整堆内存大小。例如,如果服务器有 16GB 内存,且 ElasticSearch 是该服务器上唯一运行的主要应用,可以考虑将堆内存设置为 8GB。

在启动脚本中,可以通过修改环境变量来设置内存参数,如下所示:

#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

集群和节点参数优化

  1. 集群名称(cluster.name):集群名称用于标识 ElasticSearch 集群,同一集群中的所有节点必须使用相同的集群名称。在启动脚本中,可以通过设置 ES_JAVA_OPTS 环境变量来指定集群名称:
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_cluster"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d
  1. 节点名称(node.name):节点名称用于在集群中唯一标识每个节点。可以在启动脚本中动态生成节点名称,例如结合主机名:
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_cluster -Des.node.name=$(hostname)-es-node"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

数据和日志目录参数优化

  1. 数据目录(path.data):默认情况下,ElasticSearch 将数据存储在安装目录下的 data 子目录中。在生产环境中,建议将数据目录设置到专用的磁盘分区上,以提高 I/O 性能。可以通过修改启动脚本中的 ES_JAVA_OPTS 来指定数据目录:
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_cluster -Des.node.name=$(hostname)-es-node -Des.path.data=/var/lib/elasticsearch/data"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d
  1. 日志目录(path.logs):同样,日志目录也可以进行调整。将日志目录设置到独立的分区有助于管理日志文件,避免因日志文件过大导致系统盘空间不足。修改启动脚本如下:
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_cluster -Des.node.name=$(hostname)-es-node -Des.path.data=/var/lib/elasticsearch/data -Des.path.logs=/var/log/elasticsearch"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

ElasticSearch 启动脚本的高级特性

监控和健康检查

为了确保 ElasticSearch 成功启动并正常运行,可以在启动脚本中添加监控和健康检查机制。一种常见的方法是使用 ElasticSearch 的 REST API 来检查集群的健康状态。

可以使用 curl 命令来实现这一功能。以下是在启动脚本中添加健康检查的示例:

#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_cluster -Des.node.name=$(hostname)-es-node -Des.path.data=/var/lib/elasticsearch/data -Des.path.logs=/var/log/elasticsearch"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

# 等待 ElasticSearch 启动
sleep 10

# 检查集群健康状态
health_status=$(curl -s -XGET 'http://localhost:9200/_cluster/health?pretty' | grep '"status"' | awk '{print $2}' | tr -d '"')

if [ "$health_status" == "green" ] || [ "$health_status" == "yellow" ]; then
    echo "ElasticSearch 已成功启动,集群健康状态:$health_status"
else
    echo "ElasticSearch 启动失败,集群健康状态:$health_status"
    # 这里可以添加停止 ElasticSearch 的逻辑
    #./bin/elasticsearch -s stop
fi

在这个脚本中:

  1. 启动 ElasticSearch 后,使用 sleep 10 命令等待 10 秒钟,确保 ElasticSearch 有足够的时间启动并初始化。
  2. 然后使用 curl 命令通过 ElasticSearch 的 REST API 获取集群健康状态。
  3. 根据返回的健康状态进行判断,如果是 greenyellow,表示启动成功;否则表示启动失败,并可以选择添加停止 ElasticSearch 的逻辑。

自动化启动和停止管理

  1. 使用 systemd(适用于现代 Linux 系统):systemd 是 Linux 系统中常用的初始化系统,它可以管理系统服务的启动、停止、重启等操作。要将 ElasticSearch 配置为 systemd 服务,可以创建一个服务单元文件,例如 /etc/systemd/system/elasticsearch.service
[Unit]
Description=ElasticSearch
Documentation=http://elastic.co
After=network.target

[Service]
ExecStart=/usr/local/elasticsearch/bin/elasticsearch -p /var/run/elasticsearch.pid -d
ExecStop=/bin/kill -s TERM $(cat /var/run/elasticsearch.pid)
ExecReload=/bin/kill -s HUP $(cat /var/run/elasticsearch.pid)
Restart=always
RestartSec=5
User=elasticsearch
Group=elasticsearch
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

在这个服务单元文件中:

  • Description 描述了服务的信息。
  • After 表示该服务在网络服务启动后启动。
  • ExecStart 定义了启动 ElasticSearch 的命令,包括生成进程 ID 文件和以守护进程方式启动。
  • ExecStop 定义了停止 ElasticSearch 的命令,通过进程 ID 发送终止信号。
  • ExecReload 定义了重启 ElasticSearch 的命令,通过进程 ID 发送 HUP 信号。
  • Restart 设置为 always,表示如果服务意外终止,自动重启。
  • UserGroup 指定了运行 ElasticSearch 的用户和组,需要确保该用户和组有适当的权限。
  • LimitNOFILE 设置了允许打开的文件描述符数量,以满足 ElasticSearch 的需求。

创建好服务单元文件后,使用以下命令管理 ElasticSearch 服务:

  • sudo systemctl start elasticsearch:启动 ElasticSearch 服务。
  • sudo systemctl stop elasticsearch:停止 ElasticSearch 服务。
  • sudo systemctl restart elasticsearch:重启 ElasticSearch 服务。
  • sudo systemctl enable elasticsearch:设置 ElasticSearch 服务开机自启。
  • sudo systemctl disable elasticsearch:取消 ElasticSearch 服务开机自启。
  1. 使用 init.d(适用于较旧的 Linux 系统):对于不支持 systemd 的较旧 Linux 系统,可以使用传统的 init.d 脚本。以下是一个简单的 init.d 脚本示例,保存为 /etc/init.d/elasticsearch
#!/bin/bash
### BEGIN INIT INFO
# Provides:          elasticsearch
# Required-Start:    $local_fs $network
# Required-Stop:     $local_fs $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/stop ElasticSearch
### END INIT INFO

ES_HOME=/usr/local/elasticsearch
ES_USER=elasticsearch
ES_GROUP=elasticsearch

case "$1" in
    start)
        su - $ES_USER -c "$ES_HOME/bin/elasticsearch -d"
        ;;
    stop)
        pid=$(ps -ef | grep elasticsearch | grep -v grep | awk '{print $2}')
        if [ -n "$pid" ]; then
            kill -TERM $pid
        fi
        ;;
    restart)
        $0 stop
        sleep 5
        $0 start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac

exit 0

在这个 init.d 脚本中:

  • 开头的 ### BEGIN INIT INFO### END INIT INFO 部分定义了服务的基本信息,如启动和停止的依赖、默认启动和停止的运行级别等。
  • case 语句根据传入的参数(startstoprestart)执行相应的操作。
  • start 操作使用 su 命令以指定用户身份启动 ElasticSearch。
  • stop 操作通过查找 ElasticSearch 进程的 PID 并发送终止信号来停止服务。
  • restart 操作先停止服务,等待 5 秒钟后再启动服务。

要使用这个 init.d 脚本管理 ElasticSearch 服务,需要给脚本添加可执行权限:sudo chmod +x /etc/init.d/elasticsearch。然后可以使用以下命令:

  • sudo /etc/init.d/elasticsearch start:启动 ElasticSearch 服务。
  • sudo /etc/init.d/elasticsearch stop:停止 ElasticSearch 服务。
  • sudo /etc/init.d/elasticsearch restart:重启 ElasticSearch 服务。

还可以使用 chkconfig 工具来设置开机自启:

  • sudo chkconfig --add elasticsearch:添加 ElasticSearch 服务到开机自启列表。
  • sudo chkconfig elasticsearch on:设置 ElasticSearch 服务开机自启。
  • sudo chkconfig elasticsearch off:取消 ElasticSearch 服务开机自启。

ElasticSearch 启动脚本的故障排查与优化实践

常见启动故障及排查方法

  1. Java 环境问题:如果 ElasticSearch 启动时提示找不到 Java 命令,首先要检查 JAVA_HOME 环境变量是否正确设置。可以在启动脚本中添加输出 JAVA_HOME 的语句,例如:
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 输出 JAVA_HOME 路径,用于排查
echo "JAVA_HOME is set to: $JAVA_HOME"

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_cluster -Des.node.name=$(hostname)-es-node -Des.path.data=/var/lib/elasticsearch/data -Des.path.logs=/var/log/elasticsearch"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

此外,还要确保 Java 版本符合 ElasticSearch 的要求。不同版本的 ElasticSearch 对 Java 版本有不同的支持,例如 ElasticSearch 7.x 通常支持 Java 11 及以上版本。

  1. 内存配置问题:如果 ElasticSearch 启动时出现内存不足的错误,如 java.lang.OutOfMemoryError,可能是堆内存设置不合理。可以通过查看 ElasticSearch 的日志文件(位于 path.logs 目录下)来获取详细的错误信息。如果堆内存设置过小,可以适当增加 ES_HEAP_SIZE 的值;如果设置过大,可能会导致系统内存不足,影响其他进程运行,需要根据服务器实际内存情况进行调整。

  2. 网络问题:ElasticSearch 通过网络进行节点间通信和对外提供服务。如果启动后无法通过 REST API 访问,可能是网络端口被占用或防火墙设置问题。首先检查 ElasticSearch 配置文件(config/elasticsearch.yml)中绑定的 IP 地址和端口号,默认情况下,ElasticSearch 绑定到 localhost:9200 对外提供 REST API 服务,绑定到 localhost:9300 进行节点间通信。可以使用 netstat 命令检查端口是否被占用,例如:

netstat -tlnp | grep 9200

如果端口被占用,需要停止占用该端口的进程或修改 ElasticSearch 的端口配置。同时,确保服务器的防火墙允许 ElasticSearch 相关端口的通信。在 Linux 系统上,可以使用 iptablesfirewalld 等工具来配置防火墙规则。例如,使用 firewalld 开放 9200 和 9300 端口:

sudo firewall-cmd --zone=public --add-port=9200/tcp --permanent
sudo firewall-cmd --zone=public --add-port=9300/tcp --permanent
sudo firewall-cmd --reload

优化实践案例

假设在一个拥有 32GB 内存的服务器上部署 ElasticSearch 集群,有三个节点。为了优化性能,进行如下启动脚本配置:

  1. 节点 1 的启动脚本
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 12GB
export ES_HEAP_SIZE=12g

# 设置集群名称为 my_production_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_production_cluster -Des.node.name=node1 -Des.path.data=/var/lib/elasticsearch/node1/data -Des.path.logs=/var/log/elasticsearch/node1 -Des.network.host=192.168.1.101 -Des.http.port=9200 -Des.transport.tcp.port=9300 -Des.discovery.seed_hosts=192.168.1.101,192.168.1.102,192.168.1.103 -Des.cluster.initial_master_nodes=node1,node2,node3"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d
  1. 节点 2 的启动脚本
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 12GB
export ES_HEAP_SIZE=12g

# 设置集群名称为 my_production_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_production_cluster -Des.node.name=node2 -Des.path.data=/var/lib/elasticsearch/node2/data -Des.path.logs=/var/log/elasticsearch/node2 -Des.network.host=192.168.1.102 -Des.http.port=9201 -Des.transport.tcp.port=9301 -Des.discovery.seed_hosts=192.168.1.101,192.168.1.102,192.168.1.103 -Des.cluster.initial_master_nodes=node1,node2,node3"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d
  1. 节点 3 的启动脚本
#!/bin/bash

# 设置 ElasticSearch 安装目录
ES_HOME=/usr/local/elasticsearch

# 设置 Java 路径
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

# 将 Java 路径添加到系统路径
export PATH=$JAVA_HOME/bin:$PATH

# 设置 ElasticSearch 堆内存大小为 8GB
export ES_HEAP_SIZE=8g

# 设置集群名称为 my_production_cluster
export ES_JAVA_OPTS="-Des.cluster.name=my_production_cluster -Des.node.name=node3 -Des.path.data=/var/lib/elasticsearch/node3/data -Des.path.logs=/var/log/elasticsearch/node3 -Des.network.host=192.168.1.103 -Des.http.port=9202 -Des.transport.tcp.port=9302 -Des.discovery.seed_hosts=192.168.1.101,192.168.1.102,192.168.1.103 -Des.cluster.initial_master_nodes=node1,node2,node3"

# 进入 ElasticSearch 安装目录
cd $ES_HOME

# 启动 ElasticSearch,-d 参数表示以守护进程方式启动
./bin/elasticsearch -d

在这个案例中:

  • 每个节点都设置了合适的堆内存大小,根据节点的角色和服务器内存情况,节点 1 和节点 2 设置为 12GB,节点 3 设置为 8GB。
  • 明确指定了集群名称 my_production_cluster,确保所有节点属于同一集群。
  • 为每个节点设置了唯一的节点名称、数据目录、日志目录、网络绑定地址、HTTP 端口和传输端口。
  • 通过 discovery.seed_hostscluster.initial_master_nodes 参数配置了节点发现和初始主节点列表,保证集群能够正常组建和运行。

通过这样的配置,在实际应用中,该 ElasticSearch 集群在处理大量数据和高并发查询时表现出了较好的性能和稳定性。同时,定期检查日志文件和监控集群状态,及时发现并解决潜在问题,进一步优化了集群的运行效率。

在实际编写和优化 ElasticSearch 启动脚本时,需要根据具体的服务器环境、应用需求以及 ElasticSearch 版本等因素进行综合考虑和调整。通过不断的实践和优化,能够确保 ElasticSearch 高效、稳定地运行,为业务提供强大的搜索和分析支持。