一、书接上文

上篇博客说到单台es状态为yellow,需要搭建集群解决。如果你资源有限只有一台机器, cp一个elasticsearch,使用相同命令在本机再启动一个es实例,再次检查集群健康, 发现unassigned_shards减少, active_shards增多。下面看es介绍、es配置文件和es集群搭建。


二、es介绍

1、elasticsearch(下文称es)是一款分布式且高可扩展的全文搜索和分析引擎,本身是基于Lucene进行开发,但ES足够简单易用,提供丰富的API,部署容易。elasticsearch 已经提供了大部分设置,都是合理的默认配置。所以你不必进行烦人的配置就可以尝试一下。大多数时候,这些默认的配置就足以运行一个生产集群了。


2、分片以及水平扩展.

elasticsearch用于构建高可用和可扩展的系统。扩展的方式可以是购买更好的服务器(纵向扩展)或者购买更多的服务器(横向扩展),elasticsearch能从更强大的硬件中获得更好的性能,但是纵向扩展也有一定的局限性。真正的扩展应该是横向的,它通过增加节点来传播负载和增加可靠性。对于大多数数据库而言,横向扩展意味着你的程序将做非常大的改动来利用这些新添加的设备。对比来说,elasticsearch天生是分布式的:它知道如何管理节点来提供高扩展和高可用。


3、集群和节点

节点(node)是你运行的elasticsearch实例。一个集群(cluster)是一组具有相同cluster.name的节点集合,他们协同工作,共享数据并提供故障转移和扩展功能,当有新的节点加入或者删除节点,集群就会感知到并平衡数据。集群中一个节点会被选举为主节点(master),它用来管理集群中的一些变更,例如新建或删除索引、增加或移除节点等,当然一个节点也可以组成一个集群。


4、节点通信

我们能够与集群中的任何节点通信,包括主节点。任何一个节点互相知道文档存在于哪个节点上,它们可以转发请求到我们需要数据所在的节点上。我们通信的节点负责收集各节点返回的数据,最后一起返回给客户端。这一切都由elasticsearch透明的管理。



4、分片(shard)与副本分片(replica shard)

分片用于elasticsearch在你的集群中分配数据。想象把分片当作数据的容器。文档存储在分片中,然后分片分配给你集群中的节点上。当你的集群扩容或缩小,elasticsearch将会自动在你的节点间迁移分片,以使集群保持平衡。


一个分片(shard)是一个最小级别的“工作单元(worker unit)”,它只是保存索引中所有数据的一小片.我们的文档存储和被索引在分片中,但是我们的程序不知道如何直接与它们通信。取而代之的是,他们直接与索引通信.elasticsearch中的分片分为主分片和副本分片,复制分片只是主分片的一个副本,它用于提供数据的冗余副本,在硬件故障之后提供数据保护,同时服务于像搜索和检索等只读请求,主分片的数量和复制分片的数量都可以通过配置文件配置。但是主切片的数量只能在创建索引时定义且不能修改.相同的分片不会放在同一个节点上。



5、集群生态:

(1)、同集群中节点之间可以扩容缩容

(2)、主分片的数量会在其索引创建完成后修正,但是副本分片的数量会随时变化

(3)、相同的分片不会放在同一个节点上




6、集群健康(cluster health)

es中用三种颜色状态表示:green,yellow,red.

green:所有主分片(Primary Shard)和副本分片(Replica Shard)都可用

yellow:所有主分片可用,但不是所有副本分片都可用

red:不是所有的主分片都可用

[root@ossec-server plugins]# curl -XGET http://localhost:9200/_cluster/health\?pretty

{

  "cluster_name" : "elasticsearch", #集群的名字

  "status" : "yellow",              #集群的状态  

  "timed_out" : false,

  "number_of_nodes" : 2,            #节点数

  "number_of_data_nodes" : 1,       #数据节点数

  "active_primary_shards" : 216,    #主分片数,216个index库

  "active_shards" : 216,            #共有216个分片

  "relocating_shards" : 0,

  "initializing_shards" : 0,

  "unassigned_shards" : 216,        #未指定节点,配置了副本,仅用一台机器部署会出现这种情况

  "number_of_pending_tasks" : 0,

  "number_of_in_flight_fetch" : 0

}



三、elasticsearch配置文件详解

[root@elasticsearch-node02 config]# tree

.

├── elasticsearch.yml

└── logging.yml

第一个是es的基本配置文件,第二个是日志配置文件。下面主要讲elasticsearch.yml。


cluster.name: elasticsearch

配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。


