我们 CIAN 如何驯服 TB 级的日志

我们 CIAN 如何驯服 TB 级的日志

大家好,我叫 Alexander,我在 CIAN 担任工程师,负责基础设施流程的系统管理和自动化。 在之前一篇文章的评论中,我们被要求说明每天从哪里获得 4 TB 的日志以及我们如何处理它们。 是的,我们有很多日志,并且创建了一个单独的基础设施集群来处理它们,这使我们能够快速解决问题。 在本文中,我将讨论我们如何在一年的时间里对其进行调整以处理不断增长的数据流。

我们从哪里开始?

我们 CIAN 如何驯服 TB 级的日志

过去几年,cian.ru的负载增长非常快,到2018年第三季度,资源流量达到每月11.2万独立用户。 当时关键时刻我们丢失了高达40%的日志,这就是为什么我们不能快速处理事件,花费了大量的时间和精力去解决。 我们也经常找不到问题的原因,并且一段时间后又会再次出现。 这是地狱,必须采取一些措施。

当时,我们使用ElasticSearch版本10、标准索引设置的5.5.2个数据节点的集群来存储日志。 它是一年多前推出的,作为一种流行且经济实惠的解决方案:那时日志流量还没有那么大,没有必要提出非标准配置。 

传入日志的处理由 Logstash 在五个 ElasticSearch 协调器的不同端口上提供。 一个索引,无论大小,都由五个分片组成。 每小时和每天进行轮换,集群中每小时会出现约 100 个新分片。 虽然日志不是很多,但集群处理得很好,没有人关注它的设置。 

快速增长的挑战

由于两个进程相互重叠,生成的日志量增长得非常快。 一方面,该服务的用户数量有所增长。 另一方面,我们开始积极转向微服务架构,用 C# 和 Python 打破旧的单体架构。 几十个新的微服务取代了整体架构的一部分,为基础设施集群生成了更多的日志。 

正是扩展导致我们的集群变得几乎难以管理。 当日志开始以每秒 20 万条消息的速度到达时,频繁的无用旋转将分片数量增加到 6 个,每个节点有超过 600 个分片。 

这导致了 RAM 分配的问题,当一个节点崩溃时,所有分片开始同时移动,从而增加流量并加载其他节点,这使得几乎不可能将数据写入集群。 在此期间,我们没有日志。 而如果服务器出现问题,我们基本上就失去了集群的 1/10。 大量的小索引增加了复杂性。

没有日志,我们不了解事件的原因,迟早会再次踩到同一个耙子,而在我们团队的意识形态中,这是不可接受的,因为我们所有的工作机制都旨在做相反的事情 - 永不重复同样的问题。 为此,我们需要全部日志及其几乎实时的交付,因为值班工程师团队不仅从指标中监控警报,还从日志中监控警报。 要了解问题的规模,当时的日志总量约为每天 2 TB。 

我们设定的目标是完全消除日志丢失,并在不可抗力期间将日志传送到 ELK 集群的时间减少到最多 15 分钟(我们后来依赖这个数字作为内部 KPI)。

新的轮换机制和热温节点

我们 CIAN 如何驯服 TB 级的日志

我们通过将 ElasticSearch 版本从 5.5.2 更新到 6.4.3 开始集群转换。 我们的版本 5 集群再次崩溃,我们决定关闭它并完全更新它 - 仍然没有日志。 因此,我们在短短几个小时内就完成了这一转变。

这一阶段最大规模的改造是在三个节点上实现 Apache Kafka,并以协调器作为中间缓冲区。 消息代理使我们避免在 ElasticSearch 出现问题时丢失日志。 同时,我们向集群添加了2个节点,并切换到热温架构,其中三个“热”节点位于数据中心的不同机架中。 我们使用在任何情况下都不应丢失的掩码(nginx)以及应用程序错误日志将日志重定向到它们。 次要日志被发送到其余节点 - 调试、警告等,24 小时后,来自“热”节点的“重要”日志被传输。

为了不增加小索引的数量,我们从时间轮转切换到滚动机制。 论坛上有很多信息表明按索引大小进行轮换非常不可靠,因此我们决定使用按索引中文档数量进行轮换。 我们分析了每个索引并记录了轮换后应该起作用的文档数量。 因此,我们已经达到了最佳分片大小 - 不超过 50 GB。 

集群优化

我们 CIAN 如何驯服 TB 级的日志

然而,我们还没有完全摆脱这些问题。 不幸的是,小索引仍然出现:它们没有达到指定的数量,没有轮换,并且由于我们删除了按日期轮换,因此通过对超过三天的索引进行全局清理来删除它们。 由于集群中的索引完全消失,这导致了数据丢失,并且尝试写入不存在的索引破坏了我们用于管理的 curator 的逻辑。 用于写入的别名被转换为索引并破坏了翻转逻辑,导致某些索引不受控制地增长到600 GB。 

