Kibana Alerting: 突破扩展性限制,实现50倍规模提升
在过去的几年里,Kibana告警一直是许多大型组织的首选监控解决方案。随着使用的不断增加,用户创建的告警规则数量也在增长。越来越多的组织依赖Kibana进行大规模告警,我们看到了提高效率和确保未来工作负载性能的机会。
在Kibana 8.16到8.18之间,我们正面解决了这些问题,引入了关键的改进,突破了之前的扩展性限制。在这些改进之前,Kibana告警每分钟最多支持3,200个规则,而且至少需要16个Kibana节点,才能避免严重的性能瓶颈。到了Kibana 8.18,我们将每分钟规则的扩展能力提高了50倍,支持每分钟最多160,000个轻量级告警规则。这是通过让Kibana有效扩展超过16个节点,并将每个节点的处理能力从每分钟200个规则提升到最多3,500个规则来实现的。这些增强使所有告警规则运行得更快,延迟更少,效率更高。
本文将探讨我们克服的扩展挑战、实现这一目标的关键创新,以及如何利用这些改进高效地运行大规模的Kibana告警。
Kibana告警如何与任务管理器一起扩展
Kibana告警允许用户定义基于实时数据触发告警的规则。在幕后,Kibana任务管理器负责调度和运行这些规则。
任务管理器是Kibana内置的作业调度程序,旨在将异步后台任务与用户交互分开处理。它的主要职责包括:
- 运行一次性和周期性任务,例如告警规则、连接器操作和报告。
- 动态分配工作负载,当Kibana后台节点加入或离开集群时。
- 保持Kibana UI响应,通过将任务卸载到专用的后台进程。
每个告警规则都会转化为一个周期性后台任务。每个后台任务都是一个Elasticsearch文档,意味着它会被存储、获取和更新。随着告警规则数量的增加,Kibana需要管理的后台任务也在增加。然而,每个Kibana节点能够同时处理的任务数量是有限的。一旦达到容量,额外的任务就需要等待,导致延迟和任务运行时间变慢。
问题:为什么扩展受限
在这些改进之前,任务管理器面临一些扩展性限制,无法超过每分钟3,200个任务和16个Kibana节点。在这个规模上,我们观察到由于争用和资源低效,进一步扩展时收益递减。这些数字基于内部性能测试,使用一个基本的Elasticsearch查询告警规则进行无操作查询。观察到的收益递减包括:
任务争夺
任务管理器使用分布式轮询方式在Elasticsearch索引内认领任务。Kibana节点周期性查询任务并尝试使用Elasticsearch的乐观并发控制来认领任务,防止冲突的文档更新。如果另一个节点先更新了任务,原节点就会放弃它,降低整体效率。
当有太多Kibana节点争夺任务时,文档更新冲突急剧增加,效率受限于16个节点,系统吞吐量降低。
节点处理能力低效
每个Kibana节点都有一个默认的并发任务限制(默认:同时10个任务),以防止内存和CPU过载。这一保护措施常常导致CPU和内存未被充分利用,需要比必要的更多节点。
另外,轮询间隔(默认:3000ms)定义了任务管理器认领新任务的频率。较短的间隔减少任务延迟,但增加节点间的争夺。
资源低效
在运行大量告警规则时,Kibana节点执行重复的Elasticsearch查询,重复加载相同的对象和列表,消耗了比必要更多的CPU、内存和Elasticsearch资源。扩展需要昂贵的基础设施扩张以支持不断增加的请求负载。
为什么重要
打破这些限制对于Kibana的持续发展至关重要。提高扩展性可以实现:
- 成本优化:降低大规模运营的基础设施成本。
- 更快的恢复:提升Kibana从节点或集群故障中恢复的能力。
- 未来扩展:为额外的工作负载(如定时报告和事件驱动自动化)提供扩展能力。
Kibana任务管理器的关键创新
为了实现50倍的扩展提升,我们引入了几个创新:
Kibana发现服务:更智能的扩展
之前,Kibana节点彼此之间没有意识,导致任务分配效率低下。新的Kibana发现服务动态监控活跃节点并相应地分配任务分区,确保负载均匀分布,减少争夺。
任务分区:消除争夺
为了防止节点争夺相同的任务,我们引入了任务分区。任务现在分布在256个分区内,确保在任何给定时间只有一部分Kibana后台节点尝试认领相同的任务。默认情况下,每个分区分配给最多两个Kibana节点,而单个Kibana节点可以负责多个分区。
任务计费:更智能的资源分配
并不是所有后台任务都消耗相同的资源。我们实施了一个任务计费系统,根据CPU和内存使用情况分配任务权重。这使得任务管理器能够动态调整认领的任务数量,优化资源分配,确保高效性能。
新的任务认领算法
旧算法依赖于通过查询更新强制索引刷新来识别已认领的任务。这种方式效率低下,并且对Elasticsearch造成了不必要的负担。新算法避免了这一点,通过搜索任务而不需要立即刷新。相反,它在任务管理器索引上执行以下操作:一个_search来寻找候选任务,接着一个_mget,返回可能最近更新但尚未反映在刷新索引状态中的文档。通过比较_search和_mget结果中的文档版本,它在继续批量更新之前丢弃不匹配项。这种方法提高了Elasticsearch的效率,并提供了更细致的控制以支持任务计费。
通过考虑轮询间隔、任务并发和索引刷新率,我们可以计算预期冲突的上限,并相应调整_search页大小。这有助于确保检索到足够多的任务,以防_mget因文档版本不匹配而丢弃所有搜索结果。
更频繁的任务轮询
通过确保固定数量的节点争夺相同的任务、任务分区和新的轻量级任务认领算法,任务管理器现在可以更频繁地轮询任务,而不会对Elasticsearch造成额外压力。这减少了任务完成与下一个任务开始之间的延迟,提升了整体系统吞吐量。
Kibana告警的性能优化
在使用Elastic APM进行优化之前,我们分析了告警规则性能,发现告警框架需要至少20个Elasticsearch查询才能运行任何告警规则。经过优化,我们将这一数字减少到仅3个查询,减少了85%,显著提高了运行时间并降低了CPU开销。
此外,Elasticsearch之前依赖资源密集型的pbkdf2哈希算法进行API密钥认证,这在规模上引入了过多的开销。我们通过切换到更高效的SHA-256算法优化了认证,允许我们消除内部Elasticsearch缓存,该缓存严重受限于同时使用的API密钥数量。
影响:用户受益
早期采用者展示了:
- 规则运行时间缩短50%,降低了整体系统负载。
- 任务容量增加,使更多任务可以在现有基础设施上运行。
- 减少资源配置不足的集群,减少了为满足需求而扩展基础设施的必要性。
由于节点处理能力增加和集群适当配置,平均任务延迟下降
由于告警框架优化,规则运行时长下降
由于告警框架优化,Elasticsearch请求减少
如何开始:高效扩展
升级到Kibana 8.18后,大多数这些优势会自动解锁。为了进一步优化,可以考虑调整 xpack.task_manager.capacity
设置,以最大化每节点吞吐量,同时确保p999资源使用保持在内存、CPU和事件循环利用率的80%以下,并且事件循环延迟保持在500ms以下。
默认情况下,Kibana每分钟有32,000个告警规则的限制。如果您计划超过此限制,可以相应修改 xpack.alerting.rules.maxScheduledPerMinute
设置。
新的 xpack.task_manager.capacity
设置使Kibana更有效地处理工作负载分配,使得以下设置在大多数情况下不再必要,应该从您的kibana.yml设置中移除:
xpack.task_manager.max_workers
xpack.task_manager.poll_interval
如果您在本地运行Kibana并希望将后台任务隔离到专用节点,可以使用 node.roles
设置 将处理UI的节点与处理后台任务的节点分开。如果您在Elastic Cloud Hosted (ECH)上使用Kibana,扩展到8GB或更高将自动启用这种隔离。
接下来是什么?
我们不会止步于50倍。我们的路线图目标是实现100倍以上的扩展,进一步消除Elasticsearch的瓶颈。
除了扩展,我们还专注于提高大规模系统监控。即将推出的集成将为系统管理员提供更深入的后台任务性能洞察,使得何时以及如何扩展的决策变得更简单。
此外,通过任务计费,我们计划在配置了更多CPU和内存(例如,具有2GB、4GB或8GB+内存的Kibana集群)时,增加Elastic Cloud Hosted (ECH)客户的任务并发性。
请继续关注更多进展,因为我们将继续推动Kibana扩展性的极限!