MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

Trinoのタイムアウトエラーを解決するAirliftの設定について

TL;DR

Trinoで時々発生するメモリ管理関連のタイムアウトエラーは、ドキュメントに記載されていない memory-manager.http-client.request-timeout パラメータを設定することで解決できることがあります。

# config.properties(Coordinatorのみ)
memory-manager.http-client.request-timeout=60s

ただし、この設定はCoordinatorでのみ有効です。Kubernetes Helm Chartを使用する場合、additionalConfigPropertiesではなくserver.coordinatorExtraConfigを使用する必要があります。


はじめに

プラットフォームエンジニアリングユニットの長田です。今回はマイクロアドで運用しているTrinoクラスタで発生したタイムアウトエラーについて、Trino内部で使用されているAirlift HTTPクライアントの設定規約に沿ったパラメーターを追加することで解決した事例について紹介したいと思います。

対象読者

  • Trinoを運用しているインフラエンジニア
  • KubernetesでTrinoクラスタを構築している方
  • タイムアウトエラーに悩んでいる方

前提知識

  • Trinoの基本的なアーキテクチャ(Coordinator/Worker構成)
  • Kubernetesの基本的な知識(Helm Chartを使用する場合)

発生した問題

大規模なTrinoクラスタで、以下のようなタイムアウトエラーが発生することがあります。

io.airlift.http.client.jetty.JettyHttpClient -
Error fetching memory info from http://worker-xxx:8080/v1/memory
java.util.concurrent.TimeoutException: Total timeout 10000 ms elapsed

このエラーは、CoordinatorがWorkerノードからメモリ情報を取得する際のHTTPリクエストがタイムアウトしていることを示しています。

問題の特徴

  • Workerノードが多い環境で発生しやすい
  • 断続的に発生する(常に失敗するわけではない)
  • 公式ドキュメントを検索しても該当する設定が見つからない

原因の調査

Trinoの内部アーキテクチャ

TrinoはAirliftというフレームワーク上に構築されています。AirliftはHTTPサーバー、依存性注入、設定管理などの基盤を提供しており、Trinoの内部通信もAirliftのHTTPクライアントを使用しています。

ソースコードの調査

Trinoのソースコードを調査したところ、ClusterMemoryManagerがWorkerノードにHTTPリクエストを送信してメモリ情報を収集していることがわかりました。

ClusterMemoryManager.java(139行目):

checkState(serverConfig.isCoordinator(), "ClusterMemoryManager must not be bound on worker");

このコードから、ClusterMemoryManagerはCoordinatorでのみ実行されることがわかります。

デフォルトのタイムアウト値

CoordinatorModule.javaを確認すると、memory-manager用HTTPクライアントの設定が見つかりました。

CoordinatorModule.java(230-234行目):

install(internalHttpClientModule("memory-manager", ForMemoryManager.class)
        .withConfigDefaults(config -> {
            config.setIdleTimeout(new Duration(30, SECONDS));
            config.setRequestTimeout(new Duration(10, SECONDS));  // ← デフォルト10秒
        }).build());

デフォルトのRequestTimeoutは10秒でした。大規模なクラスタでは、この値では不十分な場合があります。

Trinoの公式ドキュメント「HTTP client properties」を確認すると、以下のプレフィックスのみが記載されています。

  • oauth2-jwk - OAuth 2.0認証用
  • jwk - JWT認証用
  • exchange - ノード間データ転送用

memory-managernode-managerschedulerなどの内部通信用HTTPクライアントのプレフィックスはドキュメントに記載されていません。しかし、ソースコードを見ると、これらも同じAirliftのHTTPクライアント設定規約に従っており、設定可能です。


解決方法

設定プロパティの形式

Airlift HTTPクライアントの設定は、以下の形式で指定します。

{クライアント名}.http-client.{プロパティ名}

Coordinatorのconfig.propertiesに追加

# Memory Manager HTTP Client
# デフォルト10秒から60秒に延長
memory-manager.http-client.request-timeout=60s

利用可能なプロパティ

