前言
Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。本文从零开始,讲解如何使用在 CentOS 8.2 中搭建环境、安装与配置 Elasticsearch。
当前服务器环境信息
- 腾讯云 轻量应用服务器
- CPU:1 核;内存:2 GB
- CentOS 8.2 64 bit
JDK
Elasticsearch 是使用 Java 构建的,官方建议使用 Java 8 或更高的版本,并且仅支持 Oracle 的 Java 和 OpenJDK。在 Elasticsearch 7 后,每个发行版中都捆绑了推荐版本的JDK,位于Elasticsearch根目录中的 jdk
路径下。
当前Elasticsearch版本(7.14)捆绑的JDK版本是 Java 16.0.1,如需使用自己的 Java 版本,可以通过设置环境变量 ES_JAVA_HOME
来指定( Elasticsearch 7 之前的版本是 JAVA_HOME
,具体请留意自己Elasticsearch根目录中的 bin\elasticsearch-env
启动时配置Java环境的逻辑)。
# now set the path to java
if [ ! -z "$ES_JAVA_HOME" ]; then
JAVA="$ES_JAVA_HOME/bin/java"
JAVA_TYPE="ES_JAVA_HOME"
elif [ ! -z "$JAVA_HOME" ]; then
# fallback to JAVA_HOME
echo "warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME" >&2
JAVA="$JAVA_HOME/bin/java"
JAVA_TYPE="JAVA_HOME"
else
# use the bundled JDK (default)
if [ "$(uname -s)" = "Darwin" ]; then
# macOS has a different structure
JAVA="$ES_HOME/jdk.app/Contents/Home/bin/java"
else
JAVA="$ES_HOME/jdk/bin/java"
fi
JAVA_TYPE="bundled JDK"
fi
安装 Elasticsearch
手动安装
Elasticsearch 支持 tar.gz
压缩文件和 rpm
软件包等多种方式安装,本文介绍手动安装的方法。
在官网获取最新版本的下载链接
https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.14.0-linux-x86_64.tar.gz
使用命令行进行下载并解压
cd /tmp
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.14.0-linux-x86_64.tar.gz
tar -zvxf elasticsearch-7.14.0-linux-x86_64.tar.gz -C /usr/local
修改JVM配置
虽然在默认情况下,Elasticsearch 会根据节点的角色和总内存自动设置 JVM 堆内存大小,但是必须使用捆绑的 JDK,或者自定义指定 Java 14 及更高的版本。 由于当前服务器的内存较小,以防万一还是手动设置一下。
打开 Elasticsearch 的 JVM 配置文件
vim /usr/local/elasticsearch-7.14.0/config/jvm.options
把 -Xms4g
、-Xmx4g
两个配置项的注释去掉,根据自己服务器的实际情况配置,官方建议是 Xms
和 Xmx
不超过总内存的 50%。此处我均修改为 256 m。
-Xms256m
-Xmx256m
运行 Elasticsearch
执行命令 bash /usr/local/elasticsearch-7.14.0/bin/elasticsearch -d
,其中 -d 表示后台启动。
如无意外,可以看到如下报错信息:
[root@VM-8-7-centos bin]# uncaught exception in thread [main]
java.lang.RuntimeException: can not run elasticsearch as root
at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:103)
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:170)
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:399)
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:159)
at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150)
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:75)
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:116)
at org.elasticsearch.cli.Command.main(Command.java:79)
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:115)
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:81)
原因是 Elasticsearch 默认不支持 root 用户启动。
解决方案一:使用参数 -Des.insecure.allow.root=true
-Des.insecure.allow.root=true
修改 /usr/local/elasticsearch-7.14.0/bin/elasticsearch
,ES_JAVA_OPTS
添加参数 -Des.insecure.allow.root=true
或执行时添加 bash /usr/local/elasticsearch-7.14.0/bin/elasticsearch -d -Des.insecure.allow.root=true
经过多番查阅官网资料以及亲自试验,发现这是过时的方案。
首先,Elasticserach 命令 -D 选项已经被 -E 选项替代了,假如尝试以 -D 选项执行的话,会输出以下异常信息:
[root@VM-8-7-centos bin]# bash /usr/local/elasticsearch-7.14.0/bin/elasticsearch -Des.insecure.allow.root=true
Starts Elasticsearch
Option Description
------ -----------
-E <KeyValuePair> Configure a setting
-V, --version Prints Elasticsearch version information and exits
-d, --daemonize Starts Elasticsearch in the background
-h, --help Show help
-p, --pidfile <Path> Creates a pid file in the specified path on start
-q, --quiet Turns off standard output/error streams logging in console
-s, --silent Show minimal output
-v, --verbose Show verbose output
ERROR: D is not a recognized option
其次,即使以 -E 选项输入参数启动 bash elasticsearch -Ees.insecure.allow.root=true
,依旧会抛出和前文一样的异常(can not run elasticsearch as root),无法使用 root 用户启动。
这是因为只有在 2.0.0 <= 版本 < 5.0.0 支持这个特殊的系统属性,Elasticsearch 5 以后的版本已经去除掉了这个配置项。
解决方案二:添加专门的用户
useradd elastic
chown -R elastic:elastic /usr/localelasticsearch-7.14.0
su elastic
bash /usr/localelasticsearch-7.14.0 -d
这次启动没有抛出报错了。
验证连接
curl http://localhost:9200
响应报文:
{
"name" : "VM-8-7-centos",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "1sCdWSErR6WuyR1WQrJRAw",
"version" : {
"number" : "7.14.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "dd5a0a2acaa2045ff9624f3729fc8a6f40835aa1",
"build_date" : "2021-07-29T20:49:32.864135063Z",
"build_snapshot" : false,
"lucene_version" : "8.9.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
但此时在自己电脑使用访问外网 IP xxx.xxx.xxx.xxx:9200 却无法访问。
这台服务器先前已经装过 MySQL,外网能正常连接使用,猜测是否是腾讯云的防火墙没有开放 9200 的端口,但我再三确认过已经开放了。
排查问题
检查服务器的 9200 端口占用情况:
netstat -tunlp|grep 9200
输出:
tcp6 0 0 127.0.0.1:9200 :::* LISTEN 2898806/java
注意到 Elasticsearch 只监听了 127.0.0.1:9200,所以外网的请求是没有监听到的。
修改配置文件
打开 Elasticsearch 的配置文件
vim /usr/local/elasticsearch-7.14.0/config/elasticsearch.yml
把 network.host: 192.168.0.1
一行的注释去掉,修改为:
network.host: 0.0.0.0
即监听所有(9200 端口)的请求。重启 Elasticsearch,会抛出新的异常:
ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
bootstrap check failure [1] of [1]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
ERROR: Elasticsearch did not exit normally - check the logs at /usr/local/elasticsearch-7.14.0/logs/elasticsearch.log
含义为 discovery.seed_hosts
,discovery.seed_providers
, cluster.initial_master_nodes
这三个配置项至少需要配置一个。大概是因为手动修改 network.host
配置项后,触发了程序新的检查逻辑。
再次打开 elasticsearch.yml
,把cluster.initial_master_nodes: ["node-1", "node-2"]
一行的注释去掉,修改为:
cluster.initial_master_nodes: ["node-1"]
再次重启 Elasticsearch,这时再在自己电脑访问外网 IP xxx.xxx.xxx.xxx:9200,能正常响应报文:
{
"name" : "VM-8-7-centos",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "1sCdWSErR6WuyR1WQrJRAw",
"version" : {
"number" : "7.14.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "dd5a0a2acaa2045ff9624f3729fc8a6f40835aa1",
"build_date" : "2021-07-29T20:49:32.864135063Z",
"build_snapshot" : false,
"lucene_version" : "8.9.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
一点题外话
关于不要以 root 用户运行,Elasticsearch 官方的解释是:
First and foremost, never run Elasticsearch as the
root
user as this would allow any successful effort to circumvent the other security layers to do anything on your server. Elasticsearch will refuse to start if it detects that it is running asroot
but this is so important that it is worth double and triple checking.
简单翻译一下就是:root 用户权限太高,会绕开安全层面的拦截,有风险,所以 Elasticsearch 拒绝以 root 用户启动。
关于能否以 root 身份运行 Elasticsearch,官方的论坛里也有很多相关的问题和讨论,其中一篇我认为很有意思——
有位名叫Lin Zhao的用户认为能否以 root 身份运行 Elasticsearch 这个应该交由部署(运维?)人员来决策,官方应该提供这个选项。对此,另外一位用户Jörg Prante提出了反驳,核心理由是:
The decision not to run as root is not an option for the deployment department, it's an obligation for everyone who runs applications.
“不以 root 用户身份运行的决定不是部署(运维?)部门的选项,而是每个运行应用程序的人的义务。”