例如,对于旋转配置:

сurator-elk-rollover.yaml

---
actions:
  1:
    action: rollover
    options:
      name: "nginx_write"
      conditions:
        max_docs: 100000000
  2:
    action: rollover
    options:
      name: "python_error_write"
      conditions:
        max_docs: 10000000

如果没有翻转别名,则会发生错误:

ERROR     alias "nginx_write" not found.
ERROR     Failed to complete action: rollover.  <type 'exceptions.ValueError'>: Unable to perform index rollover with alias "nginx_write".

我们将这个问题的解决方案留到下一次迭代中,并解决了另一个问题:我们切换到 Logstash 的拉取逻辑,该逻辑处理传入的日志(删除不必要的信息并丰富)。 我们将其放置在 docker 中,通过 docker-compose 启动它,并且还放置了logstash-exporter,它将指标发送到 Prometheus 以对日志流进行操作监控。 这样我们就有机会平滑地更改负责处理每种类型日志的logstash实例的数量。

在我们改进集群的同时,cian.ru 的流量增加到每月 12,8 万独立用户。 结果发现我们的改造有点落后于生产的变化,我们面临着“热”节点无法应对负载并减慢了整个日志交付速度的事实。 我们毫无故障地收到了“热”数据,但我们必须干预其余数据的交付并进行手动滚动,以便均匀分配索引。 

同时,由于它是本地 docker-compose,因此扩展和更改集群中的 Logstash 实例的设置变得很复杂,并且所有操作都是手动执行的(要添加新端,需要手动遍历所有操作)服务器并在各处执行 docker-compose up -d )。

日志重新分配

今年30月份,我们还在对单体进行切割,集群的负载不断增加,日志流已经接近每秒XNUMX万条消息。 

我们 CIAN 如何驯服 TB 级的日志

我们通过硬件更新开始了下一次迭代。 我们从五个协调员改为三个,更换了数据节点,并在金钱和存储空间方面取得了胜利。 对于节点,我们使用两种配置: 

  • 对于“热”节点:E3-1270 v6 / 960Gb SSD / 32 Gb x 3 x 2(3 个用于 Hot1,3 个用于 Hot2)。
  • 对于“热”节点:E3-1230 v6 / 4Tb SSD / 32 Gb x 4。

在本次迭代中,我们将微服务访问日志的索引(与一线 nginx 日志占用的空间相同)移至第二组三个“热”节点。 我们现在将数据存储在“热”节点上 20 小时,然后将它们传输到“热”节点以记录其余日志。 

我们通过重新配置小索引的轮换来解决小索引消失的问题。 现在,无论如何,索引每 23 小时轮换一次,即使那里的数据很少。 这稍微增加了分片数量(大约800个),但从集群性能的角度来看,这是可以忍受的。 

结果,集群中有六个“热”节点和四个“热”节点。 这会导致较长时间间隔内的请求略有延迟,但将来增加节点数量将解决此问题。

这次迭代还修复了缺乏半自动缩放的问题。 为此,我们部署了一个基础设施 Nomad 集群 - 类似于我们已经在生产中部署的集群。 目前,Logstash 的数量不会根据负载自动变化,但我们会讨论这一点。

我们 CIAN 如何驯服 TB 级的日志

未来的计划

实施的配置可以完美扩展,现在我们存储了 13,3 TB 的数据 - 所有日志为期 4 天,这对于警报的紧急分析是必要的。 我们将一些日志转换为指标,并将其添加到 Graphite 中。 为了让工程师的工作更轻松,我们提供了基础设施集群的指标和用于半自动修复常见问题的脚本。 计划明年增加数据节点数量后,我们会将数据存储从4天切换到7天。 这对于运营工作来说已经足够了,因为我们总是试图尽快调查事件,而对于长期调查来说,有遥测数据。 

2019 年 15,3 月,cian.ru 的流量已增至每月 XNUMX 万独立用户。 这成为对日志交付架构解决方案的严峻考验。 

现在我们正准备将 ElasticSearch 更新到版本 7。但是,为此我们必须更新 ElasticSearch 中许多索引的映射,因为它们从版本 5.5 移出并在版本 6 中被声明为已弃用(它们根本不存在于版本中) 7). 这意味着在更新过程中肯定会出现某种不可抗力,导致我们在问题解决期间没有日志。 在版本 7 中,我们最期待 Kibana 具有改进的界面和新的过滤器。 

我们实现了我们的主要目标:我们不再丢失日志,并将基础设施集群的停机时间从每周 2-3 次崩溃减少到每月几个小时的维护工作。 所有这些生产工作几乎是看不见的。 然而,现在我们可以准确地确定我们的服务发生了什么,我们可以在安静模式下快速完成,而不用担心日志会丢失。 总的来说,我们感到满意、高兴,并为新的探索做好准备,我们稍后会谈到。

来源: habr.com

添加评论