Javaアプリケーションによってクエリされている12個のワーカーで構成されたprestoクラスターがあります。クラスターは30個の同時要求を実行できます(それ以上ある場合はキューに入れられます)。
アプリケーションは約80〜100の異なるクエリを送信する可能性があり、これはクラスターによって処理されると予想されます。
問題:クエリが順次実行されると、並列で実行される場合よりも大幅に速く完了します。
たとえば、100個のクエリを順番に実行すると、それぞれが完了するまでに1〜12秒かかり、すべてが約2分で完了します。しかし、それらすべてを並行して開始した場合、それらすべてを完了するのに約8〜12分かかります。コーナーケースでは、最大30分かかります。
Prestoコンソールを見ると、ほとんどのクエリがブロックされており、実際には1〜3個だけが実行状態になっていることがわかります。
残念ながら、どのクエリも投稿できません。それらは通常、異なるスキーマ(1つのクエリで最大6つ)にアクセスし、結合とネストされたクエリでいっぱいです。同時に、それらのほとんどは次のように書かれています 現在のベストプラクティス 。
質問:どうすればパフォーマンスを向上させることができますか?少なくとも、根本原因を見つけるためにどの領域を調査する必要がありますか?
最も遅いクエリの1つに対するいくつかのメトリックがあります(数字があなたに何かを言うかもしれません)。
Resource Utilization Summary
CPU Time 8.42m
Scheduled Time 26.04m
Blocked Time 4.77d
Input Rows 298M
Input Data 9.94GB
Raw Input Rows 323M
Raw Input Data 4.34GB
Peak Memory 10.18GB
Memory Pool reserved
Cumulative Memory 181G seconds
Timeline
Parallelism 477
Scheduled Time/s 1.47K
Input Rows/s 281K
Input Bytes/s 9.60MB
Memory Utilization 0B
自分で問題を理解しました。
Prestoは分散SQLクエリエンジンです。そしてここでのキーワードはdistributedです。クエリを実行すると、クエリがワーカー間で効率的に分散され、高速で実行されることが保証されます。
並列クエリを実行し、Prestoがそれらを効率的に並列化する方法を理解することを期待するのは誤用です。これは、残念ながらPrestoでは機能しないリレーショナルデータベースアプローチに似ています。