Collector を本番対応にする:メモリ制限、バッチ処理、リトライ
過負荷や障害の間もテレメトリが生き残るように、processor、キュー、永続ストレージを設定します。
ノート PC で動作する Collector も、本番では行き詰まることがあります。トラフィックのスパイクがメモリを使い果たす、バックエンドの障害でデータが失われる、再起動で転送中のすべてが失われるなどです。解決策はすべて設定です。このガイドでは、すべての本番の Collector が持つべき processor と exporter の設定、そしてそれらを置く順序を説明します。
ベースのパイプライン
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 80
spike_limit_percentage: 20
batch:
timeout: 5s
send_batch_size: 8192
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/backend]
順序は重要です。processor は、列挙された順に実行されます。memory_limiter を最初に置き、他のものがメモリを消費する前に、バックプレッシャーが receiver に届くようにします。batch は、フィルタリングやエンリッチメントの後の最後に置き、バッチが最終的なデータから作られるようにします。
memory_limiter
Collector のメモリを監視し、使用量が高すぎるときは新しいデータを拒否します。そのため、プロセスはオペレーティングシステムに強制終了されるのではなく、減速します。
processors:
memory_limiter:
check_interval: 1s
limit_mib: 4000
spike_limit_mib: 800
check_intervalは、メモリを測定する頻度です。1sが推奨され、デフォルトの0sは、定期的なチェックを無効にします。limit_mibは、ヒープメモリのハードリミットです。プロセス全体は、通常、それよりやや多く使用します。spike_limit_mibは、チェック間の想定される最大のジャンプで、デフォルトは制限の 20% です。ソフトリミットは、limit_mibからspike_limit_mibを引いたものです(ここでは 3200 MiB)。limit_percentageとspike_limit_percentageは、同じ制限を、利用可能なメモリに対する割合として表します(cgroup を持つ Linux)。メモリ制限が Kubernetes によって設定されるコンテナに適しています。limit_mibも設定されている場合は、それが優先されます。
ソフトリミットを超えると、processor は前のコンポーネントにエラーを返してデータを拒否し、行儀のよい送信者はリトライするか、速度を落とします。ハードリミットを超えると、ガベージコレクションも強制します。カーネルより先に動作するように、コンテナのメモリ制限より少し低く設定してください。
batch
バッチ処理は、エクスポートが少なく、大きくなるように項目をグループ化し、ネットワークとバックエンドの負荷を節約します。
processors:
batch:
timeout: 5s # バッチがいっぱいでなくても、この時間後に送信する
send_batch_size: 8192 # 目標のバッチサイズ
send_batch_max_size: 0 # 0 は上限なしを意味する
レイテンシーのために timeout を、スループットのために send_batch_size を調整します。最近の Collector のバージョンでは、exporter のキュー内でもバッチ処理ができます。お使いのバージョンの exporter helper のドキュメントを確認してください。
exporter のキューとリトライ
ネットワーク経由で送信する exporter には、送信キューとリトライポリシーがあります。これらは processor ではなく exporter の中にあり、バックエンドの短い停止から身を守ってくれるものです。
exporters:
otlp/backend:
endpoint: backend.example.com:4317
sending_queue:
enabled: true
queue_size: 5000 # デフォルトは 1000
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 10m # デフォルトは 300s
数値の考え方:
- キューは、バックエンドが遅いまたはダウンしている間、バッチをバッファリングします。大きなキューはより長いインシデントに耐えられますが、メモリを多く使います。
retry_on_failureは、max_elapsed_timeまで、増加する遅延でリトライします。その後、データは破棄されます。- 損失なしに耐えたい最長の停止と、ご自身のボリュームに合わせて、両方のサイズを決めます。
永続キュー:再起動に耐える
デフォルトでは、キューはメモリ内にあるため、クラッシュするとキューに入っていたものが失われます。file_storage extension でディスクを裏付けにします。
extensions:
file_storage:
directory: /var/lib/otelcol/storage
exporters:
otlp/backend:
endpoint: backend.example.com:4317
sending_queue:
storage: file_storage
service:
extensions: [file_storage]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/backend]
3 つの要素が必要です。extension を定義し、exporter で参照し、service.extensions で有効にします。そのディレクトリに永続ボリューム(たとえば StatefulSet 用の PersistentVolumeClaim)をマウントします。ディスクがいっぱいになるか故障した場合、あるいはバックエンドがリトライの制限を超えてダウンし続けた場合には、それでもデータが失われる可能性があるため、ディスクの使用量を監視してください。
基本を超えて有用な processor
属性を追加または変更する:
processors:
resource/env:
attributes:
- key: deployment.environment.name
value: production
action: upsert
attributes/scrub:
actions:
- key: http.request.header.authorization
action: delete
- key: user.email
action: hash
resource は、プロデューサーを記述する属性(バッチ全体に適用)を編集し、attributes は、スパンごと、メトリクスのデータポイントごと、ログレコードごとの属性を編集します。これらを使って、環境のラベルを追加し、データがネットワークを出る前に、機密性のある値を削除またはハッシュ化します。
OpenTelemetry Transformation Language(OTTL)で書かれた filter processor で、ノイズを破棄する:
processors:
filter/health:
error_mode: ignore
traces:
span:
- 'attributes["url.path"] == "/healthz"'
- 'attributes["url.path"] == "/ready"'
transform processor で、データを変換する:
processors:
transform/normalize:
error_mode: ignore
trace_statements:
- context: span
statements:
- set(attributes["team"], "payments") where resource.attributes["service.name"] == "checkout"
OTTL は強力なので、本番で有効にする前に、データのコピーに対して debug exporter でステートメントをテストしてください。ステートメントの構文と利用可能なコンテキストは、バージョン間で変わるため、お使いのバージョンの processor の README を確認してください。これらの processor は、contrib ディストリビューションにあります。
Collector 自体を守る
- Kubernetes のリソースの requests と limits を設定し、
memory_limiterを limit より低く保ちます。 health_checkを追加し、liveness と readiness の probe に使います。- キューのサイズ、破棄された項目、拒否されたデータについて、ポート 8888 の Collector 自身のメトリクスを監視します。
otelcol_exporter_queue_sizeが容量に近づいたとき、または exporter が送信の失敗を報告したときに、アラートを出します。 - ゲートウェイには、Service の背後で複数のレプリカを実行し、想定するバーストに合わせて、単一のレプリカのサイズを決めます。
チェックリスト
memory_limiterが、すべてのパイプラインの最初の processor であること。batchが、最後の processor であること。- ネットワークの exporter に、停止への許容度に合わせたサイズの、送信キューとリトライポリシーがあること。
- データの損失が許されない場所に、永続キューが設定されていること。
- 機密性のある属性が、エッジで削除またはハッシュ化されること。
- ヘルスチェック、リソースの制限、Collector のメトリクスが揃っていること。
人気のガイド
-
OpenTelemetry を解説する:SDK、OTLP、Collector YAML を 1 行も書く前に、構成要素と、設定が存在する 3 つの場所を理解します。 -
Collector の設定モデル:コンポーネント、パイプライン、プロバイダー Collector の YAML のルールを学びます。命名、パイプライン、connector、ファイルのマージ、環境変数。 -
OTEL_* 環境変数で SDK を設定する 標準の変数を使って、任意の言語のサービス名、exporter、サンプリング、制限を設定します。 -
コードを変更せずにアプリを計装する:Java、Python、Node.js 環境変数とコマンドラインのフラグだけで、OpenTelemetry のエージェントをアタッチします。 -
Helm で Kubernetes に Collector をデプロイする 公式チャートをインストールし、ログとメトリクスに preset を使い、values ファイルで設定を上書きします。 -
Collector と SDK のトラブルシューティング テレメトリが届かないときの体系的なチェックリスト:debug exporter、ヘルスチェック、内部メトリクス、よくある間違い。