Elasticsearch PB群集中的最佳分片排列:线性规划

Elasticsearch是Meltwater和Fairhair.ai搜索引擎的核心,它是一个包含数十亿个媒体和社交媒体文章的集群集合。

集群中的索引分片在访问结构,工作负载和大小方面差异很大,这引起了一些非常有趣的问题。

在本文中,我们将描述如何使用线性规划(线性优化)在群集中的所有节点上尽可能均匀地分布搜索和索引工作负载。 此解决方案降低了一个节点成为系统瓶颈的可能性。 结果,我们提高了搜索速度并节省了基础架构。

背景知识


Fairhair.ai的搜索引擎包含来自社交媒体和社论的大约400亿个帖子,每天处理数百万个查询。 该平台为客户提供搜索结果,图形,分析,数据导出,以进行更高级的分析。

这些庞大的数据集驻留在750个节点的Elasticsearch集群中,这些集群具有50,000个分片中的数千个索引。

有关我们集群的更多信息,请参阅先前有关其架构机器学习负载平衡器的文章

工作量分配不均


我们的数据查询和用户查询通常都带有日期限制。 大多数请求属于某个时间段,例如上周,上个月,上一季度或任意范围。 为了简化索引和查询,我们使用时间索引 ,类似于ELK堆栈

该索引体系结构具有多个优点。 例如,您可以执行有效的质量索引,以及在数据过时时删除整个索引。 这也意味着给定索引的工作负载会随着时间变化很大。

与旧索引相比,最新查询的索引数量更多。


1.时间索引的访问方案。 纵轴表示已完成查询的数量,横轴表示索引的使用期限。 每周,每月和每年的平稳期都清晰可见,随后旧指标的工作量减少了

图中的图案。 1个是可以预见的,因为我们的客户对新信息更感兴趣,并定期将当月与过去和/或今年与过去一年进行比较。 问题在于,Elasticsearch不了解这种模式,并且不会自动针对观察到的工作负载进行优化!

内置的Elasticsearch分片分配算法仅考虑两个因素:

  1. 每个节点上的分片数 。 该算法尝试在整个集群中平均平衡每个节点的分片数量。
  2. 标记可用磁盘空间。 Elasticsearch在决定是向该节点分配新的分片还是将段从该节点移动到其他节点之前,先考虑节点上的可用磁盘空间。 如果使用了80%的磁盘,则禁止在一个节点上放置新的碎片,而90%的系统将开始从该节点主动转移碎片。

该算法的基本假设是,集群中的每个段接收的工作量大致相同,并且每个人的大小均相同。 就我们而言,这与事实相去甚远。

标准负载平衡会很快导致群集中出现热点。 它们随着工作负载随时间变化而随机出现和消失。

热点本质上是指主机在接近一个或多个系统资源(例如CPU,磁盘I / O或网络带宽)的限制下运行。 发生这种情况时,节点首先将请求排队一段时间,这会增加对请求的响应时间。 但是,如果过载持续很长时间,那么最终请求将被拒绝,并且用户会收到错误消息。

拥塞的另一个常见后果是由于查询和索引操作导致JVM垃圾的不稳定压力,这导致JVM垃圾收集器的“可怕地狱”现象。 在这种情况下,JVM要么无法足够快地获取内存并崩溃,要么陷入无尽的垃圾回收周期,冻结并停止响应集群的请求和ping。

当我们在AWS下重构架构时,问题变得更加严重。 以前,我们对自己在数据中心强大的服务器(24个内核)上最多运行四个Elasticsearch节点感到“震惊”。 这掩盖了碎片不对称分布的影响:机器上相对大量的铁心极大地减轻了负载。

重构之后,我们一次只在功能不强的机器(8核)上放置了一个节点-最初的测试立即显示出“热点”存在很大的问题。

Elasticsearch以随机顺序分配碎片,并且在集群中有500多个节点时,单个节点上太多“热”碎片的可能性大大增加-并且此类节点迅速溢出。

对于用户来说,这将意味着工作严重恶化,因为拥塞的节点响应速度很慢,有时会完全拒绝请求或崩溃。 如果您将这样的系统投入生产,那么用户会看到频繁的UI减速和随机超时。

同时,仍然存在大量带有分片的节点,它们没有很大的负载,实际上是不活动的。 这导致对群集资源的低效使用。

如果Elasticsearch更智能地分布分片,则可以避免这两个问题,因为所有节点上系统资源的平均使用率处于40%的健康水平。

集群连续变化


当工作超过500个节点时,我们还观察到了另一件事:节点状态的不断变化。 在以下因素的影响下,分片在节点中不断来回移动:

  • 创建新索引,旧索引被丢弃。
  • 磁盘标签是由于索引编制和其他分片更改而触发的。
  • Elasticsearch随机决定与群集的平均值相比,节点上的碎片太少或太多。
  • 硬件崩溃和操作系统级别的崩溃导致新的AWS实例启动并将它们加入集群。 对于500个节点,这种情况平均每周发生几次。
  • 由于正常的数据增长,几乎每周都会添加新站点。

考虑到所有这些因素,我们得出的结论是,所有问题的复杂而连续的解决方案都需要一个连续且动态的重新优化算法。

