架构师系列-搜索引擎ElasticSearch(九)- 分布式文档原理

索引的路由计算

当索引一个文档的时候,文档会被存储到一个主分片中, Elasticsearch如何知道一个文档应该存放到哪个分片中呢?

肯定不是随机的而是根据以下算法来决定的

shard = hash(routing)% number_of_primary_shards

1) routing值是一个任意字符串,它默认是_id,但也可以自定义

2) 这个routing字符串通过哈希函数生成一个数字,然后除以主切片的数量得到一个余数(remainder),余数的范围永远是0到number_of_primary_shards -1,这个数字就是特定文档所在的分片。

注意事项

         创建索引的时候就确定好主分片的数量,并且永远不会改变这个数量,数量的改变将导致上述公式的结果变化,最终会导致我们的数据无法被找到。

文档的写操作

        新建、索引和刷除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。

        下图是数据写入 P0 主分片的过程,master在这里起到一个协调节点的作用。

详细步骤

下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤。

1.客户端给 Node1 发送新建、索引或删除请求。
2.节点使用文档的 _id确定文档属于分片0,它转发请求到 Node3,分片0位于这个节点上
3.Node3在主分片上执行请求
4.Node 3保存文档,将数据保存到主分片
5.保存成功后,它转发请求到相应的位于Node1和 Node2的复制节点上
6.当所有的复制节点报告成功, Node3报告成功到请求的节点
7.请求的节点再报告给客户端,客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片

注意事项 

        把文档存储写入到primary shard,如果设置了index.write.wait_for_active_shards=1,那么写完主节点,直接返回客户端,如果 index.write.wait_for_active_shards=all,那么必须要把所有的副本写入完成才返回客户端。

验证

PUT /customer {"mappings":{"properties":{"name":{"type":"keyword"}}},         "settings":{"index":{"number_of_shards": 1,"number_of_replicas": 2,"write.wait for_active_shards": "a11"}}
}
POST customer/_doc
{"name": "张三"
}

搜索单个文档

根据文档ID如何搜索到文档?

分片或任意一个复制分片被检索。

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

更新单个文档

更新文档,必须先定位到主分片,修改文档后,再次同步到其他副本中才算完成。

以下是部分更新一个文档的步骤:
1.客户端向 Node 1发送更新请求,发现主分片在 Node 3
2.它将请求转发到主分片所在的 Node 3
3.Node 3从主分片检索文档,修改_source 字段中的JSON,并且尝试重新索引主分片的文档,如果文档已经被另一个进程修改,它会重试步骤3,超过 retry_on_conf1ict 次后放弃。
4.如果 Node 3成功地更新文档,它将新版本的文档并行转发到 Node1和 Node 2上的副本分片,重新建立索引,一旦所有副本分片都返回成功, Node 3 向协调节点也返回成功,协调节点向客户端返回成功。 

全文搜索

 对于全文搜索而言,文档可能分散在各个节点上,那么在分布式的情况下,如何搜索文档呢?
搜索,分为2个阶段,搜索(query)+取回(fetch)。

搜索

详细步骤

1、客户端发送一个search(搜索)请求给 Node 3创建了一个长度为from+size的空优先级队
2、Node 3 转发这个搜索请求到索引中每个分片的原本或副本。每个分片在本地执行这个查询并且结果将结果放到一个大小为 from+size 的有序本地优先队列里去。
3、每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点Node 3。Node 3把这些值合并到自己的优先队列里产生全局排序结果。

优先级队列

一个 优先队列 仅仅是一个存有 top-n 匹配文档的有序列表,优先队列的大小取决于分页参数 from 和size,如下搜索请求将需要足够大的优先队列来放入100条文档。

GET /_search {"from": 90,"size": 10
}

注意事项 

        当一个搜索请求被发送到某个节点时,这个节点就变成了协调节点
        这个节点的任务是广播查询请求到所有相关分片并将它们的响应整合成全局排序后的结果集合,这个结果集合会返回给客户端。
        第一步是广播请求到索引中每一个节点的分片拷贝,查询请求可以被某个主分片或某个副本分片处理,这就是为什么更多的副本(当结合更多的硬件)能够增加搜索吞吐率,协调节点将在之后的请求中轮询所有的分片来分摊负载。
        每个分片在本地执行查询请求并且创建一个长度为 from + size 的本地优先队列,也就是说,每个分片创建的结果集足够大,均可以满足全局的搜索请求,分片返回一个轻量级的结果列表到协调节点,它仅包含文档 ID 集合以及任何排序需要用到的值,例如_score
        协调节点将这些分片级的结果合并到自己的有序优先队列里,它代表了全局排序结果集合,至此查询过程结 

 取回

