Elasticsearch 集群的详细分析

查看集群状态

curl -XGET http://localhost:9200/_cluster/health?pretty
返回:
{
“cluster_name” : “ccnu-resource-cluster”,
“status” : “green”,
“timed_out” : false,
“number_of_nodes” : 2,
“number_of_data_nodes” : 2,
“active_primary_shards” : 0,
“active_shards” : 0,
“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有3种状态,分别是green(所有主分片和复制分片都可用),yellow(所有主分片可用,但不是所有复制分片都可用)和red(不是所有主分片可用)。

分片(Shard)

Elasticsearch中的索引(index)是由分片(shard)构成的。比如我们集群中有个索引users,该索引由3个分片组成,那么这个users索引中的文档数据将分布在这3个分片中。

users索引中的文档是根据下面这个规则确定该文档属于哪个分片:
// routing值默认是文档的_id,number_of_primary_shards是索引的主分片个数
shard = hash(routing) % number_of_primary_shards

这3个分片可以进行复制,复制是为了实现容错性,比如复制1份,那么一共就需要6个分片(3个主分片+3个主分片复制出来的复制分片)。

// users索引的创建命令(主分片3个,复制1份):
curl -XPUT http://localhost:9200/users -d ’
{
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 1
}
}’

创建完users索引之后,es集群(单节点)分片情况如下:
这里写图片描述

由于users索引有3个分片,es内部会创建出3个分片,分别是P0、P1和P2(大写P指的是primary),且这3个分片都是主分片。users索引需要对分片进行复制1份,所以这3个主分片都需要复制1份,分别对应R0、R1和R2这3个复制分片(大写R指的是replica)。

这个时候我们的集群只有1个节点node-1,所以复制分片并没有起作用(如果复制分片和主分片在同一个节点了,那么这个复制分片的意义就不存在了。复制分片的意义在于容错性,当一个节点挂了,另一个节点上的分片可以代替挂掉节点上的分片)。

curl -XGET http://localhost:9200/_cluster/health?pretty
如果集群的状态变成了yellow。这是因为users索引中的分片需要复制1份,但是没有足够的机器用来存储复制出来的复制分片,还有其它的一些字段比如unassigned_shards字段为3,对应R0、R1和R2这3个未分配的复制分片。

主分片和复制分片均可用,status为green,情况如下:
这里写图片描述

我们往users索引中插入一条文档,如果返回的_shards为total=2,successful=2,代表有2个分片都创建成功了。

集群操作分析

ES中文档的新建、删除和修改都是先在主分片上完成的,在主分片上完成这些操作以后,才会进行复制操作。
例如:我们一共有3个节点node-1,node-2,node-3;一共有2个分片P0和P1;每个分片有2个副本比如P0有2个副本R0,R0。
这里写图片描述
提示:ES自动会处理,保证主分片和备分片不会出现在同一个节点上(防止单点故障)

当进行新建文档的时候过程如下

  1. 客户端给master节点node-1发送新建文档的请求
  2. node-1节点根据文档的_id,确定该文档是属于分片P0还是分片P1,假设这里是P1。P1在节点node-2上,故将请求转发到node-2
  3. node-2上的主分片P1处理文档成功,然后转发请求到node-1和node-3节点上的复制节点R1上
    这里写图片描述

当进行检索文档的时候过程如下

  1. 客户端给master节点node-1发送检索文档的请求
  2. node-1节点根据文档的_id,假设该文档属于分片P0。分片P0在3个节点中都存在(P0,R0,R0),随机请求到节点node-2的R0上,于是将请求转发给node-2节点
  3. node-2节点得到文档数据,并返回给node-1节点,node-1节点返回给客户端
    这里写图片描述

这里es集群会使用轮询的策略对读取不同节点上的分片中的文档数据,比如针对上图中的查询,下次查询就会读取node-3节点上的R0分片中的文档。

当对文档进行局部更新的时候过程如下

  1. 客户端给master节点node-1发送局部更新文档的请求
  2. node-1节点根据文档的_id,确定该文档属于分片P1,并发现找到分片P1的主分片在node-2节点上,转发请求到node-2节点上
  3. node-2节点在主分片P1中找出对应id的文档,修改文档内部的_source属性,之后对文档重建索引。如果这个文档已经被其它进程修改,会重试步骤3 retry_on_conflict 次数(retry_on_conflict可通过参数设置)
  4. 如果步骤3执行成功,node-2节点转发新版本的文档给node-1和node-3节点上的复制分片(R1),这2个节点对文档进行重建索引。一旦node-1和node-3节点上的复制分片处理成功,node-2节点返回成功给node-1节点,node-1节点返回给客户端
    这里写图片描述

节点(Node)

在分布式集群情况下,ES中的节点可分为4类:
1. master节点:配置文件中node.master属性为true(默认为true),就有资格被选为master节点,master节点用于控制整个集群的操作。比如创建或删除索引,管理其它非master节点等
2. data节点:配置文件中node.data属性为true(默认为true),就有资格被设置成data节点,data节点主要用于执行数据相关的操作。比如文档的CRUD
3. 客户端节点:配置文件中node.master属性和node.data属性均为false。该节点不能作为master节点,也不能作为data节点。可以作为客户端节点,用于响应用户的请求,把请求转发到其他节点
4. 部落节点:当一个节点配置tribe.*的时候,它是一个特殊的客户端,它可以连接多个集群,在所有连接的集群上执行搜索和其他操作

查询主节点信息

curl -XGET http://localhost:9200/_cat/master?v
返回:
这里写图片描述

查看节点信息

curl -XGET http://localhost:9200/_cat/nodes?v
返回:
这里写图片描述

查看分片信息

curl -XGET http://localhost:9200/_cat/shards?v
返回:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/andybegin/article/details/79731107
今日推荐