node.name: "Franz Kafka"

节点名,默认随机指定一个name列表中名字,该列表在es的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字。


node.master: true

指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。


node.data: true

指定该节点是否存储索引数据,默认为true。


index.number_of_shards: 5

设置默认索引分片个数,默认为5片。


index.number_of_replicas: 1

设置默认索引副本个数,默认为1个副本。


path.conf: /path/to/conf

设置配置文件的存储路径,默认是es根目录下的config文件夹。


path.data: /path/to/data

设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开,例:

path.data: /path/to/data1,/path/to/data2


path.work: /path/to/work

设置临时文件的存储路径,默认是es根目录下的work文件夹。


path.logs: /path/to/logs

设置日志文件的存储路径,默认是es根目录下的logs文件夹


path.plugins: /path/to/plugins

设置插件的存放路径,默认是es根目录下的plugins文件夹


bootstrap.mlockall: true

设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过`ulimit -l unlimited`命令。


network.bind_host: 192.168.0.1

设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。


network.publish_host: 192.168.0.1

设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。


network.host: 192.168.0.1

这个参数是用来同时设置bind_host和publish_host上面两个参数。


transport.tcp.port: 9300

设置节点间交互的tcp端口,默认是9300。


transport.tcp.compress: true

设置是否压缩tcp传输时的数据,默认为false,不压缩。


http.port: 9200

设置对外服务的http端口,默认为9200。


http.max_content_length: 100mb

设置内容的最大容量,默认100mb


http.enabled: false

是否使用http协议对外提供服务,默认为true,开启。


gateway.type: local

gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的HDFS,和amazon的s3服务器,其它文件系统的设置方法下次再详细说。


gateway.recover_after_nodes: 1

设置集群中N个节点启动时进行数据恢复,默认为1。


gateway.recover_after_time: 5m

设置初始化数据恢复进程的超时时间,默认是5分钟。


gateway.expected_nodes: 2

设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。


cluster.routing.allocation.node_initial_primaries_recoveries: 4

初始化数据恢复时,并发恢复线程的个数,默认为4。


cluster.routing.allocation.node_concurrent_recoveries: 2

添加删除节点或负载均衡时并发恢复线程的个数,默认为4。


indices.recovery.max_size_per_sec: 0

设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。


indices.recovery.concurrent_streams: 5

设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。


discovery.zen.minimum_master_nodes: 1

设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)


discovery.zen.ping.timeout: 3s

设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。


discovery.zen.ping.multicast.enabled: false

设置是否打开多播发现节点,默认是true。


discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]"]

设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。


下面是一些查询时的慢日志参数设置

index.search.slowlog.level: TRACE

index.search.slowlog.threshold.query.warn: 10s

index.search.slowlog.threshold.query.info: 5s

index.search.slowlog.threshold.query.debug: 2s

index.search.slowlog.threshold.query.trace: 500ms


index.search.slowlog.threshold.fetch.warn: 1s

index.search.slowlog.threshold.fetch.info: 800ms

index.search.slowlog.threshold.fetch.debug:500ms

index.search.slowlog.threshold.fetch.trace: 200ms



四、搭建es集群

1、搭建elasticsearch集群很简单,只要cluster.name设置一致,并且机器在同一网段下,启动的es会自动发现对方,组成集群。elasticsearch采用广播的方式自动发现节点,需要等待一段时间才能发现新的节点。搭建完成后, 集群健康从yellow恢复到green


2、默认的elasticsearch把自己和0.0.0.0地址绑定,HTTP传输的监听端口在[9200-9300],节点之间

通信的端口在[9300-9400]。(范围的意思是说如果一个端口已经被占用,它将会自动尝试下一个端口)


3、集群最好是3个以上节点,方便故障转移


4、默认情况下,eleasticsearch会把插件、日志、最重要的是你的数据都放在安装目录下。这可能会不幸的意外,通过安装新的elasticsearch就可能把安装目录覆盖了。如果你不小心,你可能擦除你所有的数据,建议更改数据、日志和插件路径

path.data: /home/elk/data

path.logs: /home/elk/logs

path.plugins: /home/elk/plugins




5、脑裂的危害:

这个配置一定程度地防止脑裂(无法发现部分节点)问题。设置最小主节点数Minimum Master Nodes。最小主节点数的设置对集群的稳定是非常重要的。该设置对预防脑裂是有帮助的,即一个集群中存在两个master。这个配置就是告诉elasticsearch除非有足够可用的master候选节点,否则就不选举master,只有有足够可用的master候选节点才进行选举。


