「译文」Loki 简明指南:如何处理失序和较旧的日志

简介: 「译文」Loki 简明指南:如何处理失序和较旧的日志

在本周的 "Loki 简明指南 " 中,我想重点谈谈 Grafana Loki 历史上的一个有趣话题:摄取无序日志。

参与这个项目有一段时间的人可能还记得,Loki 曾经会拒绝任何比它已经接收到的日志行更早的日志。这当然是对 Loki 内部结构的一个很好的简化,但也给现实世界中的许多用例带来了很大的不便。

正是由于这种不便,我们在几年前决定解决这个问题。当时,欧文 - 迪尔(Owen Diehl)写了一篇不错的 博客,其中详细介绍了解决方案中的工程考虑因素。如果你想了解解决方案是如何构建的,这篇文章值得一读,但它的高度概括是这样的: 工程设计总是充满了权衡取舍,我们试图在性能、运营成本和功能之间取得平衡,从而开发出我们认为最适合 Loki 及其用户的解决方案。

在今天的文章中,我想谈谈这些取舍–不是 为什么 我们要这样做,而是 如何 影响您使用 Loki 的方式。我将使用一些动画来帮助您直观地了解其工作原理,并解释您在将旧版日志导入 Loki 时应该注意的事项。请系好安全带,做好准备: “订阅简明指南!”

无序摄取的工作原理

正如我在 本系列第一篇文章 中所描述的,Loki 的设计侧重于在摄取时实现快速和低成本。一般来说,它还希望能处理最近的数据。(也就是说,它所接收的数据的时间戳是在当前时间的几秒到几分钟之内)。因此,我们采用失序解决方案的主要目的是确保 Loki 在合理的时间内接受并存储延迟日志。

我们将 " 合理时间 " 定义为一小时。从技术上讲,它被定义为 max_chunk_age/2,但您应该像我们在 Grafana Labs 所做的那样,将 max_chunk_age设为两小时(稍后将详细介绍)。Loki 的无序日志摄取规则是这样的:

任何日志都将被接受并存储。任何比某个数据 收到的 最近日志 早一个小时以上的日志都会被拒绝,并显示错误信息,内容如下 “Entry too far behind.”。

上述声明中有两个非常重要的概念,它们是导致 Loki 如何接受较早日志的最主要原因。我用粗体标出了这两个概念:" 最近日志 " 和 “流”。

顾名思义," 最近日志 " 指的是 Loki 收到的具有最新时间戳的日志。听起来很简单,对吗?但是,如果将其与 "for a stream " 配对使用,就会出现混乱。这是因为 Loki 会逐个流确定最新日志,所以你不能自动假定你的流都是在同一时间对齐的。

也许一些更简陋的动画会对您有所帮助!首先让我们来看一个单一的数据流:

现在,让我们将该示例扩展到多个数据流:

希望这有助于澄清洛基是如何接收旧日志的!

重要配置

有几项重要配置与 Loki 如何处理日志条目的排序有关,接下来让我们看看这些配置。

摄取旧数据

在 Loki 配置的 limits_config 部分,有两个设置可以控制旧数据的摄取:

reject_old_samples: true 
reject_old_samples_max_age: 1w
YAML

有趣的是,这些默认值在很大程度上与 Loki 能够将亚马逊 DynamoDB 用作索引类型的传统有关。使用 DynamoDB 时,Loki 会更改旧表的吞吐量配置以节省成本,这意味着它不能再接受旧时间范围的数据。

自几年前发布 Loki 2.0 以来,我们已经不再使用这些外部索引类型。如果您希望向 Loki 发送超过一周的日志,或任何时间段的日志,请随时更改 reject_old_samples: false 或将窗口设置得更大。

失序窗口

我在开篇中提到了失序数据的窗口:

max_chunk_age 可以在 ingester config 中找到。

这里的默认值是两小时。我 强烈建议 增加该值,以创建更大的失序窗口。在 Grafana 实验室,我们并不以这种方式运行 Loki,因此我无法轻易告诉您可能会面临哪些挑战。我建议尝试找到一种使用标签来分离数据流的方法,这样就可以分别摄取它们。

如果您决定不采纳我的建议,请务必增加 query_ingesters_within 的值,使其与您的 match_chunk_age 匹配,以确保这些数据是可查询的。

获取旧数据时的查询注意事项

在向 Loki 采集旧数据时,有一个重要的注意事项。具体来说,如果您希望 Loki 摄取距离当前时间超过两个小时的数据,这些数据将无法立即进行查询

