企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
#Elasticsearch学习笔记(三)Elasticsearch集群分片的读写操作流程 在上篇文章中详细介绍了Elasticsearch基于Lucene的单节点的准实时索引的实现,那么Elasticsearch是如何解决分布式下面的CRUD操作的呢? ## 1、路由计算(routing)和副本一致性(replica) **routing** Elasticsearch针对路由计算选择了一个很简单的方法,计算如下: routing = hash(routing) % number_of_primary_shards 每个数据都有一个routing参数,默认情况下,就使用其_id值,将其_id值计算hash后,对索引的主分片数取余, 就是数据实际应该存储到的分片ID 由于取余这个计算,完全依赖于分母,所以导致Elasticsearch索引有一个限制,索引的主分片数,不可以随意修改。因为一旦主分片数不一样,索引数据不可读。 副本一致性(replica) 作为分布式系统,数据副本可算是一个标配。Elasticsearch数据写入流程。自然涉及副本,在有副本配置的情况下,数据从发向Elasticsearch节点,到接到Elasticsearch节点响应返回,流向如下 ![](https://box.kancloud.cn/2016-03-10_56e11d2527f66.jpg) 1)客户端请求发送给Node1节点,这里也可以发送给气他节点 2)Node1节点用数据的_id计算出数据应该存储在shard0上,通过cluster state信息发现shard0的主分片在Node3节点上,Node1转发请求数据给Node3,Node3完成数据的索引,索引过程在上篇博客中详细介绍了。 3)Node3并行转发数据给分配有shard0的副本分片Node1和Node2上。当收到任一节点汇报副本分片数据写入成功以后,Node3即返回给初始的接受节点Node1,宣布数据写入成功。Node1成功返回给客户端。 新建、索引和删除都是写(write)操作,他们必须在主分片上成功完成才能赋值到相关的复制分片上。 replication:通过在客户端发送请求的URL中加入?replication=async,可以控制Node3在完成本机主分片写入后,就返回给Node1宣布写入成功。这个参数在2.0版本中已经被废弃 consistency:默认主分片在尝试写入时需要规定数量(quorum)或过半的分片(可以使主分片或复制分片)写入成功,就返回给客户端。consistency允许为one(只有一个主分片,与上面的replication等同) `int((primary+number_of_replica) / 2) +1` 默认只有一个分片,那么就必须要两个活动分片,当然,这个默认设置将阻止我们在单一节点集群中进行操作。为了避开这个问题,规定数量只有在number_of_replicas大于1时才生效,也就是默认分片情况下不生效。 timeout:如果集群出现异常,有些分片当前不可用,Elasticsearch默认会等待1分钟,看分片能否恢复, 副本设置和分片设置不一样,是可以随时调整的,有些较大的索引,甚至可以做optimize之前,先把副本全部取消掉,等optimize完成后,再重新打开开启副本,节约单个segment的重复归并消耗。 ## 2、shard的allocate配置 上文介绍了分片的索引过程,通过路由计算可以确定文本所在的分片id,那么分片在集群中的分配策略是如何确定的? 一般来说,某个shard分配在哪个节点上,是由Elasticsearch自动决定的。以下几种情况会触发分配动作。 - 新索引生成。 - 索引的删除 - 新增副本分片 - 节点增减引发的数据均衡 Elasticsearch还提供了一系列参数详细控制这部分逻辑: cluster.routing.allocation.enable参数用来允许分配哪种分片。默认是All,可选项还包括primaries和new_primaries。none则彻底拒绝分片。 cluster.routing.allocation.allow_rebalance参数用来控制什么时候允许数据均衡。默认是indices_all_active,即要求所有分片都正常启动成功以后,才可以进行数据均衡操作,否则的话,在集群重启阶段,会浪费太多流量了。 cluster.routing.allocation.cluster_concurrent_rebalance参数用来控制集群内同时启动的数据均衡任务个数。默认是2个。