Elasticsearch分布式文档存储(四)

1.将文档路由到分片

索引文档时,它存储在单个主分片上。

Elasticsearch如何知道文档属于哪个分片?当我们创建一个新文档时,它是如何知道它是否应该将该文档存储在分片1或分片2上?

该过程不能是随机的,因为我们将来可能需要检索文档。事实上,它由一个简单的公式决定:

shard = hash(routing)%number_of_primary_shards

routing值是一个任意字符串,默认为文档 _id,但也可以设置为自定义值。

routing字符串通过散列函数传递以生成一个数字,该数字除以索引中的主分片数以返回余数。其结果范围为[0,number_of_primary_shards - 1],结果的值正好和某个分片对应。

这解释了为什么主分片的数量 只有在创建索引并且永远不会更改时才能设置:如果将来更改主分片的数量,则所有先前的路由值都将无效,并且永远不会找到文档。

所有文件的API( getindexdeletebulkupdatemget)都接受一个routing参数可用于自定义文档到分片映射。

可以使用自定义路由值来确保所有相关文档(例如,属于同一用户的所有文档)存储在同一个分片上。

2.主分片和副本分片如何交互

出于解释目的,让我们来 想象一下,我们有一个由三个节点组成的集群。它包含一个名为的索引blogs,它有两个主分片。每个主分片都有两个副本。

同一个分片的副本永远不会分配给同一个节点,因此我们的集群看起来像下图。

我们可以将请求发送到集群中的任何节点。 每个节点完全能够满足任何请求。

每个节点都知道集群中每个文档的位置,因此可以将请求直接转发到实际处理数据的节点。在后面的示例中,我们将发送所有请求Node 1,我们将其称为协调节点(直接和客户端交互的节点)

发送请求时,最好循环遍历群集中的所有节点,以便分散负载。

3.创建,索引和删除文档

创建,索引和删除 请求是操作,必须在主分片上成功完成,然后才能将它们复制到任何关联的副本分片,如下图所示

下面是在主分片和任何副本分片上成功创建,索引或删除文档所需的主要步骤:

客户端发送创建,索引或删除请求给Node 1

节点使用文档_id来确定文档属于分片0。它将请求转发到主分片0所在的节点Node3上。

Node 3在主分片上执行请求。如果是成功的,它并行转发请求给Node 1和 Node 2。一旦所有副本分片报告成功,Node 3向协调节点(这里是Node0)报告成功,该协调节点向客户端报告成功。

当客户端收到成功响应时,已在主分片和所有副本分片上执行文档更改。修改是安全的。

有许多可选的请求参数允许您改变此过程,可能以数据安全性为代价提高性能。

这些选项很少使用,因为Elasticsearch已经很快了,但为了完整起见,这里解释了它们:

consistency

默认情况下,主分片需要法定数量或大部分的分片副本(其中分片副本可以是主分片或副本分片)在尝试写入操作之前可用。这是为了防止将数据写入网络分区的“错误方”(少数派)。法定人数定义如下:

int((primary + number_of_replicas)/ 2)+ 1

允许的值consistencyone(仅主要分片),all (主要和所有副本),或默认quorum或大多数分片副本。

请注意,它number_of_replicas是索引设置中指定的副本数,而不是当前活动的副本数。如果您已指定索引应具有三个副本,则仲裁将如下所示:

int((主要+3个复制品)/ 2)+ 1 = 3

但是,如果仅启动两个节点,则将没有足够的活动分片副本来满足仲裁,并且您将无法索引或删除任何文档。

timeout
如果可用的分片副本不足,会发生什么?Elasticsearch等待,希望会出现更多的分片。默认情况下,它将等待最多1分钟。如果需要,可以使用timeout参数让它更快地中止:100是100毫秒,30s是30秒。

默认情况下,新索引具有1个副本,这意味着应该需要两个活动分片副本以满足需要的quorum。但是,这些默认设置会阻止我们对单节点群集执行任何有用的操作。为避免此问题,仅当number_of_replicas大于1时才强制要求仲裁。

4.检索文档

可以从主分片或其任何副本分片检索文档,如下图所示。

