ElasticSearch(四)-分布式文档存储

来源:互联网 发布:创世中文网数据查询 编辑:程序博客网 时间:2024/05/17 08:27

1.路由

文档存储在分片的算法

shard =hash(routing) % number_of_primary_shards

routing值是一个任意字符串,默认为_id,可以自定义;

从这可以看出,主分片的数量不能改变,假如改变文档的路由将全部失效。


2.分片交互

当我们发送请求,最好的做法是循环通过所有节点请求,这样可以平衡负载。


3.新建和索引和删除文档

这几种操作都是写操作,必须在主分片上完全成功,才能复制到相关副本节点。

假如现在有两个主分片和两个副本,三个节点,其中主分片0在节点三上

  • 客户端给Node 1发送新建、索引或删除请求。
  • 节点使用文档的_id确定文档属于分片0。它转发请求到Node 3,分片0位于这个节点上。
  • Node 3在主分片上执行请求,如果成功,它转发请求到相应的位于Node 1Node 2的复制节点上。当所有的复制节点报告成功,Node 3报告成功到请求的节点,请求的节点再报告给客户端。

副本replication默认为sync(同步),可以设置为异步async

不建议使用异步,因为可能发生不等待分片就绪的情况下发送过多的的请求,导致es过载。


Consistency(需要再研究)

写入需要规定数量或过半的分片可用,这样可以防止数据被写入到错的网络分区:

int( (primary + number_of_replicas) / 2 ) + 1

 

timeout

默认等待一分钟,可以设置,默认单位为ms,可以设置为30s

 

4.检索

  •   客户端给Node 1发送get请求。
  • 节点使用文档的_id确定文档属于分片0。分片0对应的复制分片在三个节点上都有。此时,它转发请求到Node 2
  • Node 2返回endangered给Node 1然后返回给客户端。

对于读请求,为了平衡负载,请求节点会为每个请求选择不同的分片:它会循环所有分片副本。

 

5.局部更新

  •  客户端给Node 1发送更新请求。
  • 它转发请求到主分片所在节点Node 3
  • Node 3从主分片检索出文档,修改_source字段的JSON,然后在主分片上重建索引。如果有其他进程修改了文档,它以retry_on_conflict设置的次数重复步骤3,都未成功则放弃。
  • 如果Node 3成功更新文档,它同时转发文档的新版本到Node 1Node 2上的复制节点以重建索引。当所有复制节点报告成功,Node 3返回成功给请求节点,然后返回给客户端。

对于副本的更新,主分片是这样做的:

转发给副本分片上不是更新请求,而是转发整个文档的新版本,而且这些事异步的。如果发送的更新请求有可能在异步的情况下,导致数据与主分片上不一致。

 

6.批量请求

  Mget的细节

  • 客户端向Node 1发送mget请求。
  • Node 1为每个分片构建一个多条数据检索请求,然后转发到这些请求所需的主分片或复制分片上。当所有回复被接收,Node 1构建响应并返回给客户端。

routing 参数可以被docs中的每个文档设置。

 

Bulk的细节

  • 客户端向Node 1发送bulk请求。
  • Node 1为每个分片构建批量请求,然后转发到这些请求所需的主分片上。
  • 主分片一个接一个的按序执行操作。当一个操作执行完,主分片转发新文档(或者删除部分)给对应的复制节点,然后执行下一个操作。复制节点为报告所有操作完成,节点报告给请求节点,请求节点整理响应并返回给客户端。

bulk API还可以在最上层使用replicationconsistency参数,routing参数则在每个请求的元数据中使用。

 

7.批量的格式说明

批量中每个引用的文档属于不同的主分片,每个分片可能被分布于集群中的某个节点上。这意味着批量中的每个操作(action)需要被转发到对应的分片和节点上。

如果每个单独的请求被包装到json数组中,可能需要的麻烦是:

  •    解析JSON为数组(包括文档数据,可能非常大)
  •    检查每个请求决定应该到哪个分片上
  •    为每个分片创建一个请求的数组
  •    序列化这些数组为内部传输格式
  •    发送请求到每个分片

本文出处:http://blog.csdn.net/shan1369678/article/details/51454709

0 0