深圳龙岗企业网站建设,一级造价工程师含金量,网站js特效,简单动画制作文章目录1. 分布式文档存储1. 路由一个文档到一个分片中2. 主分片和副本分片如何交互3. 新建、索引和删除文档4. 取回一个文档5. 局部更新文档2. ElasticSearch相关问题1. 路由计算方式#xff1f;2. 分片控制3. 分布式文档写入(索引)的过程#xff1f;4. 分布式文档搜索的过…
文章目录1. 分布式文档存储1. 路由一个文档到一个分片中2. 主分片和副本分片如何交互3. 新建、索引和删除文档4. 取回一个文档5. 局部更新文档2. ElasticSearch相关问题1. 路由计算方式2. 分片控制3. 分布式文档写入(索引)的过程4. 分布式文档搜索的过程5. 分布式文档更新和删除的过程?1. 分布式文档存储
1. 路由一个文档到一个分片中
当索引一个文档的时候文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢当我们创建文档时它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢
首先这肯定不会是随机的否则将来要获取文档的时候我们就不知道从何处寻找了。实际上这个过程是根据下面这个公式决定的 shard hash(routing) % number_of_primary_shards routing 是一个可变值默认是文档的 _id 也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字然后这个数字再除以 number_of_primary_shards 主分片的数量后得到 余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数就是我们所寻求的文档所在分片的位置。
这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量因为如果数量变化了那么所有之前路由的值都会无效文档也再也找不到了。
所有的文档 API get 、 index 、 delete 、 bulk 、 update 以及 mget 都接受一个叫做 routing 的路由参数 通过这个参数我们可以自定义文档到分片的映射。一个自定义的路由参数可以用来确保所有相关的文档——例如所有属于同一个用户的文档——都被存储到同一个分片中。
2. 主分片和副本分片如何交互
为了说明目的, 我们 假设有一个集群由三个节点组成。 它包含一个叫 blogs 的索引有两个主分片每个主分片有两个副本分片。相同分片的副本不会放在同一节点所以我们的集群看起来像 Figure 8, “有三个节点和一个索引的集群” 我们可以发送请求到集群中的任一节点。 每个节点都有能力处理任意请求。 每个节点都知道集群中任一文档位置所以可以直接将请求转发到需要的节点上。 在下面的例子中将所有的请求发送到 Node 1 我们将其称为 协调节点(coordinating node) 。
3. 新建、索引和删除文档
新建、索引和删除 请求都是 写 操作 必须在主分片上面完成之后才能被复制到相关的副本分片如下图所示 Figure 9, “新建、索引和删除单个文档” . 以下是在主副分片和任何副本分片上面 成功新建索引和删除文档所需要的步骤顺序
客户端向 Node 1 发送新建、索引或者删除请求。节点使用文档的 _id 确定文档属于分片 0 。请求会被转发到 Node 3因为分片 0 的主分片目前被分配在 Node 3 上。Node 3 在主分片上面执行请求。如果成功了它将请求并行转发到 Node 1 和 Node 2 的副本分片上。一旦所有的副本分片都报告成功, Node 3 将向协调节点报告成功协调节点向客户端报告成功。
在客户端收到成功响应时文档变更已经在主分片和所有副本分片执行完成变更是安全的。
4. 取回一个文档
可以从主分片或者从其它任意副本分片检索文档 如下图所示 Figure 10, “取回单个文档” . 以下是从主分片或者副本分片检索文档的步骤顺序
1、客户端向 Node 1 发送获取请求。
2、节点使用文档的 _id 来确定文档属于分片 0 。分片 0 的副本分片存在于所有的三个节点上。 在这种情况下它将请求转发到 Node 2 。
3、Node 2 将文档返回给 Node 1 然后将文档返回给客户端。
在处理读取请求时协调结点在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡。
在文档被检索时已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。 在这种情况下副本分片可能会报告文档不存在但是主分片可能成功返回文档。 一旦索引请求成功返回给用户文档在主分片和副本分片都是可用的。
5. 局部更新文档
如 Figure 11, “局部更新文档” 所示update API 结合了先前说明的读取和写入模式。 以下是部分更新一个文档的步骤
客户端向 Node 1 发送更新请求。它将请求转发到主分片所在的 Node 3 。Node 3 从主分片检索文档修改 _source 字段中的 JSON 并且尝试重新索引主分片的文档。 如果文档已经被另一个进程修改它会重试步骤 3 超过 retry_on_conflict 次后放弃。如果 Node 3 成功地更新文档它将新版本的文档并行转发到 Node 1 和 Node 2 上的副本分片重新建立索引。 一旦所有副本分片都返回成功 Node 3 向协调节点也返回成功协调节点向客户端返回成功。
当主分片把更改转发到副本分片时 它不会转发更新请求。 相反它转发完整文档的新版本。请记住这些更改将会异步转发到副本分片并且不能保证它们以发送它们相同的顺序到达。 如果Elasticsearch仅转发更改请求则可能以错误的顺序应用更改导致得到损坏的文档。
2. ElasticSearch相关问题
1. 路由计算方式
1.1 路由解决的问题
当索引一个文档的时候文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢当我们创建文档时它如何决定这个文档应当被存储在分片 P0还是P1和P2中呢 首先这肯定不会是随机的否则将来要获取文档的时候我们就不知道从何处寻找了。实际上这个过程是根据下面这个公式决定的
shard hash(routing) % number_of_primary_shardsrouting 是一个可变值默认是文档的 id 也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字然后这个数字再除以 number_of_primary_shards 主分片的数量后得到余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数就是我们所寻求的文档所在分片的位置。 这就解释了为什么我们要在创建索引的时候就确定好主分片的数量并且永远不会改变这个数量因为如果数量变化了那么所有之前路由的值都会无效文档也再也找不到了。
你可能觉得由于Elasticsearch主分片数量是固定的会使索引难以进行扩容。实际上当你需要时有很多技巧可以轻松实现扩容。
所有的文档 API get 、 index 、 delete 、 bulk 、 update 以及 mget 都接受一个叫做 routing 的路由参数 通过这个参数我们可以自定义文档到分片的映射。一个自定义的路由参数可以用来确保所有相关的文档——例如所有属于同一个用户的文档——都被存储到同一个分片中。相同的路由值总是指向同一个分片。换个说法就是“之前使用某个路由值将文档存放在特定的分片上那么搜索时也去相应的分片查找该文档。”
1.2 路由实战
通过路由控制Elasticsearch选择将文档发送到哪个主分片。此时需要指定路由参数routing。路由参数值无关紧要可以选择任何值。重要的是在将不同文档放到同一个分片上时需要使用相同的值。简单地说给不同的文档使用相同的路由参数值可以确保这些文档被索引到相同分片中。向Elasticsearch提供路由信息有多种途径。最简单的办法是在索引文档时加一个routing URI参数。例如
查询时请求会被发送至所有的分片所以最关键的事情就是使用一个能均匀分发数据的算法让每个分片都包含差不多数量的文档。并不希望某个分片持有99%的数据而另一个分片持有剩下的1%这样做极其低效。
2. 分片控制
索引一个文档时这个文档会被存储到主分片中主分片再将数据拷贝到副本分片中而主分片和各个副本分片都在不同的节点上所以每个节点上都有zhangsan这个文档数据那我们要到哪个节点上获取这个文档数据呢
实际上我们可以发送请求到集群中的任一节点。 每个节点都有能力处理任意请求。 每个节点都知道集群中任一文档位置所以可以直接将请求转发到需要的节点上。 将所有的请求发送到节点 1我们将其称为协调节点。 但是当发送请求的时候 为了扩展负载更好的做法是轮询集群中所有的节点。
3. 分布式文档写入(索引)的过程
新建、索引和删除 请求都是写操作必须在主分片上面完成之后才能被复制到相关的副本分片如图所示新建索引和删除单个文档 以下是在主副分片和任何副本分片上面成功新建索引和删除文档所需要的步骤顺序
① 客户端向 节点 1 发送新建文档请求 节点 1就是协调节点。
② 协调节点根据文档的 id 确定文档属于分片 0 路由计算。请求会被转发到 节点 2因为分片0的主分片目前被分配在 节点 2 上。
③ 节点 2 在主分片上面执行请求写入文档。如果成功了它将请求并行转发到 节点 1 和 节点 3 的副本分片上。一旦所有的副本分片都报告写入成功, 节点 2 将向协调节点报告成功协调节点向客户端报告成功。
在客户端收到成功响应时文档变更已经在主分片和所有副本分片执行完成变更是安全的。
当协调节点接收到来自客户端对某个索引的写入文档请求时该节点会根据路由算法将该文档映射到某个主分片上然后将请求转发到该分片所在的节点。完成数据的存储后该节点会将请求转发给该分片的其他副分片所在的节点直到所有副分片节点全部完成写入协调节点向客户端报告写入成功。 如图所示一个包含3个节点的ES集群假设索引中只有3个主分片和6个副分片客户端向节点1发起向索引写入一条文档的请求在本次请求中节点1被称为协调节点。节点1判断数据应该映射到哪个分片上。假设将数据映射到分片1上因为分片1的主分片在节点3上因此节点1把请求转发到节点3上。节点3接收客户端的数据并进行存储然后把请求转发到副分片1所在的节点1和节点2上当所有副分片所在的节点全部完成存储后协调节点也就是节点1向客户端返回成功标志。
4. 分布式文档搜索的过程
可以从主分片或者从其它任意副本分片检索文档 如下图所示取回单个文档 以下是从主分片或者副本分片检索文档的步骤顺序
① 客户端向 节点 1 发送获取请求。
② 节点使用文档的 id 来确定文档属于分片 0 。分片 0 的副本分片存在于所有的三个节点上。 在这种情况下它将请求转发到 节点 3 。
③ 节点 3 将文档返回给 节点 1 然后将文档返回给客户端。
在处理读取请求时协调结点在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡。
当协调节点接收到来自客户端的获取某个索引的某文档的请求时协调节点会找到该文档所在的所有分片然后根据轮询算法在主/副分片中选择一个分片并将请求转发给该分片所在的节点该节点会将目标数据发送给协调节点协调节点再将数据返回给客户端。 一个包含3个节点的ES集群假设索引中只有3个主分片和6个副分片客户端向节点1发起向索引获取文档的请求在本次请求中节点1被称为协调节点。节点1判断数据应该映射到哪个分片上。假设将数据映射到分片1上分片1有主/副两种分片分别在节点2、节点1和节点3上。假设此时协调节点的轮询算法选择的是节点3那么它会将请求转发到节点3上然后节点3会把数据传输给协调节点也就是节点1最后由节点1向客户端返回文档数据。
在文档被检索时已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。 在这种情况下副本分片可能会报告文档不存在但是主分片可能成功返回文档。 一旦索引请求成功返回给用户文档在主分片和副本分片都是可用的。
5. 分布式文档更新和删除的过程?
update API 结合了读取和写入模式。 以下是部分更新一个文档的步骤
① 客户端向 节点 1 发送更新请求。
② 节点使用文档的 id 来确定文档属于分片 0 它将请求转发到主分片所在的 节点 2 。
③ 节点 2 从主分片检索文档修改 _source 字段中的 JSON 并且尝试重新索引主分片的文档。 如果文档已经被另一个进程修改它会重试步骤 3 超过 retry_on_conflict 次后放弃。
④ 如果 节点 2 成功地更新文档它将新版本的文档并行转发到 节点 1 和 节点 3 上的副本分片重新建立索引。 一旦所有副本分片都返回成功 节点 2 向协调节点也返回成功协调节点向客户端返回成功。
当主分片把更改转发到副本分片时 它不会转发更新请求。 相反它转发完整文档的新版本。请记住这些更改将会异步转发到副本分片并且不能保证它们以发送它们相同的顺序到达。 如果Elasticsearch仅转发更改请求则可能以错误的顺序应用更改导致得到损坏的文档。