TT Lab
开始
学习 学习路径 课程

Loki — 不索引日志的日志库

不打开它,日志就永远留着

在 TT Lab 中继续学习

一句话总结

Loki 出厂时保留功能是关闭的。不打开,放进去的日志就永远留着;就算打开,删除也是 compactor 按自己的周期执行的异步任务,所以“删了”和“看不见了”之间有时间间隔。

为什么需要它

有个团队的存储账单在三个月里变成了原来的四倍。在仪表板上打开较旧的区间,一年前的日志也出来了。没有人配置过保留,也没有人知道这件事——因为默认值是“不删除”。

也有相反方向的事故。一个团队发现混进了个人信息,提交了删除请求,看到请求刚提交那行日志就从查询里消失了,便报告说“已经删了”。一个月后,存储容量原封不动。默认的删除方式(filter-and-delete)在请求被接收的瞬间就会在查询时过滤掉,但从对象里真正删除,要等取消等待期(默认 24 小时)过后由 compactor 来做。看不见和被删掉是两回事。

工作原理

保留由 compactor 来做。要同时看三件事。

设置 默认值 含义
compactor.retention_enabled false 关着就什么也不删
compactor.compaction_interval 10m 运行压缩和保留的周期
compactor.retention_delete_delay 2h 标记为待删除之后,到真正删除之前等待的时间

保留期限本身用 limits_config.retention_period 来定,想按流分别设置的话,就在 retention_stream 列表里写上选择器、优先级和期限。多条规则重叠时,优先级高的获胜。审计日志保留一年、调试日志保留一天——在同一个集群里这样区分,是降低成本最大的旋钮。

删除特定的行与保留是不同的路。给 POST /loki/api/v1/delete 传入选择器和区间,删除请求就会被接收,状态变成 received。在默认的 deletion_mode 即 filter-and-delete 下,从那一刻起查询就会过滤掉这些行,所以查询马上就显示为空。但请求在 delete_request_cancel_period(默认 24 小时)内可以取消,真正从存储的对象中删除,要等过了这段时间之后,由 compactor 来做。

这里常常错位的是期望与保证。“查询里没了”是一个表象,不是“已删除”的证据。如果因合规要求有时限,就要把这个时限与取消等待期、compactor 周期一起算进去,如果是在等容量下降,就更是如此。

容量规划反而很简单。用查询响应附带的 totalBytesProcessed 测出一小时的实际字节数,乘以一天、一个月,再乘以各流的保留期限后相加。压缩率则对照实际存储的数据块文件的大小来校正。从实测而不是估算出发,讨论缩短保留期限时就是在用数字说话。

在现场相遇的样子

最常见的错误是打开了保留却没有启动 compactor。在微服务部署中,compactor 是单独的组件,整个集群里必须恰好只运行一个。设置里写了 retention_enabled: true,却没有 compactor,什么也不会发生,而只看设置文件,会觉得它是开着的。

第二是漏掉流规则的优先级。优先级相同的两条规则作用在同一个流上,哪边获胜就很难预测。每次加规则都明确写上优先级,是更安全的习惯。

第三是“删了,容量却没降”。删除标记与真正删除对象之间有等待时间,对象存储一侧还可能另有一层生命周期策略。

下一项实验要做什么

亲手写出打开保留并按流设置不同期限的设置文件,用 loki -verify-config 确认的不是语法,而是设置本身是否有效。用这份设置在另一个端口上启动第二个 Loki(连 gRPC 端口也要改),用 /config 确认服务器确实带着这些值启动之后,提交删除请求,一并记录它被接收,以及不会马上消失。最后根据实测字节数计算保留预算,做成策略文档。