投稿日:
更新日:

Batch Processor から Exporter Helper へ移行する

Authors

目次

はじめに

OpenTelemetry Collector はテレメトリデータを効率的に送信するためにデータをバッチ化する仕組みを備えています。 従来、この役割は Batch Processor と呼ばれる Processor のコンポーネントが担っており、全ての Collector に設定することが推奨されていました。

一方で、Batch Processor はエクスポート失敗時にバッチ全体がドロップされる問題や、gRPC の ResourceExhausted エラー等、本番運用においていくつかの深刻な課題が顕在化していました。

これを受け、コアメンテナの Bogdan 氏はバッチ処理を Exporter レイヤへ移行することを提案しました。 2026 年 1 月現在、Batch Processor は非推奨化となり、後継である Exporter Helpersending_queue にバッチ機能が統合されています。

今回のブログでは Batch Processor から Exporter Helper へのバッチ機能移行について紹介したいと思います。

OpenTelemetry Collector のパイプラインの基本構成については以下の記事で紹介しています。

Batch Processor の課題

Batch Processor はパイプラインの Processor 段階でテレメトリデータをバッチ化し、後続の Exporter へまとめて送信するコンポーネントです。

一見すると効率的な仕組みですが、本番運用においてはいくつかの深刻な課題が存在します。

エクスポート失敗時のデータロス

Batch Processor は、バッチ化したデータを Exporter に渡した後、エクスポートが失敗してもリトライを行いません。 Issue #12443 で報告されている通り、エクスポートに失敗したデータは警告ログが出力されるだけでバッチ全体がドロップされます。

これは Batch Processor がパイプラインの Processor 段階に位置しているため、Exporter 側の retry_on_failuresending_queue と連携できないことに起因しています。

Exporter 側で sending_queue を有効化していたとしても、Batch Processor から送信されるデータは既にバッチ化された大きな単位でキューに投入されるため、キューの容量を圧迫しやすくなります。

gRPC の ResourceExhausted エラー

Batch Processor は send_batch_size(アイテム数)でバッチサイズを制御しますが、バイト数での制御には対応していません。

テレメトリデータの 1 アイテムあたりのサイズは均一ではなく、大きなスタックトレースを含むスパンや、多数の属性を持つログレコード等、シリアライズ後のサイズが大きく変動します。 そのため、アイテム数ベースで同じバッチサイズであっても、シリアライズ後の実際のバイトサイズが gRPC のデフォルトメッセージ上限(4 MB)を超えてしまうケースが発生します。

drop-batch-data.png

この ResourceExhausted エラーは gRPC のステータスコード上 Permanent Error(永続的なエラー)として扱われるため、リトライ対象外となりバッチ全体がドロップされます。

Issue #6046 では send_batch_max_size_bytes で対応するような提案も出ていたみたいですが、最終的に Batch Processor 側での対応は見送られ、Exporter Helper のバッチ機能で解決する方針が取られたようです。

Collector 再起動時のバッファ消失

Batch Processor はデータをインメモリでバッファリングします。 そのため、OOM やデプロイ、ノードの再起動等によって Collector プロセスが終了した場合、バッファ内のデータはすべて失われます。

Dash0 が実施したクラッシュテストでは、Batch Processor を使用した構成で Collector を再起動した際にバッファ内のトレースデータが 100% 消失したのに対し、Exporter Helper の永続キュー(file_storage)を使用した構成ではデータの 100% が回復したことが報告されています。

これらの課題を踏まえ、Batch Processor はパイプライン内でのバッチ化というアーキテクチャ上の制約により、送信失敗時のリカバリが困難であることが明らかになりました。

Exporter Helper のバッチ機能

