[译]Elasticsearch Sequence ID实现思路及用途

原文地址:https://www.elastic.co/blog/elasticsearch-sequence-ids-6-0

如果

几年前,在Elastic,我们问自己一个"如果"问题,我们知道这将带来有趣的见解:

"如果我们在Elasticsearch中对索引操作进行全面排序会怎样?我们可以建立什么?

答案涵盖范围很广:

  • 我们可以构建一种称为"变更API"的功能,它可以接受操作ID,并为您提供自那时以来数据更改的列表。很棒!
  • 我们可以只查找发生变化的索引操作,从而建立增量reindex!
  • 我们可以使用增量reindex功能,通过过滤/连续reindex建立以实体为中心的索引!
  • 我们可以建立不依赖于数据按时、按顺序和全局精确时间戳到达的数据滚动/汇总索引!
  • 我们可以建立类似物化视图的东西,在新数据/操作到达时进行更新!
  • 如果节点之间的操作因网络断开等原因而丢失,我们可以建立一种重放操作的方法,这将大大加快恢复速度!
  • 我们可以建立一种在集群之间重放操作的方法!跨数据中心复制!

所有这些都需要打破一个小小的障碍:为索引操作添加序列号。很简单:我们只需要在主索引的每个操作中添加一个计数器!太简单了,我们看到社区成员和员工尝试了好几次。但当我们层层剥开洋葱头时,我们发现它比最初看起来要复杂得多。在我们开始讨论变更应用程序接口的实用性近6年后,我们仍然没有一个变更应用程序接口。原因何在?本博客的目的是分享幕后发生的事情,并就这个问题的答案提供一些见解。

在过去两年中,我们几乎从头开始重写了复制逻辑。我们从已知的学术算法中汲取精华,同时确保我们仍能确保并行性,这正是Elasticsearch能够如此快速的原因:这是许多甚至所有传统共识算法都无法做到的。我们与分布式系统专家合作,为我们的复制模型建立了TLA+规范。我们增加了大量测试和测试基础设施。

这篇博客必然是技术性的,因为我们会深入探讨Elasticsearch如何进行复制的一些核心内容。不过,我们的目的是通过解释/定义/链接一些术语(即使您可能已经理解了这些术语),让更多读者能够理解这些术语。首先,让我们深入了解Elasticsearch所面临的一些挑战。

挑战

在继续深入之前,我们必须先谈谈我们的复制模型以及它的重要性。在Elasticsearch数据索引中,数据被分割成所谓的"分片",基本上就是索引的子分区。你可以有5个主分片(基本上是索引的5个子分区),每个主分片可以有任意数量的主分片副本(称为副本)。但重要的是,每个子分区只有一个"主分片"。主分片首先接受索引操作(索引操作包括"添加文档"或"删除文档"等操作),然后将索引操作复制到副本。因此,在将每个操作转发给副本之前,不断递增计数器并为每个操作分配一个序列号是非常简单的。只要没有人重启服务器,网络正常运行时间达到100%,硬件不出现故障,没有长时间的Java垃圾回收事件,也没有人升级软件,这种简单易行的方法就能真正奏效。

但我们生活在现实世界中,当这些假设发生变化时,Elasticsearch就会进入"故障"模式和"恢复"过程。如果它们影响到运行主分片的节点,可能需要主分片停机,由另一个副本取而代之。由于变化来得突然,一些正在进行的索引操作可能尚未完全复制。如果您有2个或更多副本,其中一些操作可能只到达了其中一个副本,而没有到达另一个副本。更糟糕的是,由于Elasticsearch会并发索引文档(这也是Elasticsearch速度如此之快的原因之一!),每个副本都可能有不同的操作集,而这些操作集在另一个副本中并不存在。即使只运行一个副本(Elasticsearch的默认设置),也可能会出现问题。如果旧的主副本回来并被添加为副本,它可能包含从未复制到新主副本的操作。所有这些情况都有一个共同点:主节点失效后,分片上的操作历史可能会发生偏离,我们需要一些方法来解决这个问题。

PrimaryTerms & Sequence Numbers

我们采取的第一步是能够区分旧的和新的主分片。我们必须有一种方法来识别来自旧主分片的操作与来自新主分片的操作。此外,整个集群需要就此达成一致,以确保在出现问题时不会发生争执。这促使我们实现了主要术语。这些主要术语是增量的,并在主分片被提升时更改。它们被持久化在集群状态中,因此代表了集群所处的主分片的"版本"或"生成"。有了主要术语,操作历史中的任何冲突都可以通过查看操作的主要术语来解决。新术语优于旧术语。我们甚至可以开始拒绝那些太旧的操作,避免混乱的情况发生。

