TT Lab
はじめる
学ぶ 学習パス コース

Loki — ログを索引しないログストア

要求した途端に画面から消えたのに、保存容量は一か月そのままだった

TT Labで続きを見る

目標

保持をオンにして、ストリームごとに異なる期間をかける設定を自分で書いて検証し、その設定で2つ目のLokiを起動したあと、削除リクエストを出して、受理と実際の削除の間の時間差を数字で確認します。

なぜ重要なのか

Lokiは保持をオフにしたまま出発します。誰もオンにしなければ、入れたログは永遠に残り、請求書が4倍になってから、その事実に気づきます。削除リクエストも同様に2層です。デフォルトの方式では、リクエストが受理されるとすぐにクエリがその行をふるい落としてくれますが、保存されたオブジェクトから実際に消えるのは、キャンセル猶予期間が過ぎたあとの、コンパクターの仕事です。「見えない」を「消えた」と読むと、規制対応の報告書が間違ったものになり、容量計画もずれます。保持期間を決める作業は、推定ではなく実測から出発する必要があります。クエリのレスポンスに載ってくるバイト数が、その出発点です。

ステップ

  1. /root/lk-retentionでLokiを起動し、date +%sを/root/lk-retention/anchor.txtに書いたあと、python3 /opt/lab/d5/gen.py retention "$(cat anchor.txt)"でデータを入れてください。そして、auditとdebugの2つのストリームを1時間の区間でそれぞれクエリして、レスポンス統計の読んだバイト数を/root/lk-retention/01-bytes.txtにaudit_bytes=<정수>とdebug_bytes=<정수>の2行で書いてください(プレースホルダーは整数です)。
  2. ステップ1の1時間分のバイト数から、ストリームごとの保存量を計算して、/root/lk-retention/budget.tsvを作成してください。ヘッダーなしで2行で、各行はタブで区切った4つの欄<스트림><탭><한시간바이트><탭><보존일수><탭><보존기간총바이트>(プレースホルダーは順に、ストリーム、タブ、1時間のバイト数、保持日数、保持期間の総バイト数です)です。ストリームは順にaudit、debugで、保持日数はそれぞれ365と1とします。総バイト数は한시간바이트 × 24 × 보존일수(プレースホルダーは1時間のバイト数と保持日数です)です。
  3. /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が、何のエラーもなく終了する必要があります。
  4. /root/lk-retention/loki-ret.yamlのlimits_configにretention_streamのリストを加えて、{app="debug"}は24h、{app="audit"}は8760hで保持されるようにしてください。優先度は、それぞれ1と2と明示します。そして、/root/lk-retention/04-rules.txtに2行を書いてください。rules=<규칙 개수>とverify=ok(-verify-configが通ったとき)です(プレースホルダーはルールの個数です)。
  5. /root/lk-retention/loki-ret.yamlで2つ目のLokiを起動し、http://localhost:3200/readyがreadyを返すまで待ってください。そして、そのサーバーの/configから3つの値を読み取って、/root/lk-retention/05-run.txtに書きます。retention_enabled=<값>、retention_period=<값>、compaction_interval=<값>です(プレースホルダーは値です)。
  6. 3200番ポートのLokiに行を何行か入れ、そのうち1つのストリームの1つの区間を削除するようリクエストしてください。リクエストはPOST /loki/api/v1/deleteにquery・start・endを渡します。そして/root/lk-retention/06-delete.txtに3行を書いてください。post_code=<HTTP 상태 코드>、requests=<목록에 있는 요청 수>、status=<그 요청의 status 값>です(プレースホルダーは順に、HTTPステータスコード、一覧にあるリクエスト数、そのリクエストのstatusの値です)。
  7. 削除をリクエストしたその区間をもう一度クエリして、現在何行出るかを数え、実際の削除がいつ起きるかを、サーバー設定から探して確認してください。/root/lk-retention/07-async.txtに4行を書きます。still_visible=<정수>、mode=<deletion_mode 값>、param=<실제 삭제까지 기다리는 시간을 정하는 설정 이름>、value=<서버가 찍은 값 그대로>です(プレースホルダーは順に、整数、deletion_modeの値、実際の削除までの待ち時間を決める設定名、サーバーが出力した値そのままです)。
  8. /root/lk-retention/policy.txtに5行を書いてください。audit_period=、debug_period=(どちらも設定に書いた値そのまま)、audit_bytes_total=、debug_bytes_total=(ステップ2の表の最後の欄)、note=(空白を除いて60文字以上、なぜ2つの期間を異なる値にしたのかと、削除リクエストがすぐには反映されないという事実を一緒に書きます)。

参考

2種類のログを入れて、実際のバイト数を測る

/root/lk-retentionでLokiを起動し、date +%sを/root/lk-retention/anchor.txtに書いたあと、python3 /opt/lab/d5/gen.py retention "$(cat anchor.txt)"でデータを入れてください。そして、auditとdebugの2つのストリームを1時間の区間でそれぞれクエリして、レスポンス統計の読んだバイト数を/root/lk-retention/01-bytes.txtにaudit_bytes=<정수>とdebug_bytes=<정수>の2行で書いてください(プレースホルダーは整数です)。

