作者:来自 Elastic Andrei Dan
在 Elastic Cloud Serverless 中,我们根据索引负载自动为数据流配置最佳分片数量,从而使用户无需摆弄分片。
传统上,用户会更改数据流的分片配置,以处理各种工作负载并充分利用可用资源。在 Elastic Cloud Serverless 中,我们引入了数据流的自动分片,使其能够根据索引负载自动管理和扩展。这篇文章探讨了自动分片的机制、其好处以及它对处理可变工作负载的用户的影响。自动分片的理念是积极增加分片数量并非常谨慎地减少分片数量,这样分片的增加不会因为工作负载在短时间内减少而过早地减少分片数量。
无服务器 Elasticsearch 中的数据流自动分片
想象一下,你有一个大披萨需要在聚会上与朋友们分享。如果你将披萨切成两片,供六个朋友食用,那么每片都需要供多人食用。这将造成瓶颈,一个人独占一整片,而其他人则在等待,导致共享过程缓慢。此外,并不是每个人都能同时享用披萨;你几乎可以听到那些等待的朋友的叹息声。如果更多的朋友意外出现,你将很难用两片披萨喂饱他们,并发现自己不得不当场手忙脚乱地重新塑形。
另一方面,如果你把披萨切成 36 片小块给同样的六个朋友,管理分享就变得很棘手。每个人都没有享受披萨,而是花更多的时间想办法拿到自己的小份。如果切片太小,披萨甚至可能会散开。
为了确保每个人都能高效地享用披萨,你应该把它切成与朋友数量相匹配的片数。如果你有六个朋友,把披萨切成 6 片或 12 片,每个人都可以拿到一片,而不用等很长时间。通过在切披萨时找到合适的平衡,你将让聚会顺利进行,让每个人都开心。
当你立即跟进解释时,你就知道这是一个很好的比喻;披萨代表数据,切片代表索引分片,朋友是集群中的 Elasticsearch 节点。
传统上,Elasticsearch 的用户必须预测他们的索引吞吐量并手动配置每个数据流(data stream)的分片数量。这种方法严重依赖于预测启发式方法,需要根据工作负载特征进行持续调整,同时还要平衡数据存储、搜索分析和应用程序性能。
零售等具有季节性流量的企业通常会处理数据需求激增的问题,而物联网应用程序可能会在特定时间经历负载的快速增加。开发和测试环境通常每周只运行几个小时,这使得固定分片配置效率低下。新应用程序可能难以准确估计工作负载需求,从而导致潜在的过度或不足配置。
我们在 Elastic Cloud Serverless 中引入了数据流的自动分片。Serverless 中的数据流根据索引负载自动管理和扩展 - 当朋友到达你的聚会或吃完时自动切片你的披萨。
自动分片的承诺
自动分片通过根据当前索引负载自动调整分片数量来解决这些挑战。这意味着用户无需手动调整配置,Elasticsearch 将根据实时数据流量动态管理项目中数据流的分片数量。
Elasticsearch 将每个索引的索引负载作为名为写入负载的指标的一部分进行跟踪,并将其作为索引部分下索引统计 API (index stats API)的一部分公开给本地和 ESS 部署。
write_load 表示索引文档时使用的平均写入线程数。
对于具有一个分片的索引,write_load 指标的最大可能值是可用的写入线程数(例如,所有写入线程都忙于在同一个分片中写入)。
对于具有多个分片的索引,写入负载的最大可能值是节点中可用的写入线程数乘以项目中的索引节点数。(例如,托管我们索引的分片的所有索引节点上的所有写入线程都忙于在属于我们索引的分片中写入,仅此而已)
为了了解 write_load 允许的值,让我们查看索引 logs,其中一个分片在一台分配了 2 个处理器的 Elasticsearch 机器上运行。写入线程池的大小将为 2 个线程。这意味着,如果此 Elasticsearch 节点专门且持续地写入相同的索引日志,我们将报告的索引日志的 write_load 将为 2.0(即 2 个写入线程完全用于写入索引日志)。
如果 logs 有 2 个主分片,并且我们现在在两个 Elasticsearch 节点上运行,每个节点分配有 2 个处理器,如果两个 Elasticsearch 节点上的所有写入线程都专门写入日志索引,我们将能够获得最大报告的 write_load 4.0。
无服务器自动扩展
我们刚刚研究了当我们增加分片和 Elasticsearch 节点的数量时,写入 write load 如何翻倍。Elastic Cloud Serverless 使用数据流自动分片和摄取自动扩展(ingest autoscaling)自动处理这两项操作。自动扩展是指根据当前需求动态调整资源(如内存、CPU 和磁盘)的过程。
在我们的无服务器架构中,我们从一台小型 2GB 内存服务器开始,并使用阶跃函数扩展方法来有效增加容量。我们逐步增加内存,然后通过添加服务器进行扩展。这个循环继续,在管理服务器数量的同时,逐步将每台服务器的内存增加到 64GB。
将自动扩展和自动分片联系起来
自动扩展和自动分片之间的联系对于优化性能至关重要。在计算数据流的最佳分片数量时,我们会考虑扩展设置中每个节点可用的最小和最大写入线程数。
- 对于小型项目,当数据流使用超过节点容量的一半(即超过一个索引线程)时,系统将从 1 个分片移动到 2 个分片。
- 对于中型项目,由于系统跨多个节点扩展,因此不会超过 3 个分片,以避免过多的开销。
- 一旦我们达到最大的节点大小,就会启用进一步的分片以适应更大的工作负载。
自动分片还可以使项目达到更高的摄取负载值,从而实现自动扩展以根据需要增加资源,防止系统在高索引工作负载期间保持低容量。
自动分片公式
为了确定所需的分片数量,我们使用以下公式:
此公式平衡了根据 write_load 增加分片的需求,同时限制了分片数量以防止过度分片。除以 2 反映了仅在超过节点容量的一半后才增加分片的策略。最小/最大写入线程表示自动缩放步骤函数中可用的最小和最大写入线程数(即最小 2GB 步骤上可用的写入线程数和最大服务器上可用的写入线程数)
让我们可视化公式的输出:
Y 轴表示分片数量。X 轴表示写入负载(write load)。我们从 1 个分片开始,当写入负载刚好超过 3.0 时,分片数量增加到 3 个。在写入负载达到 48.0 左右之前,我们会一直使用 3 个分片。
这涵盖了我们通过节点扩展但尚未达到 2 个或更多或最大服务器的时间,此时我们会解锁自动分片到 3 个以上的分片,数量与提取数据所需的数量相同。
虽然添加分片可以提高索引性能,但 Elasticsearch 集群中的过度分片可能会产生负面影响 - 想象一下只有 7 个朋友分享 56 片披萨。每个分片都有间接成本,包括维护和资源分配。我们的算法考虑并避免了过度分片的危险,直到我们达到最大的工作负载,此时添加超过 3 个分片会对索引性能和吞吐量产生重大影响。
使用滚动实现自动分片
自动分片的实现依赖于滚动(rollover)的概念。滚动操作会在数据流(data stream)中创建一个新索引,将其提升为写入索引,同时将前一个索引指定为常规后备索引,不再接受写入。这种转变可能基于特定条件发生,例如超过 50GB 的分片大小。我们负责为无服务器中的数据流配置最佳滚动条件(optimal rollover conditions)。
在无服务器(Serverless)中,除了与维护健康索引和分片相关的常规滚动条件外,我们还引入了一个新条件,用于评估当前写入负载是否需要增加分片数量。如果满足此条件,将触发滚动,并为新生成的数据流写入索引(write index)配置最佳分片数量。
对于缩减规模,系统将监控工作负载,不会仅仅为了减少分片而触发滚动。相反,它将等到常规滚动条件(如主分片大小)触发滚动。生成的写入索引将配置较少数量的分片。
分片调整的冷却期
为了确保分片调整期间的稳定性,我们实施了冷却期:
- 增加分片冷却时间:自上次调整以来,在增加分片数量之前,强制执行至少 4.5 分钟的等待时间。4.5 分钟的冷却时间可能看起来很奇怪,但选择这个间隔是为了确保我们每次在数据流生命周期(data stream lifecycle)检查数据流是否应该滚动时(目前每 5 分钟一次)可以增加分片数量,但频率不会超过 5 分钟,以涵盖内部 Elasticsearch 集群重新配置。
- 减少分片冷却时间:在减少分片之前,我们保持 3 天的最低等待时间,以确保决策基于持续的工作负载模式而不是暂时的波动。
结论
无服务器 Elasticsearch 中的数据流自动分片功能代表了有效管理数据流的重大进步。通过根据实时索引负载自动调整分片数量,此功能简化了操作并增强了可扩展性。
借助自动扩展的额外优势,用户可以期待更高效、响应更快的体验,无论他们是在处理小型项目还是大型应用程序。随着数据工作负载的不断发展,自动分片提供的适应性确保 Elasticsearch 仍然是管理各种索引需求的强大解决方案。
试用我们的无服务器 Elasticsearch 产品,利用数据流自动分片,并观察索引吞吐量随着数据提取负载的增加而无缝扩展。
随着越来越多的朋友来到你的聚会,你的披萨将被最佳地切成薄片,他们渴望尝试您为他们准备的酸面团手工披萨。
了解有关 Elastic Cloud Serverless 的更多信息,并开始 14 天免费试用以亲自测试。
原文:Autosharding of data streams in Elasticsearch Serverless - Elasticsearch Labs