ElasticSearch - 文档存储

重构地球

shard

确定shard的公式:

shard = hash(routing) % number_of_primary_shards

routing 默认是文档的 _id ,也可以设置成一个自定义的值。

因此要在创建索引的时候就确定好主分片的数量,并且永远不会改变这个数量,因为如果数量变化了,那么所有之前路由的值都会无效。

每个节点都知道集群中任一文档位置,所以可以直接将请求发到任意节点。当然,为了扩展负载,更好的做法是轮询发送集群中所有的节点。

shard、replica同步

新建、索引或者删除请求

elas_0402.png

步骤:

  1. 户端向 Node 1 发送新建、索引或者删除请求。
  2. 节点使用文档的 _id 确定文档属于shard 0 。请求会被转发到 Node 3(因为shard 0 被分配在 Node 3 上)。
  3. Node 3 在shard 0上面执行请求。如果成功了,它将请求并行转发到 Node 1 和 Node 2 的replica R0上。一旦所有的R0都报告成功, Node 3 将向Node 1报告成功,Node 1向客户端报告成功。

查询请求

elas_0403.png

步骤:

  1. 客户端向 Node 1 发送查询请求。
  2. node 1使用文档的 _id 来确定文档属于shard 0 。replica 0 存在于Node 1、Node 2上。 这种情况下,每次请求都会轮询路由Node 1、Node 2,这里假设路由到Node 2。
  3. Node 2将文档返回给Node 1 ,然后Node 1将文档返回给客户端。

注意:
在文档被检索时,已经被索引的文档可能已经存在于shard上但是还没有复制到replica。即强一致性无法保证,但最终一致性可以保证。

更新请求

POST /{index}/{type}/{id}/_update

elas_0404.png

步骤略。
注意:
Node 3 从P0检索文档,修改 _source 字段中的 JSON ,并且尝试重新索引主分片的文档。 如果文档已经被另一个进程修改(_version冲突),它会重试步骤 3 ,超过 retry_on_conflict 次后放弃。
如果 Node 3 成功地更新文档,它将新版本的文档并行转发(新建、索引或者删除请求的步骤里转发的是请求而不是文档)到 Node 1 和 Node 2 上的R0,重新建立索引。一旦所有R0都返回成功,Node 3 向Node 1返回成功,Node 1向客户端返回成功。

为什么要转发文档而不是请求?
因为转发请求是异步的,不能保证到达replica的顺序,若转发更新请求,则可能以错误的顺序应用更改,导致得到损坏的文档。而转发文档,则replica可以直接根据_version来获取最大版本号的文档。

批量请求(_mget 、_bulk)

elas_0406.png

bulk步骤:

  1. 客户端向 Node 1 发送 bulk 请求。
  2. Node 1 为每个命中的shard创建一个批量请求,并将这些请求并行转发到每个包含该shard的节点。
  3. shard按顺序(请求报文体中的子请求顺序)执行每个操作。当一个子请求操作成功时,shard并行转发新文档(或删除)到replica,然后执行下一个子请求。 一旦所有的子请求的replica向shard报告完成(无论执行是否成功),该shard将向node 1报告,node 1将这些响应收集整理并返回给客户端。

可选的请求参数

  • consistency

    解决分布式脑裂问题,参数的值可以设为 one (只要该index的shard状态 ok 就允许执行_写_操作),all(必须要该index的shard和多个replica的状态没问题才允许执行_写_操作), 或 quorum (默认值)。

    # quorum 即大于一半的分片,注意,number_of_replicas是primary shard对应的replica数量,不是全部replica数量
    int( (primary + number_of_replicas) / 2 ) + 1
    

    注意:新索引默认有 1 个replica,这意味着为了满足consistency至少需要两个活动的node。 这就会阻止我们在单一node上做任何事情。为了避免这个问题,ES要求只有当 number_of_replicas 大于1的时候,consistency策略才会执行。

  • timeout
    如果没有足够的replica,Elasticsearch会等待,直到满足consistency策略。默认最多等待1分钟。 你可以使用 timeout 参数 使它更早终止: 100 是100毫秒,30s 是30秒。

一个Lucene索引在Elasticsearch称作shard。 一个Elasticsearch索引是shard的集合。

阅读 2.4k

rust-zero

68 声望
4 粉丝
0 条评论

rust-zero

68 声望
4 粉丝
文章目录
宣传栏