Linux下ELK5 - Elasticsearch Cluster 搭建

前言:

ELK 不是一款软件,而是 Elasticsearch、Logstash 和 Kibana 三种软件产品的首字母缩写。这三者都是开源软件,通常配合使用,而且又先后归于 Elastic.co 公司名下,所以被简称为 ELK Stack。根据 Google Trend 的信息显示,ELK Stack 已经成为目前最流行的集中式日志解决方案。

这里说下Elasticsearch, 它来源于作者 Shay Banon 的第一个开源项目 Compass 库,而这个 Java 库最初的目的只是为了给 Shay 当时正在学厨师的妻子做一个菜谱的搜索引擎。2010 年,Elasticsearch 正式发布。至今已经成为 GitHub 上最流行的 Java 项目,不过 Shay 承诺给妻子的菜谱搜索依然没有面世……

2015 年初,Elasticsearch 公司召开了第一次全球用户大会 Elastic{ON}15。诸多 IT 巨头纷纷赞助,参会,演讲。会后,Elasticsearch 公司宣布改名 Elastic,公司官网也变成 http://elastic.co/。这意味着 Elasticsearch 的发展方向,不再限于搜索业务,也就是说,Elastic Stack 等机器数据和 IT 服务领域成为官方更加注意的方向。随后几个月,专注监控报警的 Watcher 发布 beta 版,社区有名的网络抓包工具 Packetbeat、多年专注于基于机器学习的异常探测 Prelert 等 ITOA 周边产品纷纷被 Elastic 公司收购。

我这里分享下ELK5.1版本我的Elasticsearch Cluster的搭建过程,希望对大家有所帮助。注意所有的方式均参照ELK官方文档,此文章的elk版本是5.1,不同的版本会有所差异,比如官方文档最新的Elasticsearch5.x版本的bootstrap checks项中有System call filter check选项,而5.1版本就没有。这里也建议搭建参考最新的ELK官方文档,避免踩坑。

安装

系统环境:Ubuntu 14.04 64bit

1.安装Java

Elasticsearch至少需要java8版本:

# add-apt-repository ppa:webupd8team/java
# apt-get update
# Oracle-java8-installer
# java -version  //检验Java版本
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

2.安装Elasticsearch

使用apt源安装:

# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch
\| apt-key add -
# apt-get install apt-transport-https
# echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main"
\| tee -a /etc/apt/sources.list.d/elastic-5.x.list
# apt-get update && apt-get install elasticsearch

这里注意一点,官方建议不要用add-apt-repository的方式安装:

Linux下ELK5 - Elasticsearch Cluster 搭建

3.配置Elasticsearch

  配置文件在/etc/elasticsearch目录下,我这里采用master+data node的方式,使用3台机器做master node,剩余机器做data node(我这里有6台data node),3个master这种方式也是官方推荐的,之后在Elasticsearch性能不够的时候,可以通过增加data node数量实现横向扩展。

以下是之中一个data node的配置示例:

# egrep -v '^#|^$' /etc/elasticsearch/elasticsearch.yml
cluster.name: cds-escluster  #集群名称,集群唯一标识,同一个cluster的name必须相同
node.name: elasticsearch5  #自定义的node name
node.master: false
node.data: true            #采用data node模式,禁用其他两种node类型
node.ingest: false
path.data: /data/elasticsearch  #更改为自定义的data目录
path.logs: /var/log/elasticsearch  #默认log存放目录
bootstrap.memory_lock: true    #启用jvm的memory lock
network.host: 172.16.2.15      #指定host,启用生产模式
discovery.zen.ping.unicast.hosts: ["172.16.2.15", "172.16.2.16", "172.16.2.17", "172.16.2.18", "172.16.2.19", "172.16.2.20", "172.16.2.21", "172.16.2.22", "172.16.2.23"]
# 指定cluster的node list,可以是ip或hostname
discovery.zen.minimum_master_nodes: 2  #这里注意,为了避免出现脑列,3个master设置为2
discovery.zen.commit_timeout: 100s  #以下是集群参数调整
discovery.zen.publish_timeout: 100s
discovery.zen.ping_timeout: 100s
discovery.zen.fd.ping_timeout: 100s
discovery.zen.fd.ping_interval: 10s
discovery.zen.fd.ping_retries: 10
action.destructive_requires_name: true #集群安全设置

解释说明: 

  1)如果是master node,把node.master设为true,node.data和node.ingest设为false即可。其他配置除了node.name和network.host视实际情况自行设置。

  2)ES从2.0版本开始,默认的自动发现方式改为了单播(unicast)方式。配置里提供几台节点的地址,ES将其视作gossip router角色,借以完成集群的发现。由于这只是ES内一个很小的功能,所以 gossip router角色并不需要单独配置,每个ES节点都可以担任。所以,采用单播方式的集群,各节点都配置相同的几个节点列表作为router即可。

  3)此外,考虑到节点有时候因为高负载,慢GC等原因可能会有偶尔没及时响应ping包的可能,一般建议稍微加大Fault Detection的超时时间,即discovery.zen.fd.ping_timeout参数。

  4)同样基于安全考虑做的变更还有监听的主机名。Elasticsearch有两种模式,开发和生产模式,默认只监听本地lo网卡上,指定host之后默认即开启生产模式,所以正式环境上需要修改配置为监听具体的网卡。参考链接development mode vs production mode

  5)上面的配置中,两个timeout可能会让人有所迷惑。这里的fd是fault detection的缩写。也就是说:

 discovery.zen.ping.timeout 参数仅在加入或者选举master主节点的时候才起作用;

 discovery.zen.fd.ping_timeout 参数则在稳定运行的集群中,master检测所有节点,以及节点检测master是否畅通时长期有用。

  6)既然是长期有用,自然还有运行间隔和重试的配置,也可以根据实际情况调整,即调整