以下是从主分片或副本分片检索文档的步骤:

客户端发送get请求Node 1

节点使用文档_id来确定文档属于分片0。所有三个节点上都存在分片0的副本。在这种情况下,它将请求转发给Node 2(此时理论上任何一个节点都可以处理)

Node 2将文档返回到Node 1,Node1将文档返回给客户端。

对于读取请求,协调节点将在每个请求上选择不同的分片副本以平衡负载; 它循环遍历所有分片副本。

在索引文档时,文档可能已经存在于主分片上但尚未复制到副本分片。在这种情况下,副本可能会报告文档不存在,而主副本可能会成功返回文档。索引请求将成功返回给用户后,该文档将在主分片和所有副本分片上可用。

5.文档部分更新

updateAPI结合了读和写模式,如下图所示:

以下是用于对文档执行部分更新的步骤序列:

  1. 客户端发送更新请求到Node 1
  2. 它将请求转发到主分片所在的位置Node 3
  3. Node 3从主分片中检索文档,更改_source字段中的JSON ,并尝试在主分片上重新索引文档。如果文档已被其他进程更改,则会在放弃之前重试第3步retry_on_conflict次
  4. 如果Node 3已成功更新文档,则会将要重新编制索引的新版本的文档并行转发到副本分片Node 1 和Node 2。所有副本分片报告成功后, Node 3向协调节点报告成功,协调节点向客户端报告成功。

updateAPI也接受了routingconsistency和 timeout那些参数

当主分片转发到其副本分片时, 它不转发更新请求。相反,它转发整个文档的新版本。

请记住,这些更改会异步转发到副本分片,并且无法保证它们的到达顺序与它们的发送顺序相同。

如果Elasticsearch仅转发更改,则可能会以错误的顺序应用更改,从而导致文档损坏。

6.多文档模式

mgetbulkAPI 的模式 与个别文件类似。不同之处在于协调节点知道每个文档存在于哪个分片中。它将多文档请求分解为每个分片的多文档请求,并将这些请求并行转发到每个参与节点。

一旦它从每个节点收到答复,它就会将他们的响应整理成一个响应,并将其返回给客户端,如下图所示:

以下是使用单个mget请求检索多个文档所需的步骤序列:

  1. 客户端发送mget请求Node 1
  2. Node 1为每个分片构建一个多重获取请求,并将这些请求并行转发到存在对应主分片或者副本分片的节点。收到所有回复后,Node 1构建响应并将其返回给客户端。

一个routing参数可以为docs数组中的每个文档设置。

批量API,如图13“多文档更改bulk”所示,允许在单个批量请求中执行多个创建,索引,删除和更新请求。

图13.使用的多个文档更改 bulk

步骤顺序 其次是 bulkAPI如下:

  1. 客户端发送bulk请求Node 1
  2. Node 1 为每个分片构建批量请求,并将这些请求并行转发到托管每个涉及的主分片的节点。
  3. 主分片一个接一个地连续执行每个动作。当每个操作成功时,主服务器将新文档(或删除)并行转发到其副本分片,然后继续执行下一个操作。一旦所有副本分片报告所有操作成功,该节点就会向协调节点报告成功,协调节点整理响应并将它们返回给客户端。

bulkAPI也接受整个bulk请求指定consistency,并且每个子请求指定routing参数。

为什么是这样奇怪的格式?

当我们了解批量请求时,您可能会问自己,“为什么bulkAPI需要使用换行符的有趣格式,而不是仅仅发送包含在JSON数组中的请求,比如mget API?”

为了回答这个问题,我们需要解释一些背景:批量请求中引用的每个文档可能属于不同的主分片,每个分片都可以分配给集群中的任何节点。这意味着每个内部bulk请求需要被转发到正确的分片正确的节点上。

如果各个请求都包含在JSON数组中,那么这意味着我们需要执行以下操作:

  • 将JSON解析为数组(包括文档数据,可能非常大)
  • 查看每个请求以确定它应该转到哪个分片
  • 为每个分片创建一组请求
  • 将这些数组序列化为内部传输格式
  • 将请求发送到每个分片