详细步骤

 

  1. 协调节点辨别出哪个document需要取回,并且向相关分片发出 GET 请求。
  2. 每个分片加载document并且根据需要 enrich 它们,然后再将document返回协调节点。
  3. 一旦所有的document都被取回,协调节点会将结果返回给客户端。

 注意事项


        协调节点首先决定哪些文档 确实需要被取回.
        例如,如果我们的查询指定了{"from":90, "size::l0},最初的90个结果会被丢弃,只有从第91开始的10个结果需要被取回,这些文档可能来自和最初搜索请求有关的一个或者多个甚至全部分片。

协调节点给持有相关文档的每个分片创建一个mu1ti-getrequest ,并发送请求给同样处理查询阶段的分片副本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/619940.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ - 类的默认成员函数

文章目录 前言一、构造函数二、析构函数三、拷贝构造函数四、重载赋值操作符五、取地址及const取地址操作符重载 前言 默认成员函数是编译器自动生成的,也可以自己重写,自己重写之后编译器就不再生成,下面是深入了解这些成员函数。 一、构造…

3dmax制作小熊猫的基本流程

1.透视图插入面片,改高度宽度,把参考图放进面片里。 2.角度捕捉切换,角度改为90 3.shift旋转,旋转面片,复制一个出来 4.在前视图,把参考图片中的正式图小熊猫的一半的位置(可以是眼睛&#x…

003 【笔记神器】Obsidian:打造属于自己的万能工作台

前言:Obsidian 是一款很多大神都在用的笔记软件,具有强大的功能,能够满足日常各种笔记的需求。强大之处在于:Obsidian 能够安装各种强大的插件,实现各种功能。 废话不多说,玩转 Obsidian 仅需这篇文章足矣&…

第G7周:Semi-Supervised GAN 理论与实战

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 参考论文:《Semi-Supervised Learning with Generative Adversarial Netw…

企业级OVSSL证书的五大优势

在数字化时代,企业级OVSSL(Organization Validation Secure Sockets Layer)证书已成为保护网站安全、提升用户信任度的重要工具。越来越多企业在自身网络安全方面更倾向于OVSSL证书,以下就带你了解企业级OVSSL证书的五大优势&…

【LeetCode】2635. 转换数组中的每个元素

转换数组中的每个元素 编写一个函数,这个函数接收一个整数数组 arr 和一个映射函数 fn,通过该映射函数返回一个新的数组。 返回数组的创建语句应为 returnedArray[i] fn(arr[i], i)。 请你在不使用内置方法 Array.map 的前提下解决这个问题。 示例 1:…

第 6 章 URDF、Gazebo与Rviz综合应用(自学二刷笔记)

重要参考: 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 6.7.2 雷达信息仿真以及显示 通过 Gazebo 模拟激光雷达传感器,并在 Rviz 中显示激光数据。 实现…

#381. 四边形继承练习

太爽了 甚至还现学了叉积判断线段是否相交和求面积的方法 先给出我的代码&#xff1a; #include <iostream> #include <vector> #include <iomanip> #include <cmath>using namespace std;//下面需要补充多个类的声明及实现代码 const double EPS 1…

RocketMQ 02 功能大纲介绍

RocketMQ 02 主流的MQ有很多&#xff0c;比如ActiveMQ、RabbitMQ、RocketMQ、Kafka、ZeroMQ等。 之前阿里巴巴也是使用ActiveMQ&#xff0c;随着业务发展&#xff0c;ActiveMQ IO 模块出现瓶颈&#xff0c;后来阿里巴巴 通过一系列优化但是还是不能很好的解决&#xff0c;之后…

小程序变更主体需要多久?

小程序迁移变更主体有什么作用&#xff1f;小程序迁移变更主体的好处有很多哦&#xff01;比如可以获得更多权限功能、公司变更或注销时可以保证账号的正常使用、收购账号后可以改变归属权或使用权等等。小程序迁移变更主体的条件有哪些&#xff1f;1、新主体必须是企业主体&am…

判断IQ水平-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第50讲。 判断IQ水平&#…

如何检测和避免线程死锁?

在日常开发中涉及到多线程开发时候就很容易会产生死锁 what: 什么是线程死锁? 线程死锁是指两个或两个以上的线程在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞现象。当这些线程互相持有对方所需要的资源时&#xff0c;会互相等待对方释放资源&am…