6、该设置应该始终被配置为有主节点资格的法定节点数,法定节点数:(主节点资格的节点数/2)+1。

即最少需要2个节点才会选举master节点(即产生集群)。在配置文件的注释中看到官方的建议是,数字设置为【节点个数/2+1】,向上取整,本人的是3个节点,因此设置为2;


发现集群的超时时间为10s。默认情况下,一个节点会认为,如果master节点在3秒之内没有应答,那么这个节点就是死掉了,而增加这个值,会增加节点等待响应的时间,从一定程度上会减少误判。

discovery.zen.minimum_master_nodes: 2

discovery.zen.ping_timeout: 10s


7、节点类型

在配置集群中的节点时, 应该明确指定各节点的角色类型。如

(1)、node.mater:true & node.data:true

既为master,也为data节点,负责集群协调工作和数据存储等


(2)、node.mater:true & node.data:false

为master节点,负责集群协调工作等


(3)、node.mater:false & node.data:true

为data节点,负责索引数据和搜索等


(4)、node.mater:false & node.data:false

既不是master,也不是data节点,负责搜索负载均衡(从data节点抓取数据并作处理)


8、主节点配置

elasticsearch-node01配置:(我配了节点数之后,logstash和es起不来,不知道什么原因,我就不配了)

[root@ossec-server config]# egrep -v '^$|^#' /home/elk/elasticsearch-1.6.0/config/elasticsearch.yml 

cluster.name: elasticsearch

node.name: "elasticsearch-node01"

node.master: true

node.data: true

bootstrap.mlockall: true

http.max_content_length: 2000mb

http.compression: true

index.cache.field.type: soft

index.cache.field.max_size: 50000

index.cache.field.expire: 10m


9、从节点配置

elasticsearch-node02配置:

[root@elasticsearch-node02 ~]# yum install java-1.8.0-openjdk

[root@elasticsearch-node02 ~]# java -version

openjdk version "1.8.0_91"


[root@elasticsearch-node02 ~]# egrep -v '^$|^#' /usr/local/elasticsearch-1.6.0/config/elasticsearch.yml

cluster.name: elasticsearch

node.name: "elasticsearch-node02"

node.master: false

node.data: true

path.data: /home/elk/data

path.work: /home/elk/work

path.logs: /home/elk/logs

path.plugins: /home/elk/plugins

bootstrap.mlockall: true

transport.tcp.port: 9301

http.port: 9201

http.max_content_length: 2000mb

http.compression: true

index.cache.field.type: soft

index.cache.field.max_size: 50000

index.cache.field.expire: 10m


开启bootstrap.mlockall,需要执行ulimit -l unlimited

bootstrap.mlockall: true

ulimit -l unlimited


[root@elasticsearch-node02 config]# ulimit -n 65535


[root@elasticsearch-node02 config]# ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 62835

max locked memory       (kbytes, -l) unlimited

max memory size         (kbytes, -m) unlimited

open files                      (-n) 65535

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 62835

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited


[root@elasticsearch-node02 config]# cat /etc/security/limits.conf 

root             hard    memlock          unlimited

root             hard    memlock          unlimited


10、集群搭建完成之后,查看ossec-server上es集群状态,已变为green

[root@ossec-server config]# curl -XGET http://localhost:9200/_cluster/health\?pretty

{

  "cluster_name" : "elasticsearch",

  "status" : "green",

  "timed_out" : false,

  "number_of_nodes" : 3,

  "number_of_data_nodes" : 2,

  "active_primary_shards" : 216,

  "active_shards" : 432,

  "relocating_shards" : 0,

  "initializing_shards" : 0,

  "unassigned_shards" : 0,

  "number_of_pending_tasks" : 0,

  "number_of_in_flight_fetch" : 0

}



[root@elasticsearch-node02 ~]# curl -XGET http://localhost:9201/_cluster/health\?pretty

{

  "cluster_name" : "elasticsearch",

  "status" : "green",

  "timed_out" : false,

  "number_of_nodes" : 3,

  "number_of_data_nodes" : 2,

  "active_primary_shards" : 216,

  "active_shards" : 432,

  "relocating_shards" : 0,

  "initializing_shards" : 0,

  "unassigned_shards" : 0,

  "number_of_pending_tasks" : 0,

  "number_of_in_flight_fetch" : 0

}


由于我只搞了2台node,就不演示es故障转移了,需要的话请参考下面文章


参考文章:

http://www.searchtech.pro/articles/2013/02/18/1361194291548.html

http://www.cnblogs.com/dennisit/p/4133131.html