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-manager、node-manager、schedulerなどの内部通信用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 GitHub Repository
- Trino Helm Charts
- Airlift Project
- Trino HTTP Client Properties Documentation
環境情報
本記事は以下の環境で検証しました。
- Trino: 479
- Helm Chart: 1.41.0