統計は、query_rangeのレスポンスのdata.stats.summary.totalBytesProcessedです。2つのストリームは性格が違います。1つはまれにたまる監査記録、もう1つは毎秒数行ずつ流れ込むデバッグログです。容量計画は、この違いから始まります。

実測から保持の予算を計算する

ステップ1の1時間分のバイト数から、ストリームごとの保存量を計算して、/root/lk-retention/budget.tsvを作成してください。ヘッダーなしで2行で、各行はタブで区切った4つの欄<스트림><탭><한시간바이트><탭><보존일수><탭><보존기간총바이트>(プレースホルダーは順に、ストリーム、タブ、1時間のバイト数、保持日数、保持期間の総バイト数です)です。ストリームは順にaudit、debugで、保持日数はそれぞれ365と1とします。総バイト数は한시간바이트 × 24 × 보존일수(プレースホルダーは1時間のバイト数と保持日数です)です。

この計算の要点は、2行の最後の欄を並べて見ることです。行数が10倍多いほうが保持期間が短いと、総量が逆転することがあります。その逆転が、保持ポリシーをストリームごとに分ける理由です。

保持をオンにする設定を書いて検証する

/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と同じディレクトリを、2つのプロセスが使うことになります。

ストリームごとに異なる保持期間

/root/lk-retention/loki-ret.yamlのlimits_configにretention_streamのリストを加えて、{app="debug"}は24h、{app="audit"}は8760hで保持されるようにしてください。優先度は、それぞれ1と2と明示します。そして、/root/lk-retention/04-rules.txtに2行を書いてください。rules=<규칙 개수>とverify=ok(-verify-configが通ったとき)です(プレースホルダーはルールの個数です)。

retention_streamは、selector・priority・periodの3つの欄を持つ項目のリストです。セレクターはLogQLのストリームセレクターの文法そのままで、引用符の中に入れます。優先度を書かないと、重なるルールでどちらが勝つか予測しにくくなります。

2つ目のLokiを起動する: ポートは2つ

/root/lk-retention/loki-ret.yamlで2つ目のLokiを起動し、http://localhost:3200/readyがreadyを返すまで待ってください。そして、そのサーバーの/configから3つの値を読み取って、/root/lk-retention/05-run.txtに書きます。retention_enabled=<값>、retention_period=<값>、compaction_interval=<값>です(プレースホルダーは値です)。

ログはファイルに残してください(> ret.log 2>&1)。もしすぐに落ちるなら、そのファイルの最後の行を見てください。ポートを1つだけ変えたときに出るエラーが、そこにそのまま書かれています。/readyは20秒ほどかかるので、固定のsleepの代わりに、条件を見るループを使ってください。

削除リクエストを出して、一覧を見る

3200番ポートのLokiに行を何行か入れ、そのうち1つのストリームの1つの区間を削除するようリクエストしてください。リクエストはPOST /loki/api/v1/deleteにquery・start・endを渡します。そして/root/lk-retention/06-delete.txtに3行を書いてください。post_code=<HTTP 상태 코드>、requests=<목록에 있는 요청 수>、status=<그 요청의 status 값>です(プレースホルダーは順に、HTTPステータスコード、一覧にあるリクエスト数、そのリクエストのstatusの値です)。

区間は秒単位の整数で指定します(ナノ秒ではありません)。一覧は、同じパスにGETで問い合わせます。リクエストが400で拒否されるなら、delete_request_storeが設定されているか、区間が逆になっていないかを見てください。

応用①: 見えないことと、消えたことは違う

削除をリクエストしたその区間をもう一度クエリして、現在何行出るかを数え、実際の削除がいつ起きるかを、サーバー設定から探して確認してください。/root/lk-retention/07-async.txtに4行を書きます。still_visible=<정수>、mode=<deletion_mode 값>、param=<실제 삭제까지 기다리는 시간을 정하는 설정 이름>、value=<서버가 찍은 값 그대로>です(プレースホルダーは順に、整数、deletion_modeの値、実際の削除までの待ち時間を決める設定名、サーバーが出力した値そのままです)。

参照結果が0だからといって、ストレージから消えたわけではありません。/configから、削除方式を表す設定と、compactor:ブロックの「リクエストをキャンセルできる期間」を探してください。2つの値を並べて見れば、「なぜ容量が減らないのか」の答えが出ます。

応用②: 保持ポリシーを文書として固定する

/root/lk-retention/policy.txtに5行を書いてください。audit_period=、debug_period=(どちらも設定に書いた値そのまま)、audit_bytes_total=、debug_bytes_total=(ステップ2の表の最後の欄)、note=(空白を除いて60文字以上、なぜ2つの期間を異なる値にしたのかと、削除リクエストがすぐには反映されないという事実を一緒に書きます)。

ポリシー文書の値が設定ファイルとずれていたら、その文書はないよりも悪いです。設定からそのまま持ってきてください。最後の行は、次にこのクラスターを担当する人が読む文章です。数字の根拠と時間の遅延を一緒に書いておけば、同じ質問を2回受けずに済みます。