[ElasticSearch]原理之分布式文档存储(Distributed Document Store)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 之前的文章中,我们已经知道如何存储数据到索引中以及如何检索它。但是我们掩盖了数据存储到集群中以及从集群中获取数据的具体实现的技术细节(But we glossed over many technical details surrounding how the data is distributed and fetched from the cluster)。

之前的文章中,我们已经知道如何存储数据到索引中以及如何检索它。但是我们掩盖了数据存储到集群中以及从集群中获取数据的具体实现的技术细节(But we glossed over many technical details surrounding how the data is distributed and fetched from the cluster)。

1. 路由文档到分片中(Routing a Document to a Shard)

当你索引一篇文档时,它会存储到一个主分片中。但是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. 主分片与副本分片如何交互

假设我们有一个三个节点的集群。集群里有一个名称为blog的索引,有两个主分片(primary shards)。每个主分片都有两个副本。相同节点的副本不会分配到同一节点,最后如下图展示:

image

我们可以发送请求到集群中的任何一个节点,每个节点都有能力处理我们的请求。每个节点都知道集群中任意文档的存储位置,所以可以直接将请求转发到所需的节点(Every node knows the location of every document in the cluster,so can forward requests directly to the required node)。

在下面的例子中,我们将请求都发送到节点1上,我们将其称为协调节点(coordinating node)。

2.1 创建,索引和删除文档

创建,索引和删除请求都是写操作,所以必须在主分片上写操作完成之后才能被复制到相关的副本分片上(Create, index, and delete requests are write operations, which must be successfully completed on the primary shard before they can be copied to any associated replica shards)。

交互过程如下图所示:

image

下面是成功在主分片和副本分片上创建,索引以及删除文档所必须的步骤:

  • 客户端发送了一个新建,索引 或者 删除文档 请求给节点 1;
  • 节点 1 通过请求文档的 id 值判断出该文档应该被存储在分片 0 中,并且知道分片 0 的主分片 P0 位于节点 3 上。因此节点 1 会把这个请求转发给节点 3;
  • 节点 3 在主分片上执行请求。如果请求执行成功,节点 3 并行将该请求转发给节点 1 和节点 2 上的的副本分片(R0)。一旦所有的副本分片都成功地执行了请求,则向节点 3 报告成功,节点 3 向协调节点 (Node 1 )报告成功,协调节点向客户端报告成功。

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

有一些可选的请求参数允许您影响这个过程,可能以数据安全为代价提升性能。这些选项很少使用,因为Elasticsearch已经很快,但是为了完整起见,在这里阐述如下:

2.1.1 一致性

默认情况下,在尝试进行写操作之前,主分片需要规定数量(quorum)或大多数(majority)的分片副本shard copies(其中分片副本可以是主分片或副本分片 a shard copy can be a primary or a replica shard)。 这是为了防止将数据写入网络分区的“错误的一边wrong side”。 规定数量quorum定义如下:

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

一致性consistency值可以是one(只有主分片),all(主分片和所有的副本),或者默认值quorum,或者大多数的分片副本(The allowed values for consistency are one (just the primary shard), all (the primary and all replicas), or the default quorum, or majority, of shard copies.)。

请注意,number_of_replicas是索引设置中指定的副本数,而不是当前活跃的副本数。 如果指定索引有三个副本,则quorum将如下定义:

int( (primary + 3 replicas) / 2 ) + 1 = 3

但是,如果仅启动两个节点,则活跃的分片副本不满足规定数量,您将无法对任何文档进行索引或删除。

2.1.2 超时

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

备注

新索引默认有 1 个副本分片,这意味着为满足 规定数量 应该 需要两个活动的分片副本。 但是,这些默认的设置会阻止我们在单一节点上做任何事情。为了避免这个问题,要求只有当 number_of_replicas 大于1的时候,规定数量才会执行。

2.2 检索文档

我们可以从一个主分片(primary shard)或者它们任一副本中检索文档,流程如下图:

image

下面是从主分片或者副本分片上检索文档所需要的一系列步骤:

  • 客户端发送了一个 Get 请求给节点 1;
  • 节点 1 通过请求文档的 id 值判断出该文档被存储在分片 0 中。三个节点上都存有分片 0 的复制(节点1上R0,节点2上R0,节点3上P0)。这一次,它将请求转发给节点 2 。
  • 节点 2 返回文档给节点 1 ,节点 1 在返回文档给客户端。

对于读请求,对于每一次请求,请求节点都会选择一个不同的副本分本,达到负载均衡。通过轮询所有的副本分片。

在文档被检索时,已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。 在这种情况下,副本分片可能会报告文档不存在,但是主分片可能成功返回文档。 一旦索引请求成功返回给用户,文档在主分片和副本分片都是可用的。

2.3 局部更新文档

更新 API (Update API)融合了上面解释的两种读写模式,如下图所示:

image