一旦我们设置了主要术语的保护机制,我们添加了一个简单的计数器,并开始为每个操作分配一个来自该计数器的序列号。因此,这些序列号使我们能够了解在主分片上发生的索引操作的特定顺序,我们可以将其用于接下来几节中将要讨论的各种目的。您可以在响应中看到分配的序列号和主要术语:

$ curl -H 'Content-Type: application/json' -XPOST http://127.0.0.1:9200/foo/doc?pretty -d '{ "bar": "baz" }'{"_index": "foo","_type": "doc","_id": "MlDBm10BditXXu4kjj5E","_version": 1,"result": "created","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 19,"_primary_term": 1
}

注意返回的响应中现在包含了_seq_no和_primary_term。

Local and Global Checkpoints

有了主要术语和序列号,我们理论上有了检测分片之间差异并在主分片失败时重新对齐它们的工具。拥有主要术语为x的旧主分片可以通过删除主要术语为x且不存在于新主分片历史记录中的操作来恢复,并且具有更高主要术语的缺失操作可以索引到旧主分片中。

不幸的是,当您同时每秒索引数十万甚至数百万个事件时,比较数百万次操作的历史记录实际上是不切实际的。存储成本过高,直接比较所需的计算工作将耗时过长。为了解决这个问题,Elasticsearch维护了一个名为全局检查点的安全标记。全局检查点是一个序列号,我们知道所有活动分片的历史记录都至少与之对齐。换句话说,所有序列号低于全局检查点的操作都已经被所有活动分片处理,并在各自的历史记录中是相等的。这意味着在主分片失败后,我们只需要比较新主分片和任何剩余副本之间最后已知的全局检查点以上的操作。当旧主分片恢复时,我们取其最后知道的全局检查点,并将其以上的操作与新主分片进行比较。这样,我们只需要比较需要比较的操作,而不是整个历史记录。

推进全局检查点的责任属于主分片。主分片通过跟踪副本上已完成的操作来实现这一点。一旦检测到所有副本已经超过给定的序列号,主分片将相应地更新全局检查点。分片副本不会一直跟踪所有操作,而是维护一个全局检查点的本地变体,称为本地检查点。本地检查点是一个序列号,该副本上处理了所有更低序列号的操作。每当副本确认(或ack)主节点的写操作时,它们也会向主节点提供更新的本地检查点。利用本地检查点,主节点就能更新全局检查点,然后在下一次索引操作中将全局检查点发送给所有分片副本。

下面的动画展示了在面对有损网络和突发故障等并发挑战时,随着序列号和全局/本地检查点的增加而发生的情况:

在这里插入图片描述

当索引操作从主分片发送到副本时,我们会跟踪每个副本确认收到的最高序列号,并将其称为全局检查点。主分片会告诉所有副本全局检查点是多少。因此,如果主分片切换,我们只需要比较和可能重新处理自上次全局检查点以来的操作,而不是磁盘上的所有文件。

全局检查点还具有另一个很好的特性——它代表了那些被保证会留下的操作(它们在所有活动分片的历史记录中),以及可能会被回滚的操作所在的区域,如果主分片在它们被完全复制并向用户确认之前恰好发生故障。这是一个微妙但重要的特性,对于未来的变更API或跨数据中心复制功能将是至关重要的。

第一个好处:更快恢复

在Elasticsearch6.0之前,我们跳过了实际恢复过程的工作原理。当Elasticsearch在副本处于离线状态后恢复副本时,它必须确保该副本与活动主分片完全相同。非活动分片具有同步刷新标记,以便快速进行验证,但具有活动索引的分片则没有任何保证。如果一个分片在仍有活动索引的情况下掉线,那么新的主分片将通过网络复制Lucene段(即磁盘上的文件)。如果这些分片很大,这可能是一个繁重且耗时的操作。这是因为在6.0之前,我们没有跟踪个别写操作(序列号),而在幕后,Lucene会将所有添加/更新/删除合并到更大的分段中,这样就无法恢复构成更改的单个操作…也就是说,除非你将事务日志保留一段时间。

这就是我们现在所做的:我们保留事务日志,直到它变的"过大"或"过旧",不再有必要继续保留它。如果副本需要"更新",我们会使用该副本已知的最后一个全局检查点,仅从主事务日志中回放相关更改,而不是昂贵的大文件复制。如果主事务日志"过大"或"太旧"而无法重放到副本,那么我们将回退到旧的基于文件的恢复方式。

如果您一直在运行一个大型集群,而该集群经常出现网络断开、重启、升级等情况,我们希望这将大大提高您的工作效率,因为您不必在分片恢复时长时间等待。

须知

