一提交就从界面上消失了,存储用量却一个月没变
目标
亲手写出打开保留并按流设置不同期限的设置并验证,用这份设置启动第二个 Loki,再提交删除请求,用数字确认接收与真正删除之间的时间间隔。
为什么重要
Loki 出厂时保留功能是关闭的。如果没有人打开它,放进去的日志就永远留着,直到账单变成四倍才发现这件事。删除请求也同样有两层——在默认方式下,请求一被接收,查询就会立刻过滤掉那些行,但从存储的对象中真正删除,要等取消等待期过后由 compactor 来做。把“看不见”读成“已删除”,合规报告就会出错,容量规划也会错位。确定保留期限,必须从实测而不是估算出发——查询响应附带的字节数,就是这个出发点。
步骤
- 在
/root/lk-retention中启动 Loki,把date +%s写入/root/lk-retention/anchor.txt,然后用python3 /opt/lab/d5/gen.py retention "$(cat anchor.txt)"放入数据。接着用一小时区间分别查询audit和debug两个流,把响应统计中读取的字节数,以audit_bytes=<정수>和debug_bytes=<정수>(占位符为整数)两行写入/root/lk-retention/01-bytes.txt。 - 用第 1 步一小时的字节数,计算每个流的存储量,做出
/root/lk-retention/budget.tsv。不要表头,共两行,每行是用制表符分隔的四列<스트림><탭><한시간바이트><탭><보존일수><탭><보존기간총바이트>(占位符依次为流、制表符、每小时字节数、制表符、保留天数、制表符、保留期内总字节数)。流依次为audit、debug,保留天数分别取365和1。总字节数是한시간바이트 × 24 × 보존일수(占位符依次为每小时字节数、保留天数)。 - 写出
/root/lk-retention/loki-ret.yaml。以现在在用的loki.yaml为基础,再加上以下内容——server.http_listen_port为3200,server.grpc_listen_port为9096,存储路径放在/tmp/lokiret之下,compactor.retention_enabled为true,compactor.delete_request_store为filesystem,指定compactor.working_directory,limits_config.retention_period为720h。并且loki -config.file=/root/lk-retention/loki-ret.yaml -verify-config必须没有任何错误地结束。 - 在
/root/lk-retention/loki-ret.yaml的limits_config里加上retention_stream列表,让{app="debug"}保留24h,{app="audit"}保留8760h。优先级分别明确写为1和2。然后在/root/lk-retention/04-rules.txt中写两行——rules=<규칙 개수>(占位符为规则个数)和verify=ok(在-verify-config通过时)。 - 用
/root/lk-retention/loki-ret.yaml启动第二个 Loki,等到http://localhost:3200/ready返回ready为止。然后从该服务器的/config里读出三个值,写入/root/lk-retention/05-run.txt——retention_enabled=<값>、retention_period=<값>、compaction_interval=<값>(占位符均为值)。 - 往 3200 端口的 Loki 里放几行,然后请求删除其中一个流的一个区间。请求是向
POST /loki/api/v1/delete传入query、start、end。再在/root/lk-retention/06-delete.txt中写三行——post_code=<HTTP 상태 코드>、requests=<목록에 있는 요청 수>、status=<그 요청의 status 값>(占位符依次为 HTTP 状态码、列表中的请求数、该请求的 status 值)。 - 再次查询你请求删除的那个区间,数一数现在能出来几行,并在服务器设置里找出实际删除是什么时候发生的并确认。在
/root/lk-retention/07-async.txt中写四行——still_visible=<정수>、mode=<deletion_mode 값>、param=<실제 삭제까지 기다리는 시간을 정하는 설정 이름>、value=<서버가 찍은 값 그대로>(占位符依次为整数、deletion_mode 的值、决定等待多久才真正删除的设置名称、服务器印出的值原样)。 - 在
/root/lk-retention/policy.txt中写五行——audit_period=、debug_period=(两者都原样取设置里写的值)、audit_bytes_total=、debug_bytes_total=(第 2 步表中的最后一列)、note=(去掉空格后至少 60 个字,同时写出为什么把两个期限定得不同,以及删除请求不会立即生效这一事实)。
参考
- 工作目录是
/root/lk-retention。第一个 Loki 在第 1 步启动,第二个在第 5 步启动。 - 数据生成器是
/opt/lab/d5/gen.py,使用retention数据。评分器不读这个文件。 - 在本实验里,看不到保留删除真正发生的过程。compactor 默认每 10 分钟运行一次,删除请求默认要等 24 小时。本实验确认的是设置是否有效、服务器是否带着这些值启动、请求是否被接收,以及这件事是异步的。
- 第二个 Loki 只改
http_listen_port会挂掉——grpc_listen_port也要一起改。存储路径(path_prefix和storage_config)也不能与第一个重叠。 - 删除请求的
start和end是以秒为单位的整数。与查询 API 的纳秒不同。 - 保留(Compactor) · 日志删除请求 · 配置文档 · HTTP API
放入两种日志,测量实际字节数
在 /root/lk-retention 中启动 Loki,把 date +%s 写入 /root/lk-retention/anchor.txt,然后用 python3 /opt/lab/d5/gen.py retention "$(cat anchor.txt)" 放入数据。接着用一小时区间分别查询 audit 和 debug 两个流,把响应统计中读取的字节数,以 audit_bytes=<정수> 和 debug_bytes=<정수>(占位符为整数)两行写入 /root/lk-retention/01-bytes.txt。
统计是 query_range 响应中的 data.stats.summary.totalBytesProcessed。两个流的性质不同——一个是偶尔才积累的审计记录,一个是每秒喷出好几行的调试日志。容量规划就从这个差别开始。
从实测值计算保留预算
用第 1 步一小时的字节数,计算每个流的存储量,做出 /root/lk-retention/budget.tsv。不要表头,共两行,每行是用制表符分隔的四列 <스트림><탭><한시간바이트><탭><보존일수><탭><보존기간총바이트>(占位符依次为流、制表符、每小时字节数、制表符、保留天数、制表符、保留期内总字节数)。流依次为 audit、debug,保留天数分别取 365 和 1。总字节数是 한시간바이트 × 24 × 보존일수(占位符依次为每小时字节数、保留天数)。
这个计算的要点,是把两行的最后一列并排放着看。行数多十倍的一方如果保留期限短,总量可能会反过来——这种逆转,就是保留策略要按流区分的原因。
写出打开保留的设置并验证
写出 /root/lk-retention/loki-ret.yaml。以现在在用的 loki.yaml 为基础,再加上以下内容——server.http_listen_port 为 3200,server.grpc_listen_port 为 9096,存储路径放在 /tmp/lokiret 之下,compactor.retention_enabled 为 true,compactor.delete_request_store 为 filesystem,指定 compactor.working_directory,limits_config.retention_period 为 720h。并且 loki -config.file=/root/lk-retention/loki-ret.yaml -verify-config 必须没有任何错误地结束。
-verify-config 不仅检查语法,也检查设置的组合是否讲得通——通过的话没有输出。两个端口都要改的原因,在下一步就会显露出来。如果不改存储路径,两个进程就会使用与现在运行的 Loki 相同的目录。
按流设置不同的保留期限
在 /root/lk-retention/loki-ret.yaml 的 limits_config 里加上 retention_stream 列表,让 {app="debug"} 保留 24h,{app="audit"} 保留 8760h。优先级分别明确写为 1 和 2。然后在 /root/lk-retention/04-rules.txt 中写两行——rules=<규칙 개수>(占位符为规则个数)和 verify=ok(在 -verify-config 通过时)。
retention_stream 是由 selector、priority、period 三项组成的条目列表。选择器就是 LogQL 流选择器的语法,要放在引号里。如果不写优先级,重叠的规则里哪边获胜就难以预测。
启动第二个 Loki——端口有两个
用 /root/lk-retention/loki-ret.yaml 启动第二个 Loki,等到 http://localhost:3200/ready 返回 ready 为止。然后从该服务器的 /config 里读出三个值,写入 /root/lk-retention/05-run.txt——retention_enabled=<값>、retention_period=<값>、compaction_interval=<값>(占位符均为值)。
日志要留成文件(> ret.log 2>&1)。如果马上就挂了,看那个文件的最后一行——只改一个端口时出的错就原样写在那里。/ready 要 20 秒左右,所以不要用固定的 sleep,要用检查条件的循环。
提交删除请求并查看列表
往 3200 端口的 Loki 里放几行,然后请求删除其中一个流的一个区间。请求是向 POST /loki/api/v1/delete 传入 query、start、end。再在 /root/lk-retention/06-delete.txt 中写三行——post_code=<HTTP 상태 코드>、requests=<목록에 있는 요청 수>、status=<그 요청의 status 값>(占位符依次为 HTTP 状态码、列表中的请求数、该请求的 status 值)。
区间要用以秒为单位的整数给出(不是纳秒)。列表用 GET 向同一个路径询问。如果请求被以 400 拒绝,看看有没有设置 delete_request_store,区间是不是写反了。
应用 ① ——看不见和被删掉是两回事
再次查询你请求删除的那个区间,数一数现在能出来几行,并在服务器设置里找出实际删除是什么时候发生的并确认。在 /root/lk-retention/07-async.txt 中写四行——still_visible=<정수>、mode=<deletion_mode 값>、param=<실제 삭제까지 기다리는 시간을 정하는 설정 이름>、value=<서버가 찍은 값 그대로>(占位符依次为整数、deletion_mode 的值、决定等待多久才真正删除的设置名称、服务器印出的值原样)。
查询结果为 0,不等于存储里已经删掉了。在 /config 里找出表示删除方式的设置,以及 compactor: 块里的“可以取消请求的期间”。把两个值并排放在一起,就能得出“为什么容量不降”的答案。
应用 ② ——把保留策略钉成文档
在 /root/lk-retention/policy.txt 中写五行——audit_period=、debug_period=(两者都原样取设置里写的值)、audit_bytes_total=、debug_bytes_total=(第 2 步表中的最后一列)、note=(去掉空格后至少 60 个字,同时写出为什么把两个期限定得不同,以及删除请求不会立即生效这一事实)。
策略文档里的值如果与设置文件错位,这份文档还不如没有。要原样从设置里取。最后一行是写给下一个接手这个集群的人读的句子——把数字的依据和时间延迟一起写下来,就不会被问两遍同样的问题。