下面是部分更新一篇文档所需要的一系列步骤:

  • 客户端发送了一个 Update 请求给节点 1;
  • 节点 1 通过请求文档的 id 值判断出该文档被存储在分片 0 中。并且知道分片 0 的主分片 P0 位于节点 3 上。因此节点 1 会把这个请求转发给节点 3;
  • 节点 3 从主分片(P0)上检索出指定文档,并更改_source字段中的JSON,修改完毕之后试着重新索引文档到主分片(P0)上。如果有人已经修改了该文档,那么会重复步骤3,如果尝试retry_on_conflict次还没有成功则放弃。
  • 如果节点 3 更新文档成功,节点 3 会把文档新版本并行发给节点 1 和 节点 2 上的副本分片,重新索引文档。一旦所有的副本分片返回成功,节点 3 向协调节点返回成功,协调节点向客户端返回成功。

基于文档的复制

当主分片把更改转发到副本分片时, 它不会转发更新请求。 相反,它转发完整文档的新版本。请记住,这些更改将会异步转发到副本分片,并且不能保证它们以发送它们相同的顺序到达。 如果Elasticsearch仅转发更改请求,则可能以错误的顺序应用更改,导致得到损坏的文档。

2.4 多文档模式

mget 和 bulk API的模式类似于单文档模式。 不同的是,协调节点知道每个文档存储在哪个分片中。 它将多文档请求分解成对每个分片的多文档请求,并将请求并行转发到每个参与节点。

一旦从每个节点接收到应答,将每个节点的响应整合到单个响应中,并返回给客户端

2.4.1 mget

如下图所示:

image

以下是使用单个 mget 请求取回多个文档所需的步骤顺序:

  • 客户端向节点 1 发送 mget 请求。
  • 节点 1 为每个分片构建多文档获取请求,然后并行转发这些请求到托管在每个所需的主分片或者副本分片的节点上。一旦收到所有应答, 节点 1 构建响应并将其返回给客户端。
2.4.2 bulk

bulk API,允许在单个批量请求中执行多个创建、索引、删除和更新请求,如下图所示:

image

bulk API 按如下步骤顺序执行:

  • 客户端向 节点 1 发送 bulk 请求。
  • 节点 1 为每个节点创建一个批量请求,并将这些请求并行转发到每个包含主分片的节点主机。
  • 主分片一个接一个按顺序执行每个操作。当每个操作成功时,主分片并行转发新文档(或删除)到副本分片,然后执行下一个操作。 一旦所有的副本分片报告所有操作成功,该节点将向协调节点报告成功,协调节点将这些响应收集整理并返回给客户端。

bulk API 还可以在整个批量请求的最顶层使用 consistency 参数,以及在每个请求中的元数据中使用 routing 参数。



相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
7天前
|
机器学习/深度学习 边缘计算 人工智能
第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025) 2025 2nd international Conference on Edge Computing, Parallel and Distributed Computing
第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025) 2025 2nd international Conference on Edge Computing, Parallel and Distributed Computing 机器学习 计算学习理论 数据挖掘 科学计算 计算应用 数字图像处理 人工智能
30 6
|
2月前
|
存储 JSON 数据库
Elasticsearch 分布式架构解析
【9月更文第2天】Elasticsearch 是一个分布式的搜索和分析引擎,以其高可扩展性和实时性著称。它基于 Lucene 开发,但提供了更高级别的抽象,使得开发者能够轻松地构建复杂的搜索应用。本文将深入探讨 Elasticsearch 的分布式存储和检索机制,解释其背后的原理及其优势。
191 5
|
3月前
|
存储 监控 负载均衡
检索服务elasticsearch分布式结构
【8月更文挑战第22天】
44 3
|
5天前
|
存储 Dubbo Java
分布式 RPC 底层原理详解,看这篇就够了!
本文详解分布式RPC的底层原理与系统设计,大厂面试高频,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 RPC 底层原理详解,看这篇就够了!
|
9天前
|
存储 索引
Elasticsearch分布式架构
【11月更文挑战第2天】
17 1
|
2月前
|
自然语言处理 搜索推荐 数据库
高性能分布式搜索引擎Elasticsearch详解
高性能分布式搜索引擎Elasticsearch详解
84 4
高性能分布式搜索引擎Elasticsearch详解
|
1月前
|
分布式计算 Hadoop 网络安全
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
30 1
|
1月前
|
存储 机器学习/深度学习 缓存
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
44 1
|
1月前
|
存储 缓存 数据处理
深度解析:Hologres分布式存储引擎设计原理及其优化策略
【10月更文挑战第9天】在大数据时代,数据的规模和复杂性不断增加,这对数据库系统提出了更高的要求。传统的单机数据库难以应对海量数据处理的需求,而分布式数据库通过水平扩展提供了更好的解决方案。阿里云推出的Hologres是一个实时交互式分析服务,它结合了OLAP(在线分析处理)与OLTP(在线事务处理)的优势,能够在大规模数据集上提供低延迟的数据查询能力。本文将深入探讨Hologres分布式存储引擎的设计原理,并介绍一些关键的优化策略。
97 0
|
2月前
|
机器学习/深度学习 自然语言处理 数据可视化
分布式表示(Distributed Representation)
分布式表示(Distributed Representation)
139 15