ElasticSearch集群部署文档
官方es搭建步骤写的很简略, 但是实际搭建过程中, 会涉及一系列环境配置. 以下的流程, 是在搭建过程中梳理出来的详细步骤(实践过3遍以上)
其实, 这些流程在具体应用的时候, 都可以变成自动化脚本, 或者直接用docker好了, 以便扩容足够快(目前我们用的打包成集成安装包, 实现脚本自动部署)
只是简单集群的基本设置, 不涉及调优的参数配置, 不涉及client/master/data
节点区分等等. 可以参照搭建的主体流程.
版本及连接
elasticseearch版本: 2.3.3
相关链接:
系统要求
如果仅作测试用, 不需要两天机器, 可以将两个节点部署在同一台机器上, 对磁盘/cpu要求不高, 内存大于2g基本足够了
如果是正式环境, 需要根据日志量进行评估, 例如, 每天日志量占硬盘约约10G, 且保留30天日志, 则磁盘会占用约300g, es设定的阈值是磁盘空间占满85%则日志开始告警. 所以, 需要至少 300/0.85=354g
.
准备两台机器, 在同一个局域网内(可ping通), 分别在每台机器上部署相应es节点, 搭建一套日志集群.
两台机器, 最少的资源了, 但是没法做到高可用, 所以, 还需要再加一台机器, 防止脑裂, 具体见最后(两台主力机器+一台稳定的机器就行)
- 集群节点: 最少两台机器
- 内存: 16G及以上
- cpu: 4核及以上
- 硬盘: 800G及以上, 建议1T, 集群容量约10亿级(取决于对应日志大小)
- 操作系统: centos
这里假设, 两台机器ip分别为
第一台机器: 10.0.0.1
第二台机器: 10.0.0.2
机器系统为centos6.5
部署
1. 确认JDK版本及安装
es依赖java的版本最小为1.7
java -version
-
如果系统中未安装
JDK
则命令返回
bash: java: command not found
, 需要安装JDK
-
如果系统中安装了JDK, 需确认版本是否大于
java 1.7
, 否则需要升级java version "1.7.0_51" Java(TM) SE Runtime Environment (build 1.7.0_51-b13) Java HotSpot(TM) Server VM (build 24.51-b03, mixed mode)
安装及升级java
(注意根据系统不同运行对应安装命令)
# Redhat/Centos/Fedora
sudo yum install java-1.7.0-openjdk
或者到官网, 下载最新的jdk的rpm包, 然后安装
wget http://download.oracle.com/otn-pub/java/jdk/8u91-b14/jdk-8u91-linux-x64.rpm
rpm -Uvh jdk-8u91-linux-x64.rpm
再次确认安装成功
java -version
2. 下载es
版本: 2.3.3
下载地址:
命令行中的下载命令:
curl -L -O https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.3.3/elasticsearch-2.3.3.tar.gz
解压:
tar -xzf elasticsearch-2.3.3.tar.gz
3. 用户/目录/权限设置
新建用户, 假设为es
sudo useradd es
新建目录, 假设/data/
目录挂载的硬盘最大(500G
以上)
mkdir -p /data/LogTool
mkdir -p /data/LogData
将解压后的目录移动至新建的目录/data/LogTool
下, 并改名为elasticsearch
mv elasticsearch-2.3.3 /data/LogTool/elasticsearch
将目录所有者修改为test
chown -R es:es /data/LogTool
chown -R es:es /data/LogData
5. 切换用户
切换到es
用户, 并进入elasticsearch
目录
su es
cd /data/LogTool/elasticsearch/
以用户es
的身份进行后续操作
6. 修改配置文件
以用户es
的身份进行操作
文件路径: config/elasticsearch.yml
修改该文件中配置项: (注意, 原始文件中都是被#
号注释掉了, 需要去掉对应注释并修改配置值)
- 集群名:
cluster.name
, 注意: 两台机器配置一致
cluster.name: inner_es_cluster
- 节点名:
node.name
, 注意: 两台机器配置不同, 一台为01, 另一台为02
# 第一台机器
node.name: inner_es_node_01
# 第二台机器
node.name: inner_es_node_02
- 数据路径:
path.data
, 为新建立的目录
path.data: /data/LogData/
- 日志路径:
path.logs
path.logs: /data/LogData/logs
- LockMemory:
bootstrap.mlockall: true
- 本机ip:
network.host
, 注意两台机器配置不同, 分贝配置为对应机器的内网ip
# 第一台机器
network.host: 10.0.0.1
# 第二台机器
network.host: 10.0.0.2
- Discovery配置: 注意这里是两台机器内网ip+9300端口, 注意这里
minimum_master_nodes=2
, 见最后一点防脑裂说明
discovery.zen.ping.unicast.hosts: ["10.0.0.1:9300", "10.0.0.2:9300"]
discovery.zen.minimum_master_nodes: 2
- gatewary配置:
gateway.recover_after_nodes: 2
gateway.recover_after_time: 5m
gateway.expected_nodes: 1
- 新增其他配置到文件末尾, 根据需求加, 这里用到了
script
, 同时增大了recovery
的配置(要大些保证recovery速度, 但是又不能太大, 会将带宽占满)
script.engine.groovy.inline.search: on
script.engine.groovy.inline.aggs: on
indices.recovery.max_bytes_per_sec: 100mb
indices.recovery.concurrent_streams: 10
7. 设置es占用内存
修改文件bin/elasticsearch.in.sh
, 将文件如下变量变更为4g
(根据自身机器配置, 配置的内存最大不超过机器物理内存的75%. 两个变量值相等, 以获取最大的性能). 当然, 实际使用中4g
可能远远不够, 这个值仅是个示例
ES_MIN_MEM=4g
ES_MAX_MEM=4g
修改centos配置: /etc/security/limits.conf
, 以便启用memlock, 提升性能
加入, 注意, 示例中用户为es
es soft memlock unlimited
es hard memlock unlimited
确认max descriptiors
查看系统数量
- 如果结果是
unlimited
, 则无需任何处理, 直接进入下一步
ulimit -n
unlimited
- 如果结果是一个整数, 且小于
204800
ulimit -n
4096
此时, 需要编辑/etc/security/limits.conf
, 加入
es soft nofile 204800
es hard nofile 204800
另一种方法, 修改bin/elasticsearch
, 在文件的前半部分加入下面这行代码, 保证在启动前执行即可.
ulimit -n 204800
8. 启动测试
以用户es
的身份进行操作
在命令行中执行启动命令
cd /data/elasticsearch/
./bin/elasticsearch
可以看到程序启动日志
[2016-06-30 17:20:26,677][WARN ][bootstrap ] unable to install syscall filter: seccomp unavailable: requires kernel 3.5+ with CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER compiled in
[2016-06-30 17:20:27,390][INFO ][node ] [inner_es_node_01] version[2.3.3], pid[6415], build[218bdf1/2016-05-17T15:40:04Z]
[2016-06-30 17:20:27,390][INFO ][node ] [inner_es_node_01] initializing ...
[2016-06-30 17:20:27,948][INFO ][plugins ] [inner_es_node_01] modules [lang-groovy, reindex, lang-expression], plugins [], sites []
[2016-06-30 17:20:27,974][INFO ][env ] [inner_es_node_01] using [1] data paths, mounts [[/data (/dev/xvdb1)]], net usable_space [67.4gb], net total_space [98.4gb], spins? [no], types [ext3]
[2016-06-30 17:20:27,974][INFO ][env ] [inner_es_node_01] heap size [990.7mb], compressed ordinary object pointers [true]
[2016-06-30 17:20:29,926][INFO ][node ] [inner_es_node_01] initialized
[2016-06-30 17:20:29,926][INFO ][node ] [inner_es_node_01] starting ...
[2016-06-30 17:20:30,083][INFO ][transport ] [inner_es_node_01] publish_address {10.0.0.1:9300}, bound_addresses {10.0.0.1:9300}
[2016-06-30 17:20:30,088][INFO ][discovery ] [inner_es_node_01] inner_es_cluster/odmTjZRHRVaa8Zn4vTPcxA
[2016-06-30 17:21:00,091][WARN ][discovery ] [inner_es_node_01] waited for 30s and no initial state was set by the discovery
[2016-06-30 17:21:00,099][INFO ][http ] [inner_es_node_01] publish_address {10.0.0.1:9200}, bound_addresses {10.0.0.1:9200}
[2016-06-30 17:21:00,099][INFO ][node ] [inner_es_node_01] started
等待约一分钟后, 看到如下日志代表启动成功
[2016-06-30 17:21:00,099][INFO ][node ] [inner_es_node_01] started
确认集群是否启动成功
curl http://10.0.0.1:9200/
{
"name" : "inner_es_node_01",
"cluster_name" : "inner_es_cluster",
"version" : {
"number" : "2.3.3",
"build_hash" : "218bdf10790eef486ff2c41a3df5cfa32dadcfde",
"build_timestamp" : "2016-05-17T15:40:04Z",
"build_snapshot" : false,
"lucene_version" : "5.5.0"
},
"tagline" : "You Know, for Search"
}
启动第二个节点时日志
[2016-06-30 17:32:42,494][WARN ][bootstrap ] unable to install syscall filter: seccomp unavailable: requires kernel 3.5+ with CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER compiled in
[2016-06-30 17:32:43,295][INFO ][node ] [inner_es_node_02] version[2.3.3], pid[10240], build[218bdf1/2016-05-17T15:40:04Z]
[2016-06-30 17:32:43,295][INFO ][node ] [inner_es_node_02] initializing ...
[2016-06-30 17:32:43,879][INFO ][plugins ] [inner_es_node_02] modules [lang-groovy, reindex, lang-expression], plugins [], sites []
[2016-06-30 17:32:43,905][INFO ][env ] [inner_es_node_02] using [1] data paths, mounts [[/data (/dev/xvdb1)]], net usable_space [67.4gb], net total_space [98.4gb], spins? [no], types [ext3]
[2016-06-30 17:32:43,905][INFO ][env ] [inner_es_node_02] heap size [990.7mb], compressed ordinary object pointers [true]
[2016-06-30 17:32:45,876][INFO ][node ] [inner_es_node_02] initialized
[2016-06-30 17:32:45,876][INFO ][node ] [inner_es_node_02] starting ...
[2016-06-30 17:32:45,978][INFO ][transport ] [inner_es_node_02] publish_address {10.0.0.2:9300}, bound_addresses {10.0.0.2:9300}
[2016-06-30 17:32:45,983][INFO ][discovery ] [inner_es_node_02] inner_es_cluster/VBsHeFjXQXau59hkjTuhTA
[2016-06-30 17:32:49,067][INFO ][cluster.service ] [inner_es_node_02] detected_master {inner_es_node_01}{1BktktzhQ_y6BN-lNIKhHg}{10.0.0.1}{10.0.0.1:9300}, added {{inner_es_node_01}{1BktktzhQ_y6BN-lNIKhHg}{10.0.0.1}{10.0.0.1:9300},}, reason: zen-disco-receive(from master [{inner_es_node_01}{1BktktzhQ_y6BN-lNIKhHg}{10.0.0.1}{10.0.0.1:9300}])
[2016-06-30 17:32:49,077][INFO ][http ] [inner_es_node_02] publish_address {10.0.0.2:9200}, bound_addresses {10.213.136.23:9201}
[2016-06-30 17:32:49,077][INFO ][node ] [inner_es_node_02] started
注意, 日志中cluster.service
部分, 表示发现了第一台机器的节点
[2016-06-30 17:32:49,067][INFO ][cluster.service ] [inner_es_node_02] detected_master {inner_es_node_01}{1BktktzhQ_y6BN-lNIKhHg}{10.0.0.1}{10.0.0.1:9300}, added {{inner_es_node_01}{1BktktzhQ_y6BN-lNIKhHg}{10.0.0.1}{10.0.0.1:9300},}, reason: zen-disco-receive(from master [{inner_es_node_01}{1BktktzhQ_y6BN-lNIKhHg}{10.0.0.1}{10.0.0.1:9300}])
启动第二个节点后, 同样确认是否启动成功
curl http://10.0.0.1:9200/
{
"name" : "inner_es_node_02",
"cluster_name" : "inner_es_cluster",
"version" : {
"number" : "2.3.3",
"build_hash" : "218bdf10790eef486ff2c41a3df5cfa32dadcfde",
"build_timestamp" : "2016-05-17T15:40:04Z",
"build_snapshot" : false,
"lucene_version" : "5.5.0"
},
"tagline" : "You Know, for Search"
}
9. 正式启动
ctrl+c
关掉原先的进程
使用命令, 以daemon形式启动, 进程pid写入es.pid
, 可以用于重启等
bin/elasticsearch -d -p es.pid
echo $?
0
查看对应进程是否启动
ps aux | grep elasticsearch
使用curl
请求服务确定是否正常
curl http://10.0.0.1:9200/
或者, 更好的方式, 使用supervisord
管理进程, 以下为supervisord.conf
示例
[program:es]
directory=/data/LogTool/elasticsearch
command=/data/LogTool/elasticsearch/bin/elasticsearch
autostart=true
autorestart=true
stdout_logfile=/data/LogTool/elasticsearch/log/supervisord_es_out.log
stderr_logfile=/data/LogTool/elasticsearch/log/supervisord_es_err.log
10. 脑裂
单机测试开发的时候, 其实一个节点就够了. 上线, 使用两个节点, 目的是利用es本身的特性做到高可用.
但是两个节点是远远不够的. 启动后, 集群会选举一个master
, 一切ok. 但是如果存在网络问题或者某个节点无响应(负载过高), 就会认为对方dead了, 然后两个节点自动选举为master
, 在后续建索引的时候造成数据不一致.
两个节点防脑裂的配置, minimum_master_nodes
决定了选主需要的最少节点数, N/2+1
, 两个节点即2
discovery.zen.minimum_master_nodes: 2
但是, 此时一个节点挂了, 则整个集群挂了(无法选举主节点了)
所以, 要再加一个节点, 这个节点只要保证稳定即可, 对cpu和磁盘要求不高. 这个es
节点的配置同其他节点的区别node.data: false
, 不存储索引数据.
# split brain prevent
node.data: false