OpenTelemetry Collector の Exporter Helper(exporterhelperパッケージは、Go の exporterhelper を利用して構築されたすべての Exporter が共通で利用できるキューイング・リトライ・バッチ処理の基盤です。

v0.123.0 以降、sending_queue 内にバッチ機能(batch)が統合され、バッチ処理をキューイングやリトライと同じ Exporter 内で一元管理できるようになりました。

sending_queue.batch の概要

sending_queue.batch は、Exporter の送信キュー内部でバッチ化を行う仕組みです。 バッチ処理がリトライやキュー管理と同じレイヤに統合されているため、エクスポート失敗時のリカバリが機能します。

データの流れは以下の通りです。

  1. テレメトリデータが sending_queue に投入される
  2. batch モジュールがキューからデータを取り出し、min_size に達するか flush_timeout が経過するまでバッファリングする
  3. max_size が設定されている場合、超過したバッチは自動的に分割される
  4. num_consumers で指定された数のワーカが並行してバッチを取得し、バックエンドへ送信する
  5. 送信に失敗した場合、retry_on_failure によって指数バックオフでリトライされる
  6. 永続化(storage)が設定されている場合、データはディスク上の WAL に書き込まれ、Collector の再起動後も復元される

設定項目

sending_queue.batch は明示的に有効化する必要があります。(デフォルトでは無効)

主要な設定項目を以下の通りです。

  • バッチ制御
設定項目デフォルト値説明
flush_timeout200msバッチサイズに関わらず送信を実行するタイムアウト時間
min_size8192送信をトリガする最小アイテム数(またはバイト数)
max_size0(無制限)バッチの最大サイズ(超過した場合はバッチが分割される)
  • キュー制御
設定項目デフォルト値説明
sizerrequestsキュー容量の計測単位(requests / items / bytes
queue_size1000キューの最大容量(sizer で指定した単位で計測される)
num_consumers10キューからデータを読み出して並行送信するワーカ数
  • リトライ制御
設定項目デフォルト値説明
retry_on_failure.enabledtrueリトライの有効・無効
retry_on_failure.initial_interval5sリトライの初期間隔
retry_on_failure.max_interval30sリトライの最大間隔
retry_on_failure.max_elapsed_time300sリトライを継続する最大経過時間

sizer によるバッチサイズ制御

sizer はキュー容量とバッチサイズの計測単位を決定する設定です。 用途に応じて 3 つの単位から選択できます。

  • requests:リクエスト単位
    • 最もパフォーマンスが高い
    • 従来の Batch Processor と同等のバッチ単位
  • items:アイテム単位
    • スパン・メトリクス・ログレコードの個数で計測
    • Batch Processor の send_batch_size に相当
  • bytes:バイト単位
    • シリアライズ後のバイトサイズで計測
    • gRPC のメッセージ上限を考慮した制御が可能

特に bytes sizer は、Batch Processor では実現できなかったバイトサイズベースのバッチ制御を可能にします。 gRPC のデフォルトメッセージ上限(4 MB)を超えないように max_size を設定することで、ResourceExhausted エラーを防止できます。

永続キュー

sending_queuestorage オプションを設定することで、キューのデータをディスク上に永続化できます。 File Storage Extension と組み合わせることで Collector の再起動後もキュー内のデータが復元され、データロスを防止できます。

Batch Processor と Exporter Helper の比較

Batch Processor と Exporter Helper のバッチ機能(sending_queue.batch)の主な違いについて紹介します。

パイプラインにおける位置

batch-processor-and-exporter-helper.png

Batch Processor はパイプラインの Processor 段階に位置するため、Exporter とは独立したコンポーネントとして動作します。

一方、sending_queue.batch は Exporter 内部に統合されているため、キューイング・バッチ処理・リトライ・エクスポートが同一コンポーネント内で一貫して管理されます。

機能比較

観点Batch ProcessorExporter Helper
パイプライン上の位置Processor 段階Exporter 段階
エクスポート失敗時の挙動バッチをドロップretry_on_failure でリトライ
バッチサイズの制御アイテム数のみアイテム数 / バイト数 / リクエスト数
gRPC メッセージ上限への対応不可bytes sizer + max_size で制御可能
永続化不可(インメモリのみ)file_storage によるディスク永続化が可能
デリバリ保証At-most-onceAt-least-once(永続化有効時)
運用非推奨現在の推奨方式

エクスポート失敗時の比較

Batch Processor と sending_queue.batch では、エクスポートに失敗した際のデータの扱いが大きく異なります。

Batch Processor の場合

Batch Processor ではエクスポートに失敗したバッチはリトライされず、そのままドロップされます。

sending_queue.batch の場合

sending_queue.batch では、エクスポートに失敗したデータは retry_on_failure によって指数バックオフでリトライされます。 永続キューを有効にしている場合は、Collector が再起動してもキュー内のデータが復元されるため、データロスのリスクを大幅に低減できます。

移行手順と設定例

Batch Processor から Exporter Helper(sending_queue.batch)への移行は、パイプラインから Batch Processor を取り除き、Exporter 側のバッチ設定を有効化する形で行います。

基本的な移行

Batch Processor あり

sending_queue.batch に移行

設定値のマッピング

Batch Processor の設定項目は、sending_queue.batch の以下の項目に対応します。

Batch Processorsending_queue.batch説明
timeoutbatch.flush_timeoutバッチ送信のタイムアウト時間
send_batch_sizebatch.min_size送信をトリガする最小バッチサイズ
send_batch_max_sizebatch.max_sizeバッチの最大サイズ(超過時に分割)

queue_size の算出

sending_queuesizerrequests(デフォルト)から items に変更する場合、queue_size の単位がリクエスト数からアイテム数に変わるため、値を大幅に増やす必要があります。

v0.123.0 のリリースノートではデフォルトのバッチ設定で約 5000 倍に増やすことが推奨されています。

例えば、従来 queue_size: 1000 / send_batch_size: 4096 であった場合、移行後は queue_size: 5000000(1000 * 5000)程度に設定します。

Load Balancing Exporter での構成例

Load Balancing Exporter を使用している場合、トップレベルの sending_queue にバッチ設定を適用できます。

Batch Processor あり

sending_queue.batch に移行

Load Balancing Exporter では、トップレベルの sending_queue が有効な場合、子 Exporter(protocol.otlp)の sending_queue は自動的に無効化され、二重キューイングを防止します。

なお、Load Balancing Exporter ではすべての子 Exporter が同一の sending_queue 設定を共有するため、永続キュー(storage)はサポートされていません。

移行時の注意点

移行にあたっては、以下の点を考慮する必要があります。

  • sending_queue.batch はデフォルトでは無効なため、batch: {} を明示的に指定して有効化する
  • sizeritemsbytes に変更した場合、queue_size の単位が変わるため、適切な値に調整する
  • exporterhelper を利用して構築された Exporter であれば、OTLP Exporter 以外でもバッチ機能を利用できる
  • Batch Processor の完全な廃止時期は未定だが、コアメンテナにより EOL が近いことが明言されている

まとめ

今回のブログでは OpenTelemetry Collector の Batch Processor が抱えていた課題と、Exporter Helper のバッチ機能(sending_queue.batch)への移行について紹介しました。

Batch Processor はパイプラインの Processor 段階でバッチ化を行うため、エクスポート失敗時のリトライや永続化との連携が難しく、本番運用においてデータロスのリスクがありました。 sending_queue.batch は、バッチ処理をキューイングやリトライと同じ Exporter 内に統合することで、これらの課題を解決します。

移行自体は設定ファイルの変更が中心であり、パイプラインから Batch Processor を削除して Exporter 側のバッチ設定を有効化するだけで完了します。 ただし、sizer の変更に伴う queue_size の調整や、Load Balancing Exporter を利用している場合は固有の制約等、構成に応じた考慮が必要です。

Batch Processor は EOL が見込まれるため、早めに sending_queue.batch への移行を検討しましょう。

参考・引用