はじめに
前回、Amazon Redshiftがたまに遅くなる事象について記事にしました。
対策については触れていなかったので今回は検討した案をいくつか書き記したいと思います。
問題点
Redshiftのバージョンアップによってクエリコンパイルが発生し、バージョンアップ後の初回は全体的にクエリに時間がかかる。
Redshiftのバージョンアップは一時的に遅らせることはできても完全にやらないということはできない。
Redshiftのバージョンアップはメンテナンスウィンドウ以外でも、停止→起動のタイミングでも適用されることがある。(緊急の場合やバージョンアップを遅延させていた場合など)
コンパイルの発生を利用側でコントロールする術はない。
どうする?
3案対策を考えました。
案1:ElasticResizeを使って処理性能を倍増
狙い
ノード数を普段から比べ倍増させることで実処理時間の短縮を狙い、コンパイル時間に要した時間をカバーする。
懸念事項
ノード分散で早くできる箇所は限られる。元々適正なノード数の場合、さらに細かくしても分散のオーバヘッドがかかるだけで効果は限定的になる可能性がある。
ElasticResizeは高速といっても通常のリサイズに比べて早いだけであり、実行完了時間の保証もない。
スライス数に応じた範囲のみElasticResize可能となるため、すでにElasticResizeで拡張済みの状態で運用している場合はまず通常のリサイズを行う必要がある。
案2:バッチ処理の時間帯外で起動&バージョンチェックを行い、事前に予行演習
狙い
実処理で影響が出ないように先回りしてバージョンアップとコンパイルが行われるようにする。
以下、AWS公式で推奨されている対策 https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-query-performance.html
懸念事項
コンパイルを走らせるには該当クエリを実際に実行する必要があるため、本処理と同等の処理がすべて流せるようなデータの準備が必要となる。
自動でバージョンアップチェックと予行演習処理を実行できるようにする必要があり、予行演習後は本処理に影響が出ないようリセットしておくなど考慮すべき内容が多く、開発工数が他の2案に比べると高い。
予行演習後、本処理までの間、ランニング費用を抑えるためにRedshiftを停止させた場合、本処理時の起動で万一バージョンが変わってしまうリスクへの対策はできない。
案3:RedshiftServerlessに移行
狙い
RedshiftServerlessに乗り換えることで起動停止運用をなくし、メンテナンスウィンドウの概念もなくなることで本事象の回避を期待。
懸念事項
本事象が回避できるのかどうかはやってみないとわからない。
メンテナンスウィンドウの概念がなくなるため、同じように起きる場合、予見するのが難しくなる可能性がある。
どれを採用したか?
弊社システムの場合、以下の背景があったため、案3で対応しました。
規模拡張時にElasticResizeを使用して拡張しており、案1を適用するには時間のかかる通常のResizeを行う必要があった。
運用変更が伴う案2はリスクが高い。
インスタンスタイプとしてdc2.largeを採用しているが、旧世代になりつつあったため、 移行先としてちょうどRedshiftServerlessが候補のひとつとして挙がっていた。
効果はあったの?
結論からいうと、AWS内部の状況は開示されていないため、あくまで実測に基づく感覚になりますが、一定の効果は見られました。
バージョンアップ自体は
SELECT VERSION();
などで毎日バージョン状況をみることで変わったのかどうかの確認はできます。ただしタイミングを予見することはできません。
そしてバージョンが変わったときにはやはりいくらか全体の実行時間は遅くなる傾向はみられました。
しかし、遅くなる度合いは許容できる範囲に収まっている状況でした。
※弊社の例ですと、これまで80分以上の遅延に対し、多くても20〜30分程度に留まるようになりました。
最後に
弊社システムでは案3を適用しましたが、案1、案2も試す価値はあるかと思いますので状況によって選択していただくとよいと思います。
完全に解消という結論ではなくなんだかすっきりしないですが、同じ悩みを抱えている方の参考になれば幸いです。
AWS側で根本的にこの辺りの対策を施してくれることを期待したいものですね。
Comentários