Elasticsearch 中的热点以及如何使用 AutoOps 解决它们

作者:来自 Elastic Sachin Frayne

探索 Elasticsearch 中的热点以及如何使用 AutoOps 解决它。

Elasticsearch 集群中出现热点的方式有很多种。有些我们可以控制,比如吵闹的邻居,有些我们控制得较差,比如 Elasticsearch 中的分片分配算法。好消息是,新的 desire_balance cluster.routing.allocation.type 算法(参见 shards-rebalancing-heuristics)在确定集群中的哪些节点应该获得新分片方面要好得多。如果存在不平衡,它会为我们找出最佳平衡。坏消息是,较旧的 Elasticsearch 集群仍在使用平衡(balanced)分配算法,该算法的计算能力较有限,在选择节点时容易出错,从而导致集群不平衡或出现热点。

在这篇博客中,我们将探讨这种旧算法,它应该如何工作以及何时不起作用,以及我们可以做些什么来解决这个问题。然后,我们将介绍新算法以及它如何解决这个问题,最后,我们将研究如何使用 AutoOps 来针对客户用例突出显示这个问题。然而,我们不会深入探讨热点的所有原因,也不会深入探讨所有具体的解决方案,因为它们太多了。

什么是 AutoOps?

平衡分配

在 Elasticsearch 8.5 及更早版本中,我们使用以下方法来确定在哪个节点放置分片,此方法主要归结为选择分片数量最少的节点:https://github.com/elastic/elasticsearch/blob/8.5/server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java#L242

float weight(Balancer balancer, ModelNode node, String index) {final float weightShard = node.numShards() - balancer.avgShardsPerNode();final float weightIndex = node.numShards(index) - balancer.avgShardsPerNode(index);return theta0 * weightShard + theta1 * weightIndex;
}
  • node.numShards():分配给集群中特定节点的分片数量
  • balancer.avgShardsPerNode():集群中所有节点的分片平均值
  • node.numShards(index):分配给集群中特定节点的特定索引的分片数量
  • balancer.avgShardsPerNode(index):集群中所有节点的特定索引的分片平均值
  • theta0:(cluster.routing.allocation.balance.shard) 分片总数的权重因子,默认为 0.45f,增加该值会增加均衡每个节点分片数量的趋势(请参阅  Shard balancing heuristics settings)
  • theta1:(cluster.routing.allocation.balance.index) 每个索引分片总数的权重因子,默认为 0.55f,增加该值会增加均衡每个索引分片数量的趋势每个节点(请参阅 Shard balancing heuristics settings)

该算法在整个集群中的目标值是以这样的方式选择一个节点,使得集群中所有节点的权重回到 0 或最接近 0。

示例

让我们探讨这样一种情况:我们有 2 个节点,其中 1 个索引由 3 个主分片组成,并且假设我们在节点 1 上有 1 个分片,在节点 2 上有 2 个分片。当我们向具有 1 个分片的集群添加新索引时会发生什么?

由于新索引在集群中的其他任何地方都没有分片,因此 weightIndex 项减少到 0,我们可以在下一个计算中看到,将分片添加到节点 1 将使余额回到 0,因此我们选择节点 1。

现在让我们添加另一个包含 2 个分片的索引,由于现在已达到平衡,因此第一个分片将随机分配到其中一个节点。假设节点 1 被选为第一个分片,则第二个分片将分配到节点 2。

新的平衡最终将是:

如果集群中的所有索引/分片在采集、搜索和存储要求方面都执行大致相同的工作量,则此算法将很好地发挥作用。实际上,大多数 Elasticsearch 用例并不这么简单,并且分片之间的负载并不总是相同的,请想象以下场景。

图 1:Elasticsearch 集群(夸张的分片大小表示分片实际上有多“繁忙”)
  • 索引 1,小型搜索用例,包含几千个文档,分片数量不正确;
  • 索引 2,索引非常大,但未被主动写入且偶尔搜索;
  • 索引 3,轻量级索引和搜索;
  • 索引 4,重度摄取应用程序日志。

假设我们有 3 个节点和 4 个索引,它们只有主分片,并且故意处于不平衡状态。为了直观地了解正在发生的事情,我根据分片的繁忙程度以及繁忙的含义(写入、读取、CPU、RAM 或存储)夸大了分片的大小。即使节点 3 已经拥有最繁忙的索引,新的分片也会路由到该节点。索引生命周期管理 (ILM) 不会为我们解决这种情况,当索引滚动时,新的分片将放置在节点 3 上。我们可以手动缓解这个问题,强制 Elasticsearch 使用集群重新(cluster reroute)路由均匀分布分片,但这无法扩展,因为我们的分布式系统应该处理这个问题。尽管如此,如果没有任何重新平衡或其他干预措施,这种情况将继续存在,并可能变得更糟。此外,虽然这个例子是假的,但这种分布在具有混合用例(即搜索、日志记录、安全)的旧 Elasticsearch 集群中是不可避免的,尤其是当一个或多个用例是重度摄取时,确定何时会发生这种情况并不是一件容易的事。

虽然预测这个问题的时间范围很复杂,但在某些情况下行之有效的一个好的解决方案是保持所有索引的分片密度相同,这是通过在所有索引的分片达到预定大小(以 GB 为单位)时滚动所有索引来实现的(请参阅分片大小 -  size your shards)。这并不适用于所有用例,正如我们将在下面 AutoOps 捕获的集群中看到的那样。

所期望的平衡分配

为了解决这个问题和其他一些问题,一种可以同时考虑写入负载和磁盘使用情况的新算法最初在 8.6 中发布,并在 8.7 和 8.8 版本中进行了一些微小但有意义的更改:https://github.com/elastic/elasticsearch/blob/8.8/server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java#L305

float weight(Balancer balancer, ModelNode node, String index) {final float weightShard = node.numShards() - balancer.avgShardsPerNode();final float weightIndex = node.numShards(index) - balancer.avgShardsPerNode(index);final float ingestLoad = (float) (node.writeLoad() - balancer.avgWriteLoadPerNode());final float diskUsage = (float) (node.diskUsageInBytes() - balancer.avgDiskUsageInBytesPerNode());return theta0 * weightShard + theta1 * weightIndex + theta2 * ingestLoad + theta3 * diskUsage;
}
  • node.writeLoad():特定节点的写入或索引负载
  • balancer.avgWriteLoadPerNode():整个集群的平均写入负载
  • node.diskUsageInBytes():特定节点的磁盘使用情况
  • balancer.avgDiskUsageInBytesPerNode():整个集群的平均磁盘使用情况
  • theta2:(cluster.routing.allocation.balance.write_load)写入负载的权重因子,默认为 10.0f,增加该值会增加均衡每个节点的写入负载的趋势(请参阅 Shard balancing heuristics settings)
  • theta3:(cluster.routing.allocation.balance.disk_usage)磁盘使用情况的权重因子,默认为 2e-11f,增加该值会增加均衡每个节点的磁盘使用情况的趋势(请参阅 Shard balancing heuristics settings)

我不会在本博客中详细介绍此算法所做的计算,但是 Elasticsearch 用于决定分片应位于何处的数据可通过 API 获取:获取所需平衡(Get desired balance)。在调整分片大小时,遵循我们的指导仍然是最佳实践,并且仍然有充分的理由将用例分离到专用的 Elasticsearch 集群中。然而,此算法在平衡 Elasticsearch 方面要好得多,以至于它为我们的客户解决了以下平衡问题。(如果你遇到本博客中描述的问题,我建议你升级到 8.8)。

最后要注意的是,此算法没有考虑搜索负载,这很难衡量,甚至更难预测。6.1 中引入的自适应副本选择(Adaptive replica selection)对解决搜索负载大有帮助。在未来的博客中,我们将深入探讨搜索性能的主题,特别是如何使用 AutoOps 在搜索性能问题发生之前发现它们。

在 AutoOps 中检测热点

上述情况不仅难以预测,而且一旦发生也难以检测,我们需要对 Elasticsearch 有深入的内部了解,并且我们的集群需要满足非常具体的条件才能处于这种状态。

现在,使用 AutoOps 检测这个问题就轻而易举了。让我们看一个真实的例子;

在这个设置中,Elasticsearch 前面有一个排队机制,用于处理数据峰值,但是用例是近实时日志 - 持续的滞后是不可接受的。我们遇到了持续滞后的情况,必须进行故障排除。从集群视图开始,我们获取了一些有用的信息,在下图中我们了解到有 3 个主节点、8 个数据节点(以及 3 个与案例无关的其他节点)。我们还了解到集群是红色的(这可能是网络或性能问题),版本是 8.5.1,有 6355 个分片;最后这两个将在以后变得重要。

图片 2:集群信息

这个集群中发生了很多事情,它经常变成红色,这些都与离开集群的节点有关。节点离开集群的时间大约在我们观察到索引拒绝的时间,并且拒绝发生在索引队列过于频繁地填满后不久,黄色越深,时间块中的高索引事件越多。

图 3:集群中事件的时间线(重点突出数据节点断开连接)

转到节点视图并关注最后一个节点断开连接的时间范围,我们可以看到另一个节点(节点 9)的索引率比其他节点高得多,其次是节点 4,该节点在本月早些时候曾出现过一些断开连接的情况。你还会注意到,在同一时间范围内索引率下降幅度相当大,这实际上也与此特定集群中计算资源和存储之间的间歇性延迟有关。

图4:数据节点9,索引率高。

默认情况下,AutoOps 只会报告断开连接时间超过 300 秒的节点,但我们知道包括节点 9 在内的其他节点经常离开集群,如下图所示,节点上的分片数量增长太快,无法移动分片,因此在节点断开连接/重新启动后,它们必须重新初始化。有了这些信息,我们可以放心地得出结论,集群正在经历性能问题,但不仅仅是热点性能问题。由于 Elasticsearch 以集群的形式工作,它只能以最慢的节点的速度运行,而且由于节点 9 被要求比其他节点做更多的工作,它无法跟上,其他节点总是在等待它,偶尔也会断开连接。

图5:数据节点9,分片数量增加。

此时我们不需要更多信息,但为了进一步说明 AutoOps 的强大功能,下面是另一张图像,该图像显示了节点 9 比其他节点执行了多少工作,特别是它写入磁盘的数据量。

图 6:磁盘写入和 IOPS。

我们决定将所有分片从节点 9 移出,方法是将它们随机发送到集群中的其他节点;这是通过以下命令实现的。此后,整个集群的索引性能得到改善,延迟消失。

PUT /_cluster/settings
{"transient": {"cluster.routing.allocation.exclude._name": "****-data-9"}
}

现在我们已经观察、确认并解决了该问题,我们需要找到一个长期的解决方案,这又让我们回到了博客开头的技术分析。我们遵循最佳实践,分片以预定的大小滚动,甚至限制每个节点特定索引的分片数量。我们遇到了算法无法处理的边缘情况,即索引繁重且频繁滚动的索引。

我们考虑过是否可以手动重新平衡集群,但对于由 6355 个分片组成的约 2000 个索引,这并非易事,更不用说,在这种级别的索引下,我们将与 ILM 竞争重新平衡。这正是新算法的设计目的,因此我们的最终建议是升级集群。

最后的想法

本博客总结了一组相当具体但复杂的情况,这些情况可能会导致 Elasticsearch 性能出现问题。你今天甚至可能会在集群中看到其中一些问题,但可能永远不会像这个用户那样严重地影响集群。这个案例强调了跟上 Elasticsearch 最新版本的重要性,以便始终利用最新的创新来更好地管理数据,它有助于展示 AutoOps 在发现/诊断问题并提醒我们注意问题方面的强大功能,以免它们成为全面生产事件。

考虑迁移到至少 8.8 版 https://www.elastic.co/guide/en/elasticsearch/reference/8.8/migrating-8.8.html

Elasticsearch 包含许多新功能,可帮助你为你的用例构建最佳搜索解决方案。深入了解我们的示例笔记本以了解更多信息,开始免费云试用,或立即在你的本地机器上试用 Elastic。

原文:Hotspots in Elasticsearch and how to resolve them with AutoOps - Search Labs

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

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

相关文章

【H2O2|全栈】JS进阶知识(七)ES6(3)

目录 前言 开篇语 准备工作 递归 概念 形式 优缺点 案例 数组求和 斐波那契数列 递归查找数据 柯里化 概念 形式 什么时候使用柯里化? 多维数组扁平化 多维数组 扁平化 利用flat() 与字符串相互转化 与JSON字符串相互转化 some(),…

字符数组和字符指针

为什么C程序里面不能对字符数组进行重新赋值而可以在控制台进行输入赋值? 在C语言中,字符数组(char array)和字符指针(char pointer)是两种不同的数据类型,它们在内存中的存储方式和使用方式有…

【架构】主流企业架构Zachman、ToGAF、FEA、DoDAF介绍

文章目录 前言一、Zachman架构二、ToGAF架构三、FEA架构四、DoDAF 前言 企业架构(Enterprise Architecture,EA)是指企业在信息技术和业务流程方面的整体设计和规划。 最近接触到“企业架构”这个概念,转念一想必定和我们软件架构…

迷宫题解 题目ID:8015

题目描述 时间限制: 1s 空间限制:32M 题目描述: 给定一个N∗M 方格的迷宫,每个方格最多经过一次,且迷宫里有 T 处障碍,障碍处不可通过。 在迷宫中有上下左右四种移动方式,每次只能移动一个方…

Kafka Stream实战教程

Kafka Stream实战教程 1. Kafka Streams 基础入门 1.1 什么是 Kafka Streams Kafka Streams 是 Kafka 生态中用于 处理实时流数据 的一款轻量级流处理库。它利用 Kafka 作为数据来源和数据输出,可以让开发者轻松地对实时数据进行处理,比如计数、聚合、…

Python中常用的内置函数介绍

1、生成器(Generator): 通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间&#x…

基于python Django的boss直聘数据采集与分析预测系统,爬虫可以在线采集,实时动态显示爬取数据,预测基于技能匹配的预测模型

本系统是基于Python Django框架构建的“Boss直聘”数据采集与分析预测系统,旨在通过技能匹配的方式对招聘信息进行分析与预测,帮助求职者根据自身技能找到最合适的职位,同时为招聘方提供更精准的候选人推荐。系统的核心预测模型基于职位需求技…

vulhub之fastjson