正如上一节中提到的,事务日志保留直到它"过大"或"过旧"而不再需要保留。我们如何确定什么是"过大"或"过旧"呢?当然是可配置的!在6.0中,我们引入了两个新的事务日志设置:

*index.translog.retention.size:默认为512MB。如果事务日志超过这个大小,我们只保留这么多数据。
*index.translog.retention.age:默认为12小时。超过这个时间段,我们将不再保留事务日志文件。

这些设置很重要,因为它们影响新的、更快的恢复工作以及磁盘使用情况。较大的事务日志保留大小或较长的保留时间意味着您有更高的机会通过新的更快恢复来进行恢复,而不是依赖于旧的基于文件的恢复。然而,它们也伴随着一定的成本:这会增加磁盘利用率,而且请记住事务日志是按分片进行的。举个实际的例子,如果您有20个索引,每个索引有5个主分片,并且在12小时内写入大量数据,那么可能会导致额外205512mb=50GB的磁盘利用率,直到那12小时窗口过期为止。如果您在不同索引上有不同的恢复和大小需求,您可以根据需要在每个索引上进行调整。例如,如果您预计进行机器或节点维护,您可能需要考虑对事务日志保留窗口进行任何调整。

注意:在6.0之前,事务日志的大小在索引过程中也可以增长到512MB(默认值),根据index.translog.flush_threshold_size设置。这意味着新的保留策略不会改变活动分片的存储需求。这一变化影响了停止索引的分片。现在,我们不清理事务日志,而是将其保留另外12小时。

下一个优势:跨数据中心复制

正如文章开头提到的,如果我们能进行有序的索引操作,我们就能在Elasticsearch中做很多美妙的事情。虽然花了一些时间,但现在我们做到了。更快的恢复是我们决定构建的第一个用例:它允许我们测试我们添加的新功能。

但我们知道跨数据中心复制也是我们企业客户常常要求的功能,所以这是我们即将添加的另一个功能。这需要构建新的API、在复制之上增加新的监控功能,以及是的,还需要进行更多的测试和文档编写。

还有更多工作要做

正如您在序列号GitHub问题上看到的,我们在序列号功能上有了一个良好的开端,但仍有许多工作要做!我们认为迄今为止所做的工作代表了我们向前迈出的一大步,即使它还没有涵盖我们可以建立/围绕序列号的所有功能。如果您有兴趣继续关注我们的工作,请随时关注标有:Sequence IDs的ticket或PR,或直接在讨论区与我们联系!

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

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

相关文章

解锁PPTist的全新体验:Windows系统环境下本地部署与远程访问

文章目录 前言1. 本地安装PPTist2. PPTist 使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 在Windows系统环境中,如何本地部署开源在线演示文稿应用PPTist,并实现远程访问?本文将为您提供详细的部署和配置指南。 P…

一文学会Golang里拼接字符串的6种方式(性能对比)

g o l a n g golang golang的 s t r i n g string string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去。主要有以下几种拼接方式 拼接方式介绍 1.使用 s t r i n g string string自带的运算符 ans ans s2. 使用…

IEC61850读服务器目录命令——GetServerDirectory介绍

IEC61850标准中的GetServerDirectory命令是变电站自动化系统中非常重要的一个功能,它主要用于读取服务器的目录信息,特别是服务器的逻辑设备节点(LDevice)信息。以下是对GetServerDirectory命令的详细介绍。 目录 一、命令功能 …

Flink学习连载第二篇-使用flink编写WordCount(多种情况演示)

使用Flink编写代码,步骤非常固定,大概分为以下几步,只要牢牢抓住步骤,基本轻松拿下: 1. env-准备环境 2. source-加载数据 3. transformation-数据处理转换 4. sink-数据输出 5. execute-执行 DataStream API开发 //n…

数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall

数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 贵在坚持! 数据样例项目地址: * 相关项目 1)数据集可视化项…

Windows系统运行库软件游戏修复工具

本页面下载的资源包包括PC电脑常用的运行库和电脑必备组件,如您的电脑出现应用打不开,缺少dll链接库、闪退等现象可以尝试用下面软件修复。 本资源永久有效。 软件安装基本常识科普: 为什么要安装运行库?运行库默认安装到C盘&…

wireshark使用lua解析自定义协议

wireshark解析自定义协议 1.自定义的lua放入路径2.修改init.lua2.1 开启lua2.2 init.lua文件最后加入自己的lua文件位置,这里需要确保与自己的文件名相同 3.编写lua4.编写c抓包5.wireshark添加自定义协议如何加调试信息 1.自定义的lua放入路径 一般是自己软件的安装…

ISAAC Gym 7. 使用箭头进行数据可视化

在这里发布一个ISAAC GYM可以使用的箭头绘制类。 gymutil默认有WireframeBoxGeometry,WireframeBBoxGeometry, WireframeSphereGeometry三个线段集生成函数,可以绘制盒子和球体。绘制函数分别有draw_lines和draw_line。 同理,使…

【计算机网络】网段划分

一、为什么有网段划分 IP地址 网络号(目标网络) 主机号(目标主机) 网络号: 保证相互连接的两个网段具有不同的标识 主机号: 同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号 互联网中的每一台主机,都要隶属于某一个子网 -&…

机器学习周志华学习笔记-第5章<神经网络>

机器学习周志华学习笔记-第5章<神经网络> 卷王&#xff0c;请看目录 5模型的评估与选择5.1 神经元模型5.2 感知机与多层网络5.3 BP(误逆差)神经网络算法 5.4常见的神经网络5.4.1 RBF网络&#xff08;Radial Basis Function Network&#xff0c;径向基函数网络&#xff0…

MySQL数据库设计

数据库设计 数据库是用来存在数据的&#xff0c;需要设计合理的数据表来存放数据–能够完成数据的存储&#xff0c;同时能够方便的提取应该系统所需的数据 1. 数据库的设计流程 数据库是为应用系统服务的&#xff0c;数据库的数据存储也是由应用系统决定的 当我们进行应用系统开…

Spring Boot 3.x + OAuth 2.0:构建认证授权服务与资源服务器

Spring Boot 3.x OAuth 2.0&#xff1a;构建认证授权服务与资源服务器 前言 随着Spring Boot 3的发布&#xff0c;我们迎来了许多新特性和改进&#xff0c;其中包括对Spring Security和OAuth 2.0的更好支持。本文将详细介绍如何在Spring Boot 3.x版本中集成OAuth 2.0&#xf…

数据可视化复习2-绘制折线图+条形图(叠加条形图,并列条形图,水平条形图)+ 饼状图 + 直方图

目录 目录 一、绘制折线图 1.使用pyplot 2.使用numpy ​编辑 3.使用DataFrame ​编辑 二、绘制条形图&#xff08;柱状图&#xff09; 1.简单条形图 2.绘制叠加条形图 3.绘制并列条形图 4.水平条形图 ​编辑 三、绘制饼状图 四、绘制散点图和直方图 1.散点图 2…

logback 初探学习

logback 三大模块 记录器&#xff08;Logger&#xff09;、追加器&#xff08;Appender&#xff09;和布局&#xff08;Layout&#xff09; 配置文件外层最基本的标签如图示 xml中定义的就是这个三个东西下面进入学习 包引入参考springboot 官方文档 Logging :: Spring Boo…

Linux:自定义Shell

本文旨在通过自己完成一个简单的Shell来帮助理解命令行Shell这个程序。 目录 一、输出“提示” 二、获取输入 三、切割字符串 四、执行指令 1.子进程替换 2.内建指令 一、输出“提示” 这个项目基于虚拟机Ubuntu22.04.5实现。 打开终端界面如图所示。 其中。 之前&#x…

《图像梯度与常见算子全解析:原理、用法及效果展示》

简介:本文深入探讨图像梯度相关知识&#xff0c;详细介绍图像梯度是像素灰度值在不同方向的变化速度&#xff0c;并以 “pig.JPG” 图像为例&#xff0c;通过代码展示如何选取图像部分区域并分析其像素值以论证图像梯度与边缘信息的关联。接着全面阐述了 Sobel 算子&#xff0c…

项目进度计划表:详细的甘特图的制作步骤

甘特图&#xff08;Gantt chart&#xff09;&#xff0c;又称为横道图、条状图&#xff08;Bar chart&#xff09;&#xff0c;是一种用于管理时间和任务活动的工具。 甘特图由亨利劳伦斯甘特&#xff08;Henry Laurence Gantt&#xff09;发明&#xff0c;是一种通过条状图来…

A045-基于spring boot的个人博客系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现

一、编码问题 在计算机编程中&#xff0c;流&#xff08;Stream&#xff09;是一种抽象的概念&#xff0c;用于表示数据的输入或输出。根据处理数据的不同方式&#xff0c;流可以分为字节流&#xff08;Byte Stream&#xff09;和字符流&#xff08;Character Stream&#xff0…

Python爬虫项目 | 二、每日天气预报

文章目录 1.文章概要1.1 实现方法1.2 实现代码1.3 最终效果1.3.1 编辑器内打印显示效果实际应用效果 2.具体讲解2.1 使用的Python库2.2 代码说明2.2.1 获取天气预报信息2.2.2 获取当天日期信息&#xff0c;格式化输出2.2.3 调用函数&#xff0c;输出结果 2.3 过程展示 3 总结 1…