解决方案:Shardonnay


经过对可用选项的长期研究,我们得出了我们想要的结论:

  1. 构建自己的解决方案。 我们没有找到任何适合我们规模和任务的好的文章,代码或其他现有想法。
  2. 在Elasticsearch外部启动重新平衡过程,并使用集群重定向API,而不是尝试创建插件 。 我们希望有一个快速的反馈循环,并且在如此规模的集群上部署插件可能需要数周的时间。
  3. 使用线性编程在任何给定时间计算最佳碎片运动。
  4. 连续执行优化,以使群集状态逐渐达到最佳状态。
  5. 不要一次移动太多碎片。

我们注意到了一件有趣的事情:如果您同时移动过多的分片,则很容易触发级联的分片移动风暴 。 此类风暴爆发后,它可能会持续数小时,这时碎片将无法控制地来回移动,从而在各个位置出现有关磁盘空间临界水平的标记。 反过来,这会导致新的碎片运动等。

要了解正在发生的事情,重要的是要知道,当您移动活动索引的段时,它实际上开始在要从中移动的磁盘上使用更多的空间。 这是由于Elasticsearch如何存储事务日志 。 我们已经看到了在移动节点时索引加倍的情况。 这意味着由于磁盘空间使用率高而启动了分片移动的节点将在一段时间内使用更多的磁盘空间,直到它将足够的分片移动到其他节点。

为解决此问题,我们以著名的霞多丽葡萄品种为名 ,开发了Shardonnay服务。

线性优化


线性优化(或线性规划 LP)是一种在数学模型中获得最佳结果(例如最大利润或最低成本)的方法,其要求由线性关系表示。

优化方法基于线性变量系统,必须满足的一些约束以及确定成功解决方案外观的目标函数。 线性优化的目标是找到受限制的,使目标函数最小化的变量值。

分片分布是线性优化问题


Shardonnay应该连续工作,并且在每次迭代时执行以下算法:

  1. 使用该API,Elasticsearch检索有关集群中现有分片,索引和节点及其当前位置的信息。
  2. 将集群的状态建模为一组二进制LP变量。 每个组合(节点,索引,分片,副本)都有自己的变量。 在LP模型中,有许多经过精心设计的试探法,限制和目标函数,下面将对此进行详细介绍。
  3. 将LP模型发送到线性求解器,该线性求解器考虑了约束和目标函数,给出了一个最佳解决方案。 解决方案是将分片重新分配给节点。
  4. 解释LP的解并将其转换为碎片运动的序列。
  5. 指示Elasticsearch通过集群重定向API移动分片。
  6. 等待集群移动分片。
  7. 返回步骤1。

最主要的是开发正确的约束条件和目标功能。 其余的将由Solver LP和Elasticsearch完成。

毫不奇怪,对于这种规模和复杂性的集群而言,这项任务非常困难!

局限性


我们根据Elasticsearch本身规定的规则对模型进行一些限制。 例如,始终粘贴磁盘标签或禁止将副本与同一分片的另一副本放置在同一节点上。

根据在大型集群上多年工作中获得的经验,添加了其他组件。 以下是一些我们自己的局限性的例子:

  • 不要移动当今的索引,因为它们是最热门的索引,并且在读取和写入时几乎保持恒定的负载。
  • 优先移动较小的分片,因为Elasticsearch可以更快地处理它们。
  • 建议在未来的碎片变得活跃,开始建立索引并承受沉重的负载之前几天创建并放置它们。


成本函数


我们的成本函数权衡了许多不同的因素。 例如,我们想要:

  • 最小化索引和搜索查询的差异,以减少“热点”的数量;
  • 保持磁盘使用的最小差异,以使系统稳定运行;
  • 如上所述,最大程度地减少分片移动的次数,以免发生带有连锁反应的“风暴”。

减少LP变量


在我们的规模上,这些LP模型的大小成为一个问题。 我们很快意识到,在超过6000万个变量的合理时间内无法解决问题。 因此,我们应用了许多优化和建模技巧来大大减少变量的数量。 其中包括有偏抽样,启发式,分治法,迭代松弛和优化。


2.热图显示了Elasticsearch集群上的不平衡负载。 这体现在图左侧的资源使用大量分散中。 通过不断的优化,情况正在逐步稳定


3.热图显示在Shardonnay中设置热度功能之前和之后,群集所有节点上的CPU使用情况。 在工作负载不变的情况下,CPU使用率发生了显着变化。


热图显示了在与图4相同的时间段内磁盘的读取吞吐量。 3.读取操作也更均匀地分布在整个群集中。

结果


结果,即使对于我们庞大的集群,我们的LP解算器也能在几分钟内找到好的解决方案。 因此,系统在最优方向上迭代地改善了群集的状态。

最好的部分是工作负载和磁盘使用情况的分散程度达到了预期的收敛,并且自此以来,在集群状态发生了许多有意和意外的更改之后,这种接近最佳的状态得以保持!

现在,我们在Elasticsearch集群中支持健康的工作负载分配。 全部归功于线性优化和我们的服务,我们将其称为霞多丽

Source: https://habr.com/ru/post/zh-CN429738/


All Articles