fastjson 1.2.24 反序列化 RCE 漏洞(CVE-2017-18349) 漏洞简介 什么是json json全称是JavaScript object notation。即JavaScript对象标记法,使用键值对进行信息的存储。举个简单的例子如下: {"name":"BossFrank", "age":23, "isDevel…

Scala案例:全文单词统计

2.txt内容如下 Thank you very much.Well I want to thank you all very much this is great, these are our friends, we have thousands of friends in this incredible movement.This was a movement like no nobodys ever seen before, and frankly this was I believe the…

失落的Apache JDBM(Java Database Management)

简介 Apache JDBM(Java Database Management)是一个轻量级的、基于 Java 的嵌入式数据库管理系统。它主要用于在 Java 应用程序中存储和管理数据。这个项目已经过时了,只是发表一下以示纪念,现在已经大多数被SQLite和Derby代替。…

【STK学习】part2-星座-目标可见性与覆盖性分析

【Satellite Tool Kit】学习并深入了解卫星/星座生成、可见性分析、覆盖性分析等知识,并基于STK软件实现对应数据的导出,以用于算法的约束输入。 文章目录 一、学习目标二、学习内容2.1 星地可见性分析2.1.1 单星单地2.1.2 单星多地2.1.3 多星单地 2.2 星…

金融数据中心容灾“大咖说” | 美创科技赋能“灾备一体化”建设

中国人民银行发布的《金融数据中心容灾建设指引》(JR/T 0264—2024)已于2024年7月29日正式实施。这一金融行业标准对金融数据中心容灾建设中的“组织保障、需求分析、体系规划、建设要求、运维管理”进行了规范和指导。面对不断增加的各类网络、业务、应…

k8s篇之flannel网络模型详解

在 Kubernetes (K8s) 中,Flannel 是一种常用的网络插件,用于实现容器之间的网络通信。Flannel 提供了一种覆盖网络(Overlay Network)模型,使得容器可以跨多个主机进行通信。 以下是 Flannel 在 Kubernetes 中的详细工作原理和覆盖网络模型的详解: 1.Flannel 简介 Flann…

《第十部分》1.STM32之通信接口《精讲》之IIC通信---介绍

经过近一周的USART学习,我深刻体会到通信对单片机的重要性。它就像人类的手脚和大脑,只有掌握了通信技术,单片机才能与外界交互,展现出丰富多彩的功能,变得更加强大和实用。 单片机最基础的“语言”是二进制。可惜&am…

Vue通过file控件上传文件到Node服务器

功能: 1.多文件同时上传、2.拖动上传、3.实时上传进度条、4.中断上传和删除文件、5.原生file控件的美化 搁置的功能: 上传文件夹、大文件切片上传、以及其他限制条件未处理 Node服务器的前置准备: 新建文件夹: file_upload_serve初始化npm: npm …

【AI图像生成网站Golang】图床上传与图像生成API搭建

AI图像生成网站 目录 一、项目介绍 二、雪花算法 三、JWT认证与令牌桶算法 四、项目架构 五、图床上传与图像生成API搭建 六、项目测试与调试(等待更新) 五、图床上传与图像生成API搭建 在项目中,我们通过整合 Go 和 FastAPI 实现了图像的上传和生成功能。本…

如何使用 Docker Compose 安装 WireGuard UI

简介 wireguard是什么?维基百科是这样描述的: WireGuard是一种实现加密虚拟专用网络(VPN) 的通信协议和免费开源软件,其设计目标是易于使用,高速性能和低攻击面。它旨在比IPsec和OpenVPN这两种常见的隧道协议具有更好的性能和更…

IM项目-----客户端网络通讯流程

文章目录 前言数据中心类数据持久化网络通信类http客户端websocket客户端 前言 对即时通信系统客户端部分的网络通讯流程的总结。 数据中心类 通过model/datacenter.h 中的DataCenter 类来管理所有客⼾端需要的数据.这是⼀个单例类. 这里管理一份数据有两个作用,1…

软件测试—— Selenium 常用函数(一)

前一篇文章:软件测试 —— 自动化基础-CSDN博客 目录 前言 一、窗口 1.屏幕截图 2.切换窗口 3.窗口设置大小 4.关闭窗口 二、等待 1.等待意义 2.强制等待 3.隐式等待 4.显式等待 总结 前言 在前一篇文章中,我们介绍了自动化的一些基础知识&a…

WebSocket详解、WebSocket入门案例

目录 1.1 WebSocket介绍 http协议: webSocket协议: 1.2WebSocket协议: 1.3客户端(浏览器)实现 1.3.2 WebSocket对象的相关事宜: 1.3.3 WebSOcket方法 1.4 服务端实现 服务端如何接收客户端发送的请…