一、ES 的任意节点均可以做为协调(Coordinating)节点接受请求(包括新建、索引或者删除请求),每一个节点都知道集群中任一文档位置;html
二、协调节点会经过 routing 字段计算出一个主分片(primary shard),并把请求路由到主分片所在节点(routing 是一个可变值,默认是文档的 _id) ;node
shard = hash(routing) % number_of_primary_shards
tips:这就解释了为何咱们要在建立索引的时候就肯定好主分片的数量,而且永远不会改变这个数量:由于若是数量变化了,那么全部以前路由的值都会无效,文档也再也找不到了。算法
三、在主分片节点上,数据会先被写入(index buffer)中,同时写入 translog,这个时候数据还不能被搜索到(这个也是 es 是近实时搜索的缘由);缓存
tips:整个过程大部分在内存中,若是断电就会致使数据丢失。所以,ES 引入了 translog,数据写入内存时,会同时写入 translog(会当即落盘),来保证数据不丢失。负载均衡
四、通过一段时间(默认 1s)或者 index buffer 满了(默认 jvm 的 10%),会将 index buffer 中的文档 refresh 到系统文件缓存(os cache),而后再刷入到 lucene 的底层文件 segment 中,同时创建倒排索引,这个时候文档是能够被搜索到的;jvm
五、 因为 segment 的不可变性,随着 segment 愈来愈多,每打开一个 segment 就会消耗一个文件句柄,致使查询性能愈来愈差。这时,ES 后台会有一个单独线程专门合并 segment,将零碎的小的 segment 合并成一个大的 segment;elasticsearch
六、通过一段时间(默认30 min)或者 tanslog 满了(默认512M),会将文件系统缓存的 segment 落盘;分布式
七、若是主分片所在的节点请求执行成功,它会将请求同步转发到副本分片所在节点,作到主副数据的一致性,一旦全部的副本分片都报告成功,主分片节点将向协调节点报告成功,协调节点向客户端报告成功。所以,数据写入,主副本之间采用的是同步写入过程。ide
tips:写一致性默认的策略是 —— Quorum ,即大多数的分片副本状态没问题才容许执行写操做。性能
八、当集群中某个节点宕机,该节点上全部分片中的数据所有丢失(既有主分片,又有副分片);丢失的副分片对数据的完整性没有影响,丢失的主分片在其余节点上的副分片会被选举成主分片;因此整个索引的数据完整性没有被破坏。
九、若是是删除操做,refresh 的时候就会生成一个 .del 文件,逻辑删除,将这个 document 标识为 deleted 状态,在搜索的搜索的时候就不会被搜索到了。
十、若是是更新操做,就是将原来的 document 标识为 deleted 状态,而后新写入一条数据。
GET my-index/_doc/0
一、ES 的任意节点均可以做为协调(Coordinating)节点接受请求,每一个节点都知道集群中任一文档位置;
二、协调节点对 id 进行路由,从而判断该数据在哪一个 shard,而后将请求转发给对应的节点,此时会使用随机轮询算法,在 primary shard 和 replica shard 中随机选择一个,让读取请求负载均衡,
三、处理请求的节点返回 document 给协调节点。
四、协调节点,返回 document 给客户端。
GET /my-index/_search { "query": { "match_all": {} } }
一、ES 的任意节点均可以做为协调(Coordinating)节点接受请求,每一个节点都知道集群中任一文档位置;
二、协调节点进行分词等操做后,去查询全部的 shard 节点。
三、全部 shard 将知足条件的数据(id、排序字段等)信息返回给协调节点。
四、协调节点将数据从新进行排序,获取到真正须要返回的数据的 id。
五、协调节点再次请求对应的 shard (此时有 id 了,能够直接定位到对应shard)。
六、获取到全量数据,返回给客户端。
tips: ES 要尽可能避免深度分页查询,由于每一个 shard 都会返回 from+size 的数据。好比咱们要每页显示 10 条,查询第 10000 页数据,那么每一个分片就要返回10010 条数据,协调节点要处理更多的数据,这会严重的影响性能。
参考博文: