Elasticsearch入门-5.分布式文档存储

1. 文档分片公式

文档被存储到哪个主分片由一个特定公式计算得到:

1
shard = hash(routing) % number_of_primary_shards

routing:默认是文档_id,可自定义。

公式中的主分片数量在索引创建时就固定不变了。

2. 主副分片交互

如图为有3个节点的es集群:

es3节点集群

任意分片的主分片和副分片不会在同一节点上,但是任意请求可以发送到集群中的任意节点。

2.1 新建、索引、和删除单个文档

单个文档的新建、索引、删除

请求过程:

  1. 客户端向Node1发送新增、索引、删除请求
  2. 计算出文档属于分片0,转发请求到分片0所在主分片Node3
  3. Node3执行请求,请求成功后并行转发到Node1和Node2,半数副分片(Quorum策略)都执行成功后返回

另外,特殊情况下可能会牺牲部分数据安全性来提示性能:

consistency

​ 在集群中执行一个写操作时,如果replicas大于1(避免单节点无法执行)至少有(primary + replicas) / 2 + 1个副分片处于活跃状态才能继续,这样可以保证大多数分片数据时正确的,避免网络或其他故障导致数据不一致。可以将consistency设置为one(主分片活跃就允许写入)来提升性能。

timeout

​ 如果没有足够的副分片es会进行等待,等待的时间默认1分钟,也可以通过配置timeout来自定义,例如10030s

2.2 取回单个文档

取回单个文档

请求过程:

  1. 客户端请求Node1
  2. Node1根据文档id计算文档所属分片0,请求轮询转发至副分片0所在Node,Node2返回文档至Node1
  3. Node1返回文档

注意:如果一个文档已经被索引到主分片,正在同步到副分片,则此时副分片可能查询不到结果

2.3 文档局部更新

文档局部更新

请求过程:

  1. 客户端向Node1发送请求
  2. 请求转发至主分片所在Node3
  3. Node3尝试修改_source字段中的JSON,尝试重新索引文档,如果文档已经被其他进程修改则重试步骤3,超过retry_on_conflict后返回失败
  4. 如果Node3更新成功,则将新版本文档(只转发请求可能会因为请求乱序导致文档损坏)并行转发到Node1和Node2重新索引,所有副分片更新成功后返回更新成功

2.4 多文档模式

mget多文档读

mget取回多文档

请求过程:

  1. 客户端向Node1发送请求
  2. Node1为每个分片构建一个多文档获取请求,然后并行转发到主副分片,主副分片响应后将文档返回给客户端

bulk多文档写

bulk修改多文档

请求过程:

  1. 客户端向Node1发送请求
  2. Node1为每个节点创建一个多文档写入请求,然后将请求并行转发到包含主分片的节点
  3. 主分片按顺序执行,每个操作成功后立刻并行转发新文档到副分片,完成所有操作后报告协调节点
  4. 协调节点响应客户端