本文主要总结和集群管理的相关内容。
1. 发现和恢复模块
节点的启动主要包括两个过程:(1)发现 (2)恢复
1.1 发现(discovery)
当启动ES节点的时候,最先做的事情就是查找一个拥有相同集群名称且网络上可见的主节点,如果找到,这个新启动的节点就加入那个已经存在的集群,如果没有找到,这个节点就将自己选举为主节点(前提是配置允许)。
负责上述过程的就是发现模块,该模块主要有两个作用:
1. 选主节点
2. 发现新节点
1.1.1 发现模块
发现模块在默认情况下,ES假定配置了相同集群名称且可以使用组播来相互通信的节点可自动组成集群。
发现模块可以有多种实现,Zen为默认的实现,它默认使用组播来发现节点。该方式虽然方便,但是在生产环境下可能也会带来一些问题:
1. 可能会有意外节点的加入
2. 组播会产生大量不必要的通
处于以上问题,Zen允许使用单播模式。当使用单播时,集群外的节点会发送一个Ping到所有配置中指定的地址。通过该中方式,其通知集群中的所有节点,最后的结果是要么加入一个集群,要么组件一个新的集群。
1.1.2 主节点
发现模块除了提供了发现节点的功能外,选择主节点也是发现模块的主要功能之一。
默认情况下,所有节点都可以成为主节点,数据节点以及查询节点,但是某些情况下,可能只希望一些节点只能担任部分角色,此时可以通过如下的方式进行配置
- node.master:true|false,表明该节点是否可以为主节点
- node.data:true|false,表明该节点是否可以为数据节点
- node.ingest:true|false,表明该节点是否可以为聚合节点
对于一个大规模的ES集群,在网络出现故障的时候,很容易出现脑裂的情况(假如有是10节点,在某次网络出现故障时,3个节点脱离了网络,此时脱离的三个节点有可能它们自己选了一个主节点,此时便出现两个主节点,产生脑裂)。为了降低脑裂出现的概率,ES提供了discovery.zen.minium_master_nodes参数来定义了“想要组件集群至少需要的候选主节点(node.master=true的节点)数量”.
在ES集群中,主节点是唯一可以改变集群状态的节点,当它每次处理完一个状态更新请求,都会现在本地更新,然后发送给其他的节点,发送后会在一个指定的时间内等待其他节点的响应,对于一个繁忙的集群,可能需要增加主节点的等待时间(discovery.zen.publish_timeout)
1.1.3 故障检测
ES在运行的过程中会运行两个检测进程:
1. 主节点发送Ping请求到其他节点,检测其余节点的情况
2. 其他节点发送Ping到主节点,检测主节点是否可用
对于网络环境不稳定的情况,可能需要对检测的相关参数做适当的调整,参数如下(都以 discovery.zen.fd 为前缀):
Setting | Description |
ping_interval | How often a node gets pinged. Defaults to 1s. |
ping_timeout | How long to wait for a ping response, defaults to 30s. |
ping_retries | How many ping failures / timeouts cause a node to be considered failed. Defaults to 3. |
1.1.4 发现模块的实现
除了zen模块外,还支持一下集中发现模块
1. Azure 发现模块
2. Ec2发现模块
3. Google Compute Engine 发现模块
如有需要,可参考:https://www.elastic.co/guide/en/elasticsearch/reference/5.2/modules-discovery.html 了解各发现模块对应的配置
1.2 恢复(recovery)
集群建立后,就开始了恢复的操作,在恢复的过程中,ES从网关(gateway:负责存储ES集群正常运行所有数据的组件)读取元数据和索引,并准备需要使用的分片。主分片恢复完成后,ES就可以对外提供服务了,如果还有副本则继续对副本进行恢复。
1.2.1 网关模块(Gateway)
gateway模块用于存储es集群的元数据信息。这部分信息主要包括所有的索引连同索引设置和显式的mapping信息。集群元数据的每一次改变(比如增加删除索引等),这些信息都要通过gateway模块进行持久化。当集群第一次启动的时候,这些信息就会从gateway模块中读出并应用。
设置在node级别上的gateway会自动控制索引所用的gateway。比如设置了local gataway,则每一个在这个node上创建的index都会应用他们在索引级别的local gateway。如果索引不需要持久化状态,需要显式的设置为none(这也是唯一可以设置的值)。默认的gateway设置是local gateway。
1.2.1.1 Gateway 配置
- recovery after nodes/time:在一些场景下,集群的元数据信息只有在集群中一些节点启动之后或者一段时间间隔之后才能够恢复。这在集群重启的时候非常有用,而且可以充分利用节点的本地存储来从gateway模块中恢复数据(这将会大大缩短集群的恢复时间)。下边给出一些配额项的说明:
- gateway.recovery_after_nodes:集群启动恢复进程需要多少个节点启动(包括master 和 data)
- gateway.recovery_after_data_nodes:集群启动恢复进程需要多少个数据节点启动
- gateway.recovery_after_master_nodes:集群启动恢复进程需要多少个master节点启动
- gateway.recovery_after_time:在recovery_after_*_nodes个节点启动后,需要等到多长时间,再启动集群恢复进程。
- gateway.expected_nodes:期望多少个节点(包括master和data)进入集群后,启动恢复。一旦满足,gateway.recovery_after_time参数将忽略。
- gateway.expected_data_nodes:期望多少个数据节点进入集群后,启动恢复。
- gateway.expected_master_nodes:期望多少个master节点进入集群后,启动恢复。
给出一个配置例子:
gateway:
recover_after_time: 5m
expected_nodes: 2
上述配置表明:集群启动后5分钟启动恢复,但是一旦节点数目达到2,立刻启动回复。
注意:一旦元数据已经从gateway模块中恢复,这些配置将不再有效,直至下次集群全部重启。
在恢复元数据过程中,所有操作都将堵塞,为了避免和集群真实的元数据产生冲突。
1.2.1.2 本地网关(local gateway)
local gateway从每个节点的本地存储中恢复集群状态和索引,不需要节点之间的共享存储。local gateway的持久化是同步的,一旦一个操作执行了,数据就马上会持久化,供集群恢复使用。
配置gateway.recovery_after_nodes使其在绝大多数节点启动后再进行恢复是非常重要的。这将会确保恢复到最近的集群状态。,例如
gateway:
recover_after_nodes: 3
expected_nodes: 5
2. 使用cat管理集群
_cat用于查看集群当前状态,涉及到shard/node/cluster几个层次
2.1 基本参数
verbose: 显示列名, 请求参数为v
示例: curl localhost:9200/_cat/master?v
help: 显示当前命令的各列含义, 请求参数为help. 某些命令部分列默认不显示,可通过help该命令可显示的所有列
示例: curl localhost:9200/_cat/master?help
bytes: 数值列还原为原始值. 如diskSize, 默认转为以kb/mb/gb表示, 打开后还原为原始值
示例: curl localhost:9200/_cat/indices?bytes=b
header: 显示指定列的信息, 请求参数为h
示例: curl localhost:9200/_cat/indices?h=i,tm(显示集群各索引的内存使用)
2.2. 功能列表
_cat 支持的命令如下:
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/indices
/_cat/indices/{index}
/_cat/segments
/_cat/segments/{index}
/_cat/count
/_cat/count/{index}
/_cat/recovery
/_cat/recovery/{index}
/_cat/health
/_cat/pending_tasks
/_cat/aliases
/_cat/aliases/{alias}
/_cat/thread_pool
/_cat/plugins
/_cat/fielddata
/_cat/fielddata/{fields}
/_cat/nodeattrs
/_cat/repositories
/_cat/snapshots/{repository}
详细说明可参考:https://www.elastic.co/guide/en/elasticsearch/reference/5.2/cat.html
3. 快照和恢复
虽然ES集群本身已经提供了一套完美的数据管理方案,但是当面对网络分割或是网络分区时还是可能会存在数据损坏和丢失的情况,此时可以通过ES提供的快照和恢复模块来解决该问题。
快照和恢复 模块允许创建单个索引或者整个集群的快照到远程仓库. 在初始版本里只支持共享文件系统的仓库,但是现在通过官方的仓库插件可以支持各种各样的后台仓库。
3.1 仓库
在进行任何快照或者恢复操作之前必须有一个快照仓库注册在Elasticsearch里。下面的这个命令注册了 一个名为my_backup 的共享文件系统仓库,快照将会存储在 /mount/backups/my_backup 这个目录。
$ curl -XPUT 'http://localhost:9200/_snapshot/my_backup' -d '{
"type": "fs",
"settings": {
"location": "/mount/backups/my_backup",
"compress": true
}
}'
一旦仓库被注册了,就可以只用下面的命令去获取这个仓库的信息
$ curl -XGET 'http://localhost:9200/_snapshot/my_backup?pretty'
{
"my_backup" : {
"type" : "fs",
"settings" : {
"compress" : "true",
"location" : "/mount/backups/my_backup"
}
}
}
目前支持的仓库类型主要包括:
- repository-s3 :for S3 repository support
- repository-hdfs: for HDFS repository support in Hadoop environments
- repository-azure: for Azure storage repositories
- repository-gcs :for Google Cloud Storage repositories
仓库的详细配置,可参考对应的文档
3.2 快照
一个仓库可以包含同一个集群的多个快照。快照根据集群中的唯一名字进行区分。 在仓库 my_backup 里创建一个名为snapshot_1 的快照可以通过下面的命令:
$ curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"
wait_for_completion 参数指定创建snapshot的请求是否等待快照创建完成再返回。 默认情况下,集群中所有打开和启动的索引是自动创建快照的。可以通过在快照请求里列出需要创建快照的索引.
索引创建快照的过程是增量的。在给索引创建快照的过程中,Elasticsearch会分析存储在仓库中的索引文件并且只会复制那些自从上次快照 之后新建或有所更新的文件。这使得多个快照以一种紧凑的方式存储在同一个仓库里。创建快照的过程是以非阻塞方式执行的。一个索引在创 建快照的同时能够被检索和查询。尽管如此,快照保存的是在开始进行创建快照的那个时间点的索引的视图。所以,在开始创建快照之后的记 录不会出现在这个快照里。在主分片启动之后创建快照的过程就会立即开始,并且之后不会改变位置。在1.2.0版本之前如果集群重新定位或者 新加入快照的索引初始化主分片会导致快照操作失败。从1.2.0版本开始,Elasticsearch会等待重新定位和初始化分片然后再创建快照。
任何时候在集群里只能有一个创建快照的操作在执行。当一个分片正在创建快照的时候,这个分片就不能被迁移到别的节点,因为这会影响重 新平衡和分配过滤的过程。一旦这个分片的快照建立完成,这个分片就可以根据现有的分配过滤和重新平衡算法被迁移到别的节点上。
如果快照已经建立,我们可以通过如下的命令去获得快照的信息:
$ curl -XGET "localhost:9200/_snapshot/my_backup/snapshot_1"
通过如下的命令可以把仓库里所有的快照列出来:
$ curl -XGET "localhost:9200/_snapshot/my_backup/_all"
可以通过如下的命令将仓库里的某个快照删除:
$ curl -XDELETE "localhost:9200/_snapshot/my_backup/snapshot_1"
当一个快照从仓库里删除之后,Elasticsearch会把所有和这个快照相关并且不被其它快照使用的文件删除。如果对正在创建的某个快照执行 删除操作,则创建快照的过程会被取消,并且会把创建过程中所有已经创建的文件删除。因此,删除操作可以用来取消那些由于误操作引起的 长时间运行的快照操作。
3.3 恢复
快照可以使用如下的操作来恢复:
$ curl -XPOST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore"
恢复操作可以在正在运行的集群上操作。尽管如此,已经存在的index只有在关闭之后才能被恢复。恢复操作会自动打开关闭的恢复的索引, 并且如果索引不存在将会创建新的索引。
关于快照与恢复的详细说明与配置,可参考:https://www.elastic.co/guide/en/elasticsearch/reference/5.2/modules-snapshots.html
4. 部落节点(Tribe node)
部落节点可以跨越多个集群,它可以接收每个集群的状态,然后合并成一个全局集群的状态,它可以读写所有节点上的数据,部落节点在elasticsearch.yml中的配置如下:
tribe:
t1:
cluster.name: cluster_one
t2:
cluster.name: cluster_two
T1和T2是任意的名字代表连接到每个集群。上面的示例配置两集群连接,名称分别是T1和T2。默认情况下部落节点通过广播可以做为客户端连接每一个集群。大多数情况下,部落节点可以像单节点一样对集群进行操作。
4.1 通过部落节点读取数据
当从部落节点读取数据时,相同的操作会在说有的集群上执行,合并后的结果会返回给客户端。除了基本的查询外,还可以通过部落节点执行过滤,suggestor等复杂的操作。
除了读取索引数据外,还可以通过部门节点读取集群的健康状态等数据。
4.2 通过部落节点写入数据
可以通过部落节点将数据写到已经存在的索引上,但是不可以通过部落节点执行类似于“创建索引”这样的主节点级别的写操作。
4.3 索引冲突
当部落节点连接的多个集群出现名称相同的索引时,部落节点会不知所措,默认情况下,将只有一个集群的数据会被返回。
针对冲突,ES提供了三种策略:
- Any:默认值,ES会从集群中选择一个索引
- drop:ES将会忽略同名索引,换句话说同名的索引将会被屏蔽
- prefer_XXX:出现冲突时,从XXX集群上选择数据。
4.4 屏蔽写操作
部落节点可以设置屏蔽所有的写操作和所有修改元数据的请求
4.4.1 全局设置
tribe:
blocks:
write: true
metadata: true
上述配置使部落节点只能执行查询的操作。
4.4.2 索引级别
tribe:
blocks:
write.indices: hk*
metadata.indices: hk*
上述配置屏蔽了所有以hk开头索引的写操作。