レジリエンス

回復力のあるOTelコレクターパイプラインの構成方法

OpenTelemetryコレクターは、テレメトリーの処理とエクスポートにおけるデータ損失を最小限に抑えるためのコンポーネントと構成で設計されています。 しかし、データ損失が発生する可能性のあるシナリオと、それらを軽減する方法を理解することは、回復力のあるオブザーバビリティパイプラインにとって重要です。

コレクターのレジリエンスを理解する

回復力のあるコレクターは、悪条件に直面してもテレメトリーデータのフローと処理能力を維持し、オブザーバビリティパイプライン全体が機能し続けることを保証します。

コレクターのレジリエンスは主に、構成されたエンドポイント(トレース、メトリクス、またはログの宛先)が利用できなくなった場合や、コレクターインスタンス自体にクラッシュなどの問題が発生した場合に、データをどのように処理するかにかかっています。

送信キュー(インメモリバッファリング)

コレクターのエクスポーターに組み込まれた最も基本的なレジリエンスの形態は、送信キューです。

  • 仕組み: エクスポーターが構成されると、通常は下流のエンドポイントに送信する前にデータをインメモリでバッファする送信キューが含まれます。 エンドポイントが利用可能な場合、データは迅速に通過します。

  • エンドポイントが利用できない場合の処理: ネットワークの問題やバックエンドの再起動などでエンドポイントが利用できなくなった場合、エクスポーターはデータを即座に送信できません。 データを破棄するかわりに、インメモリの送信キューに追加します。

  • リトライ機構: コレクターは、指数バックオフとジッターを備えたリトライ機構を採用しています。 一定時間を待機した後、バッファされたデータの送信を繰り返し試行します。 デフォルトでは、最大5分間リトライします。

  • データ損失のシナリオ:

    • キューがフル: インメモリキューは、構成可能なサイズ(デフォルトでは通常1000バッチ/リクエスト)を持っています。 エンドポイントが利用できなくなり、新しいデータが到着し続けると、キューがいっぱいになる可能性があります。 キューがいっぱいになると、コレクターがメモリ不足に陥るのを防ぐために、受信したデータが破棄されます。
    • リトライタイムアウト: 設定された最大リトライ期間(デフォルト5分)を超過してエンドポイントが利用できない場合、コレクターはキュー内の最も古いデータのリトライを停止し、それを破棄します。
  • 構成: エクスポーター設定内でキューサイズとリトライ動作を構成できます。

    exporters:
      otlp:
        endpoint: otlp.example.com:4317
        sending_queue:
          storage: file_storage
          queue_size: 5_000 # キューサイズを増やす(デフォルト1000)
        retry_on_failure:
          initial_interval: 5s
          max_interval: 30s
          max_elapsed_time: 10m # 最大リトライ時間を増やす(デフォルト300秒)
    

永続ストレージ (先行書き込みログ - WAL)

コレクターインスタンス自体がクラッシュまたは再起動した場合のデータ損失を防ぐために、file_storage拡張を使用して送信キューで永続ストレージを有効にできます。

  • 仕組み: インメモリでバッファするかわりに、送信キューはエクスポートを試みる前にデータをディスク上の先行書き込みログ(WAL: Write-Ahead Log)に書き込みます。

  • コレクターのクラッシュ処理: コレクターがキュー内にデータを保持している間にクラッシュした場合、そのデータはディスクに永続化されます。 コレクターが再起動すると、WALからデータを読み取り、エンドポイントへの送信を再開します。

  • データ損失のシナリオ: ディスクが故障したり、容量不足になった場合、またはコレクターが再起動後もエンドポイントがリトライ制限を超過して利用できない場合は、データ損失が発生する可能性があります。 専用のメッセージキューほど強力ではない可能性があります。

  • 構成:

    1. file_storage拡張を定義します。
    2. エクスポーターのsending_queue設定でストレージIDを参照します。
    extensions:
      file_storage: # 拡張インスタンスを定義
        directory: /var/lib/otelcol/storage # 永続ディレクトリを選択
    
    exporters:
      otlp:
        endpoint: otlp.example.com:4317
        sending_queue:
          storage: file_storage # ストレージ拡張インスタンスを参照
    
    service:
      extensions: [file_storage] # サービスパイプラインで拡張を有効化
      pipelines:
        traces:
          receivers: [otlp]
          exporters: [otlp]
    

メッセージキュー