プロパティ 説明 デフォルト
request-timeout リクエスト全体のタイムアウト 10秒
connect-timeout 接続確立のタイムアウト 5秒
idle-timeout アイドル接続のタイムアウト 30秒
max-connections-per-server サーバーあたりの最大接続数 25

Kubernetes Helm Chartでの設定

公式のTrino Helm Chartを使用している場合、設定を追加する一般的な方法はadditionalConfigPropertiesを使用することです。

# values.yaml
additionalConfigProperties:
  - memory-manager.http-client.request-timeout=60s

しかし、これは問題を引き起こします。 Helm Chartのテンプレートを確認すると、additionalConfigPropertiesはCoordinatorとWorkerの両方に適用されることがわかります。

configmap-coordinator.yaml(64-66行目):

{{- range $configValue := .Values.additionalConfigProperties }}
{{ $configValue }}
{{- end }}

configmap-worker.yaml(61-63行目):

{{- range $configValue := .Values.additionalConfigProperties }}
{{ $configValue }}
{{- end }}

memory-manager HTTPクライアントはCoordinatorでのみバインドされるため、Workerに設定すると起動時にエラーが発生します。

Error: Unknown configuration property 'memory-manager.http-client.request-timeout'

解決策: server.coordinatorExtraConfigを使用

Helm Chartにはserver.coordinatorExtraConfigという設定項目があります。これはCoordinatorのみに適用されます。

configmap-coordinator.yaml(79-81行目):

{{- if .Values.server.coordinatorExtraConfig }}
{{- .Values.server.coordinatorExtraConfig | nindent 4 }}
{{- end }}

正しい設定方法

# values.yaml
server:
  coordinatorExtraConfig: |
    memory-manager.http-client.request-timeout=60s
    node-manager.http-client.request-timeout=60s

その他の有用なAirlift HTTPクライアント設定

ソースコードを調査した結果、以下のHTTPクライアントが存在することがわかりました。

Coordinator専用クライアント

クライアント名 デフォルトRequestTimeout 用途
memory-manager 10秒 Workerのメモリ情報取得
node-manager 10秒 ノード情報の管理
scheduler 20秒 タスクスケジューリング
worker-info 5分 Worker情報取得
catalog-prune 10秒 カタログプルーニング

推奨設定

大規模クラスタや長時間クエリが多い環境では、以下の設定を検討してください。

# values.yaml
server:
  coordinatorExtraConfig: |
    # Memory Manager - Workerからのメモリ情報取得
    memory-manager.http-client.request-timeout=60s

    # Node Manager - ノード情報の管理
    node-manager.http-client.request-timeout=60s

    # Scheduler - 長時間クエリ対応
    scheduler.http-client.request-timeout=120s

全ノード共通クライアント

以下は全ノードで使用されるため、additionalConfigPropertiesで設定可能です。

クライアント名 デフォルトRequestTimeout 用途
exchange 10秒 ノード間データ転送
additionalConfigProperties:
  - exchange.http-client.request-timeout=60s

設定の検証

1. Coordinatorの設定確認

Coordinatorのログで設定が読み込まれていることを確認します。

kubectl logs trino-coordinator-xxx | grep "memory-manager"

2. タイムアウトエラーの解消確認

以前タイムアウトが発生していたクエリを実行し、エラーが解消されていることを確認します。

3. JMXでのメトリクス確認

HTTPクライアントのメトリクスはJMX経由で確認できます。


バージョンに関する注意

Trino 472での変更

Trino 472(2025年3月リリース)で、HTTPクライアントのプレフィックス名が変更されました。

旧プレフィックス 新プレフィックス
memoryManager memory-manager
workerInfo worker-info

古いバージョンを使用している場合は、旧形式のプレフィックスを使用する必要があります。


まとめ

Airliftフレームワークの設定規約を理解することで、Trinoの設定にも応用ができるという事例でした。 マイクロアドではTrinoを活用したデータ基盤を運用しており、これからも知見を発信していければと思います。


参考情報


環境情報

本記事は以下の環境で検証しました。

  • Trino: 479
  • Helm Chart: 1.41.0