它可以工作,但需要大量的RAM来保存基本上相同数据的副本,并且会创建更多的数据结构,Java虚拟机(JVM)必须花费时间进行垃圾收集。

相反,Elasticsearch进入网络缓冲区,在那里收到原始请求,并直接读取数据。它使用换行符来识别和解析小的action/metadata请求,以便决定哪个分片应该处理每个请求。

这些原始请求将直接转发到正确的分片。没有冗余的数据复制,没有浪费的数据结构。整个请求过程在尽可能少的内存中处理。

原文地址:https://www.cnblogs.com/gc65/p/10647959.html

时间: 2024-10-19 20:12:37

Elasticsearch分布式文档存储(四)的相关文章

[Elasticsearch] 分布式文档存储

本文翻译自Elasticsearch官方指南的distributed document store一章. 分布式文档存储 在上一章中,我们一直在介绍索引数据和获取数据的方法.但是我们省略了很多关于数据是如何在集群中被分布(Distributed)和获取(Fetched)的技术细节.这实际上是有意为之 - 你真的不需要了解数据在ES中是如何被分布的.它能工作就足够了. 在本章中,我们将会深入到这些内部技术细节中,来帮助你了解你的数据是如何被存储在一个分布式系统中的. 路由一份文档(Document

mongodb 分布式文档存储数据库

简述: MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型. Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引. 在高负载的

分布式文档存储数据库 MongoDB

MongoDB 详细介绍 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型.Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引. 整体架构: 内部架构: 它的特点是高性能.易部署.易使用,存储数据非常方便.主要功能特性有: 面向集合存储,易存储

章节首语-分布式文档存储(distributed document store)

在上一个章节,我们了解来向index插入和检索数据的所有的方法.但是对于数据是怎么样分布和检索的很多细节都没有进行详细的解释.这种分开讲解(没有详细的解释)是故意的,你不用知道ES中数据是怎么分布,怎么工作的,但是就知道他能工作就行了. 在本章节,我们将会深入的讲解内部的细节,帮助你数据是怎么存储在一个分布式的系统上的. 内容提示 你会对下面呈现的内容感兴趣的.你不用必须去了解和记忆使用ES的所有细节.这个章节是为高级使用者准备的. 阅读这个章节将会了解ES是怎么工作的,并且知道在如果将来的某些

007-elasticsearch【一】概述、Elasticsearch 访问方式、Elasticsearch 面向文档、常用概念

一.概述 Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上. Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目标是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API. 然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎. 它可以被下面这样准确的形容: 一个分布式的实时文档存储

27.初识分布式文档存储系统慨念

主要知识点: 初识distributed document store 一.distributed document store(分布式文档存储系统) Elasticsearch在运行起来以后,他的第一个最核心的功能就是一个分布式的文档数据存储系统.主要有以下三个慨念: 分布式的:es可以实现分布式,可以很方便的扩容. 文档数据:es可以存储和操作json文档类型的数据,而且这也是es的核心数据结构. 存储系统:es可以对json文档类型的数据进行存储,查询,创建,更新,删除等操作.满足了这些功

elasticsearch 路由文档到分片

路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是随机的,因为我们将来要检索文档.事实上,它根据一个简单的算法决定: shard = hash(routing) % number_of_primary_shards routing值是一个任意字符串,它默认是_id但也可以自定义.这个routing字符串通过哈希函数生成一个数字,然后除以主切片的数量

ElasticSearch部署文档(Ubuntu 14.04)

ElasticSearch部署文档(Ubuntu 14.04) 参考链接 https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html#setup-configuration https://www.elastic.co/guid

MySQL更改默认的数据文档存储目录

MySQL默认的数据文档存储目录为/var/lib/mysql.假如要把MySQL目录移到/home/data下需要进行下面几步: 1.创建目录 cd /opt && mkdir data 2.把MySQL服务进程停掉 mysqladmin -u root -p shutdown .. 或者 service mysqld stop 3.把/var/lib/mysql整个目录移到/home/data mv /var/lib/mysql/* /opt/data/ 这样就把MySQL的数据文档移