中文网站建设英文,怎么开发小程序,wordpress 加描述,专业做标书作者#xff1a;来自 Elastic Sachin Frayne 探索 Elasticsearch 中的热点以及如何使用 AutoOps 解决它。 Elasticsearch 集群中出现热点的方式有很多种。有些我们可以控制#xff0c;比如吵闹的邻居#xff0c;有些我们控制得较差#xff0c;比如 Elasticsearch 中的分片分…作者来自 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 settingstheta1(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 用例并不这么简单并且分片之间的负载并不总是相同的请想象以下场景。 图 1Elasticsearch 集群夸张的分片大小表示分片实际上有多“繁忙”) 索引 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()整个集群的平均磁盘使用情况theta2cluster.routing.allocation.balance.write_load写入负载的权重因子默认为 10.0f增加该值会增加均衡每个节点的写入负载的趋势请参阅 Shard balancing heuristics settingstheta3cluster.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