这是因为我们在上一节中提到的配置:query_ingesters_within。也许这个配置的名称有点令人困惑,但它的基本意思是 “只查询从当前时间起在这个时间窗口内的摄取者”。这里的默认值是三小时;从当前时间算起的三小时内的任何数据查询都将发送给摄取者,而该窗口之外的任何数据都不会发送。

之所以采用这种方式构建 Loki,是因为我们知道摄取器允许的 max_chunk_age 是两个小时。因此,我们可以不要求摄取器提供我们知道它们不会有的数据,从而大大减少摄取器的损耗。换句话说,如果你要查询昨天的日志,我们就不会向摄取器索要,因为它不应该有昨天的日志。

您在这里可能会遇到的问题是,如果您 发送昨天的 Loki 日志,那么这些日志 就会在摄取器中,直到它们被刷新到存储空间(最多两个小时)。在刷新之前,它们不会返回到查询结果中。

您可以 将此配置值改为更大的值,比如 48 小时,这样您就可以查询昨天的日志,因为它们是在今天被摄取的。但我真的不建议这样做,因为这将迫使 Loki 在 48 小时内查询所有查询结果。这将迫使您的摄取器做更多的工作,使它们的运行成本更高。在正常情况下,摄取器在两小时内不会有任何数据,这也会损害摄取器的性能。

如果您要为回填操作摄取旧数据,我建议您只需等待两小时,让所有数据都刷新即可。如果您在正常操作中摄取较旧的日志,并且不喜欢等待,那么您可以考虑更改 query_ingesters_within ,但要意识到这可能会在成本和性能上带来一些负面的操作权衡。

结论

我希望这篇文章有助于解释 Loki 中的失序和旧日志摄取是如何工作的。我们确实努力在支持 Loki 的典型用例和适应其他用例之间取得适当的平衡 - 所有这些都没有增加成本或牺牲性能,至少我们尽了最大努力。

请在下周再次访问我们的 Loki 指南!


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
Prometheus Cloud Native 数据库
Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介
Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介
|
1月前
|
存储 监控 数据可视化
Nginx+Promtail+Loki+Grafana Nginx日志展示
通过这些步骤,你可以将Nginx的日志收集、存储、查询和可视化整合在一起。这样,你就可以在Grafana中轻松地创建和展示Nginx日志的图表和面板。
44 3
|
3月前
|
存储 Prometheus Cloud Native
「译文」开源日志监控:Grafana Loki 简要指南
「译文」开源日志监控:Grafana Loki 简要指南
|
3月前
|
JSON Prometheus Cloud Native
Grafana 系列 -Loki- 基于日志实现告警
Grafana 系列 -Loki- 基于日志实现告警
|
3月前
|
JSON Prometheus Cloud Native
Grafana 系列文章(十二):如何使用 Loki 创建一个用于搜索日志的 Grafana 仪表板
Grafana 系列文章(十二):如何使用 Loki 创建一个用于搜索日志的 Grafana 仪表板
|
3月前
|
存储 Prometheus Cloud Native
Grafana 系列文章(十一):Loki 中的标签如何使日志查询更快更方便
Grafana 系列文章(十一):Loki 中的标签如何使日志查询更快更方便
|
5月前
|
Prometheus Kubernetes Cloud Native
prometheus|云原生|轻型日志收集系统loki+promtail的部署说明
prometheus|云原生|轻型日志收集系统loki+promtail的部署说明
197 0
|
7月前
|
存储 Prometheus Cloud Native
现代化日志解决方案 PLG (Promtail +Loki + Grafana )
综合使用 Promtail、Loki 和 Grafana 可以实现从应用程序生成的日志数据的收集、存储、查询和可视化,有助于更好地理解应用程序的行为,识别问题,以及监视性能和可用性。这一组工具通常在现代DevOps和云原生环境中得到广泛使用
503 0
|
10月前
|
存储 JSON 缓存
K8s日志组件-Loki是如何存储数据的?
日志记录本质上是一个事件。大多数语言、应用程序框架或库都支持日志,表现形式可以是字符串这样原始的非结构化数据,也可以是JSON等半结构化数据。开发者可以通过日志来分析应用的执行状况,报错信息,分析性能…… 正因为日志极其灵活,生成非常容易,没有一个统一的结构,所以它的体量也是最大的。
402 0
|
4天前
|
C++
JNI Log 日志输出
JNI Log 日志输出
12 1