最高レベルのレジリエンス、特に異なるコレクター層(エージェントからゲートウェイなど)の間や、インフラストラクチャとベンダーのバックエンドの間で、Kafkaのような専用のメッセージキューを導入できます。

  • 仕組み: あるコレクターインスタンス(エージェント)がKafkaエクスポーターを使用してデータをKafkaトピックにエクスポートします。 ほかのコレクターインスタンス(ゲートウェイ)がKafkaレシーバーを使用してそのKafkaトピックからデータを消費します。
  • エンドポイント/コレクターが利用できない場合の処理:
    • コンシューマーコレクター(ゲートウェイ)が利用できない場合、メッセージはKafkaトピックに(Kafkaの保持制限まで)蓄積されます。 プロデューサーコレクター(エージェント)は、Kafkaが稼働している限り影響を受けません。
    • プロデューサーコレクター(エージェント)が利用できない場合、新しいデータはキューに入らなくなりますが、コンシューマーは既存メッセージの処理を続行できます。
    • Kafka自体が利用できない場合、プロデューサーコレクターはKafkaに送信するデータをバッファするために、独自のレジリエンスメカニズム(WALを備えた送信キューなど)が必要です。
  • データ損失のシナリオ: データ損失は主にKafka自体(クラスター障害、トピックの誤設定、データの有効期限切れ)、または十分なローカルバッファリングを持たないプロデューサ ーがKafkaへの送信に失敗した場合に発生します。
  • 構成:
    • エージェントコレクター構成(プロデューサー):

      exporters:
        kafka:
          brokers: ['kafka-broker1:9092', 'kafka-broker2:9092']
          topic: otlp_traces
      
      receivers:
        otlp:
          protocols:
            grpc:
      
      service:
        pipelines:
          traces:
            receivers: [otlp]
            exporters: [kafka]
      
    • ゲートウェイコレクター構成(コンシューマー):

      receivers:
        kafka:
          brokers: ['kafka-broker1:9092', 'kafka-broker2:9092']
          topic: otlp_traces
          initial_offset: earliest # バックログを処理
      
      exporters:
        otlp:
          endpoint: otlp.example.com:4317
          # ゲートウェイ*から*バックエンドへのエクスポートのためにキュー/リトライを検討
      
      service:
        pipelines:
          traces:
            receivers: [kafka]
            exporters: [otlp]
      

データ損失の状況

これらの状況下でデータ損失が発生する可能性があります。

  1. ネットワーク利用不可 + タイムアウト: 下流のエンドポイントが利用できない時間が retry_on_failure 設定で構成した max_elapsed_time を超えた。
  2. ネットワーク利用不可 + キューオーバーフロー: 下流のエンドポイントが利用できず、エンドポイントが回復する前に送信キュー(インメモリまたは永続的)がキャパシティに達した。その場合、新しいデータは破棄されます。
  3. コレクターのクラッシュ(永続性なし): コレクターインスタンスがクラッシュまたは終了し、インメモリの送信キューのみを使用していた。インメモリのデータは失われる。
  4. 永続ストレージの障害: file_storage拡張で使用されているディスクが故障するか、容量不足になる。
  5. メッセージキューの障害: (Kafkaのような)外部のメッセージキューで停止やデータ損失イベントが発生し、プロデューサーコレクターに十分なローカルバッファリングがない。
  6. 設定ミス: エクスポーターまたはレシーバーが誤って構成され、データフローを妨げる。
  7. レジリエンスの無効化: 構成で送信キューやリトライ機構が明示的に無効化されている。

データ損失防止のための推奨事項

データ損失を最小限に抑え、信頼性の高いテレメトリーデータ収集を確保するために、次の推奨事項に従ってください。

  1. 送信キューを常に使用する: ネットワークをまたいでデータを送信するエクスポーターに対してsending_queueを有効にします。
  2. コレクターメトリクスを監視する: otelcol_exporter_queue_sizeotelcol_exporter_queue_capacityotelcol_exporter_send_failed_spans(およびメトリクス/ログの同等のもの)を常に監視して、潜在的な問題を早期に検出します。
  3. キューサイズとリトライを調整する: 予想される負荷、メモリ/ディスクリソース、および許容可能なエンドポイントのダウンタイムに基づいて、queue_sizeおよびretry_on_failureパラメーターを調整します。
  4. 永続ストレージ(WAL)を使用する: コレクターの再起動時にデータ損失が許容できないエージェントやゲートウェイには、送信キューにfile_storage拡張を構成します。
  5. メッセージキューを検討する: ネットワークセグメント全体で最大限の耐久性を確保したり、コレクター層を分離するために、運用上のオーバーヘッドが許容できる場合はKafkaのような管理されたメッセージキューを使用します。
  6. 適切なデプロイメントパターンを使用する:
    • エージェント + ゲートウェイアーキテクチャを採用します。 エージェントはローカルの収集を処理し、ゲートウェイは処理、バッチ処理、および回復力のあるエクスポートを処理します。
    • レジリエンスの取り組み(キュー、WAL、Kafka)をネットワーク中継区間(エージェント -> ゲートウェイおよびゲートウェイ -> バックエンド)に集中させます。
    • アプリケーション(SDK)とローカルエージェント(サイドカー/DaemonSet)間のレジリエンスは、信頼性の高いローカルネットワークのおかげであまり重要でないことがよくあります。 ここにキューを追加すると、エージェントが利用できない場合にアプリケーションに悪影響を与えることがあります。

これらのメカニズムを理解し、適切な構成を使用することで、OpenTelemetryコレクターのデプロイメントのレジリエンスを大幅に向上させ、データ損失を最小限に抑えることができます。