discovery.zen.fd.ping_interval和discovery.zen.fd.ping_retries这两个参数。

  7)这里重点说下discovery.zen.minimum_master_nodes这个参数

在ping主节点过程中,节点会加入到集群中或者会被选举为主节点;发送主节点的超时时间由discovery.zen.join_timeout参数来控制,默认为3s,对于配置node.master为false的节点启动后不会作为主节点的候选。discovery.zen.minimum_master_nodes配置当前集群中最少的主节点数,对于多于两个节点的集群环境,计算公式如下:

(master_eligible_nodes / 2) + 1

比如我这里有3个master node,那么为了防止脑裂的出现,最小的主节点数就是:3/2+1=2;

同理,5个master,最小主节点数就是:5/2+1=3;

参考链接:zen discovery 和 transport module

参考链接:Avoid Split Brian

  8)ES是一个P2P类型(使用 gossip 协议)的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给哪些节点,并且直接跟这些节点通信。

  9) 另外master node一般只负责集群内轻量级操作,比如创建、删除索引,跟踪集群内node的变化信息,决定哪个数据分片的存储位置,一般master不用来存储数据。

其他参数可以查阅官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/5.x/important-settings.html

更改系统设置和基本优化:

配置完elasticsearch之后即可以启动,但是在系统之前建议先调整系统参数,这里对应的是官方文档的Bootstrap Checks:

1)JVM Heap Size:

这里更改的是jvm的参数,更改之前需要确保ES的配置里,bootstrap.memory_lock项是启用的,见上:

vim /etc/elasticsearch/jvm.options
-Xms8g
-Xmx8g    #这里一般设置为50%-60%的系统物理内存大小

2)File Descriptors和Max Thread Number:

#临时设置办法:
ulimit -n 65536
#想永久生效,编辑系统limit文件,添加两行
vim /etc/security/limits.conf
elasticsearch    -      nofile          65536
elasticsearch    -      nproc          2048
 
#Ubuntu需要确保pam启用了limit:
vim /etc/pam.d/su
session    required  pam_limits.so  #这里取消注释
 
#系统配置
vim /etc/default/elasticsearch # 添加两行
MAX_LOCKED_MEMORY=unlimited
MAX_OPEN_FILES=65536

3)禁用swap

# swapoff -a  # 临时禁用
# vim /etc/fstab
  swap 行取消注释  #永久禁用

4)内核参数调整

# vim /etc/sysctl.conf
vm.max_map_count=262144  #对应Virtual Memory

启动服务:

# service elasticsearch start
# service elasticsearch status
 * elasticsearch is running
# update-rc.d elasticsearch defaults 95 10  #设置开机自启动

启动之后查看node和cluster的状态,常用的几个:

检查集群状态:

curl -XGET 'http://server_ip:9200/_cluster/state?pretty'

或者

curl -XGET 'http://server_ip:9200/_cluster/health?pretty'

输出示例,我的集群有9个node,3个master,6个data node:

{
  "cluster_name" : "op-escluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 9,
  "number_of_data_nodes" : 6,
  "active_primary_shards" : 16,
  "active_shards" : 32,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}  这里最重要的就是status这行。很多开源的ES监控脚本,其实就是拿这行数据做报警判断。status 有三个可能的值:

green 绿灯,所有分片都正确运行,集群非常健康。

yellow 黄灯,所有主分片都正确运行,但是有副本分片缺失。这种情况意味着 ES 当前还是正常运行的,但是有一定风险。注意,在 Kibana4 的 server 端启动逻辑中,即使是黄灯状态,Kibana 4 也会拒绝启动,死循环等待集群状态变成绿灯后才能继续运行。

red 红灯,有主分片缺失。这部分数据完全不可用。而考虑到 ES 在写入端是简单的取余算法,轮到这个分片上的数据也会持续写入报错。

2.查看node信息和

curl -XGET http://server_ip:9200

或者

curl -XGET 'http://server_ip:9200/_nodes/process?pretty'

或者

curl -XGET 'http://server_ip:9200/_nodes/stats

通过nodes/stats可以看到很多信息,包括:写入、读取、搜索性能,JVM等数据。

3.查看node的文件描述符

curl -XGET 'http://server_ip:9200/_nodes/stats/process?filter_path=**.max_file_descriptors'

4.任务管理

curl -XGET 'http:///server_ip:9200/_cat/tasks?v'

趟过的坑:

如果是自定义目录,需要注意权限的问题;elasticsearch的属主和属组都是elasticsearch用户;

启动报错:Unable to lock JVM Memory: error=12, reason=Cannot allocate memory.-----检查JVM的Heap Size是否调整。

集群无法正常启动:因为我是在云主机上配置的,开始图方便,配置好其中一台node之后就拿这台机器去克隆的其他8台,结果最后改完配置完成总启动不正常,卸载重新安装也不行;查看node的cluster_uuid一直是“__ha__”。排除了两天才发现,克隆机器的es data目录没有清空干净,存在残留的集群信息。囧....

对官网上下面这句话的理解:

Linux下ELK5 - Elasticsearch Cluster 搭建

为了集群稳定性官方推荐,master和data node做分离,需要设置最小主节点数;但是由于刚安装成功的elasticsearch默认是master和data在一起的,比如我有9个节点,开始理解以为munimum_master_nodes就设置为9/2+1=5个,官方文档读多了之后才发现,应该是:9个节点,我把其中3个node作为master,那么这个munimum_master_nodes就应该是3/2+1=2。

ElasticSearch 的详细介绍:请点这里
ElasticSearch 的下载地址:请点这里

相关推荐