この記事は更新から24ヶ月以上経過しているため、最新の情報を別途確認することを推奨いたします。
Azure Well-Architected Frameworkとはワークロードの品質向上に使用できる原則です。Azure アプリケーション アーキテクチャ ガイドによると次のステップにより理想的なアプリ設計が可能とされています。
①アーキテクチャスタイル:アーキテクチャスタイルを決定する
②テクノロジの選択:アーキテクチャーのテクノロジを選択する
③アーキテクチャの設計
④Well-Architected Framework:評価する
この記事では運用中のワークロードを改善するためにAzure Well-Architected Frameworkを活用する方法の一つを紹介します。次に説明する Azure Well-Architected Framework の5つの柱のうちの1つ、パフォーマンス効率にて提唱されている能力が運用中のワークロードに備わっているかどうかを確認できるチェックリストについて紹介します。
Azure Well-Architected Framework 5つの柱
Azure Well-Architected Frameworkは次の5つの柱で構成されています。本記事ではこの中のパフォーマンス効率を取り上げます。
- コスト最適化:必要な品質、速度、効率性を維持しつつできるだけコストを下げる
- オペレーショナル エクセレンス(OPEX):DevOpsなどの最新の手法を取り入れることでOPEXを作り出す
- パフォーマンス効率:需要に応じて調整することができる
- 信頼性:障害があったとしても回復して機能し続けることができる
- セキュリティ:システムをセキュリティで保護できる
パフォーマンス効率の設計チェックリスト
改めてパフォーマンス効率とは、ユーザーからの要求に合わせて効率的にワークロードをスケーリングできる能力のことです。この能力が既存ワークロードのアーキテクチャーに備わっているかどうかをチェックできるリストがあります。設計リストは 設計、テスト、監視 の3つありますが、今回はこのうち設計チェックリストについて記載しています。
設計チェックリスト :Checklist – Design for performance efficiency
テストチェックリスト:Checklist – Testing for performance efficiency
監視チェックリスト :Monitor the performance of a cloud application
設計チェックリストは3つの観点があり、それぞれ ①アプリ設計、②データ管理、③実装 となっています。表現が少々難しいと感じた箇所があったため、より実践的にかみ砕いて解説してみようと思います。運用中のワークロードがどのような状態であるかの確認に役立てば幸いです。
①アプリ設計
チェックリスト | 解説 |
ワークロード分割ができているか? | モノリシックになっていないか。たとえばWebアプリとバックグラウンドサービスを分けていると、バックグラウンドサービスへの負荷軽減はバックグラウンドサービスをスケールすることで問題を回避できる。 |
スケーリングを考慮した設計になっているか? | クラウドの特性として負荷に応じてサイズを変更できることが挙げられる。これを念頭に置いて設計する必要がある。 |
オートスケールを使っているか? | Web Appであれば自動スケーリング機能が備わっており、負荷に対応してインスタンスの増減ができる。 |
ユニットとしてスケールができるか? | アプリケーションがモノリシックになっている可能性があり、必要なサービスだけをスケールできていないのではないか。 |
可能ならアフィニティを回避することができるか? | 複数インスタンスが存在する場合にはアフィニティを回避することで負荷が分散されるようになる。 |
CPUやI/O集中型のタスクをバックグラウンドタスクとしてオフロードできるか? | 例えばバッチ処理やメール送信といったタスクはアプリケーション内ではなく、別にサーバーを用意して処理させることでアプリケーションの負荷を軽減できる。 |
バックグラウンドタスクが大量の場合には分散しているか? | バックグラウンドタスクとは、数秒のうちに溜まっていくタスクを指す。このタスクが大量にある場合に1件1件処理するのではなく、分散処理することで効率化することができる。 |
データ管理
チェックリスト | 解説 |
データのパーティション分割を使用できるか? | データ量増大に応じたDBの垂直スケーリングでは根本的な対応が難しい。水平方向スケーリング可能なデータストア(※)であるか。 ※エラスティックDBやNoSQLであるテーブルストレージ等 ※アーキテクチャ決定段階のため構成変更は難しい |
コンポーネントとサービスの間の煩雑なやり取りを削減できるか?( 対話型のやりとりを要する設計を避ける) | 複数回の通信ではなく、少数のやり取りでデータ授受を行う。 |
キューを使用し負荷を均等にできているか? | バッチ的な処理ではキューを使用し負荷分散する。この場合、負荷がかかる部分だけスケーリングすることも可能である。 ※例えばWebアプリでの画像データアップロード時のサムネイル作成処理など。 |
データストアへの負荷を最小化できているか? | DBでのXML・JSON等のデータ変換処理を避けアプリケーションロジックで実行する。一概にアプリで実施すべきではなく、DBですべきところとすべきでないところは検討が必要。 |
取得するデータ量を最小化できているか? | 不要なデータ(テーブルの列)を取得しない。 |
データの増大に対処できているか? | データ増大によりコスト増大やアクセス時間増大が見込まれる。そのため、アクセスされなくなっている古いデータを定期的にアーカイブするか、めったにアクセスしないデータをコスト効率の良い長期保存向けのストレージに移動することを検討する(アクセスの待ち時間がより長くなる)。 |
効率の良いバイナリ形式でデータ転送オブジェクト (DTO) を最適化できているか? | データ授受時にRAWデータではなく、gzip等の圧縮形式での転送を検討する。 |
キャッシング制御を設定しているか?(出力キャッシングまたはフラグメント キャッシング) | 出力キャッシングまたはフラグメント キャッシングを使用すると処理負荷が減る。 ※フラグメント キャッシュとは、ページの断片(フラグメント)単位に異なるキャッシュ・ポリシーを設定するための仕組み。これを利用することで、ページ全体に対して一律のキャッシュ・ポリシーを設定する場合に比べ、個々のコンテンツに即したより効果的なキャッシングが可能になる。 |
クライアント側キャッシングを有効にしているか? | プロキシ・ブラウザーでのキャッシュを有効にする。 |
Azure BLOB Storage と Azure CDN を使用してアプリへの負荷を軽減できているか? | 左記のとおり。 |
SQL クエリおよびインデックスを最適化し調整しているか? | 左記のとおり。 |
データの非正規化を検討しているか? | 正規化するとテーブルの結合等が必要になりデータ ストアへの負荷が掛かる。以下を検討する。 ・非正規化により、追加のストレージ ボリュームおよび重複を受け入れられるか。 ・アプリケーション自体を使用してテーブル結合(参照整合性の管理)などのタスクを引き継ぐことができるかどうか。→アプリケーションをスケールする方が容易であるから。 |
③実装
チェックリスト | 解説 |
パフォーマンスのアンチパターンを確認できているか? | パフォーマンスを下げるアンチパターンがあるので、それを避けられているかをチェックする。 |
非同期の呼び出しを使用できているか? | 以下の条件に当てはまるサービスにアクセスすることがある場合、非同期処理になっているか。 ・I/O、ネットワーク帯域幅 により制限される可能性があるサービス ・著しい待ち時間があるサービス |
ストレージへの書き込みなどの際にリソースのロックを避けているか? | ストレージや著しい待ち時間があるサービスへのアクセスをロックすると、パフォーマンスが低下することがある。常にオプティミスティックアプローチ(楽観的排他制御)を使用すること。 |
データの圧縮ができているか? | Webアプリの場合、最大データのほとんどがクライアント要求に対するHTTP応答である。HTTP圧縮により大幅に縮小可能。 |
データベースへの接続およびリソースが使用されている時間を最小限にしているか? | データベースとの接続をなるべく短くすること。 ※接続を開くのはできるだけ遅く、接続プールに返すのはできるだけ早くします。 リソースの取得はできるだけ遅くし、解放はできるだけ早くします。 |
必要なデータベースへの接続の数を最小限にしているか? | 左記のとおり。 |
要求をバッチで送信しているか? | 例えばキューへのアクセスであればメッセージの送信および読み取りをバッチで行う。ストレージまたはキャッシュへのアクセスであれば読み取りや書き込みをバッチで実行する。それによりネットワーク上の呼び出しの数を減る。 |
セッション状態をサーバー側に格納していないか? | 可能であればクライアント側にセッション情報を持たせられると理想。しかしながらアプリがセッション状態を維持する必要がある場合にはサーバー側にキャッシュを格納する必要がある。 |
テーブル ストレージ スキーマを最適化できているか? | テーブルストア(例:Azure Table Storage)を利用している場合は列の名前を短くするとオーバーヘッドを減らせる。 |
リソース作成時に存在の有無をチェックし、存在しない場合にはリソースを作成する、といったロジックを組み込んでいないか? | 例えばストレージへのアクセスの度にこのような処理を行うと著しいオーバーヘッドが生じる。代わりに次の方法を使用する。 ・アプリケーションのデプロイ時、または初回の起動時に必要なリソースを作成 ・見つからないリソースを例外処理コードの一部として作成する |
軽量のフレームワークを利用しているか? | APIおよびフレームワークによっては リソース使用料・実行時間・アプリへの負荷を最小限にすることができる。 たとえば、Web API を使用してサービス要求を処理すると、アプリケーションのフットプリントが小さくなり、実行速度が向上する。 |
サービスアカウントの数を最小限にすることを検討しているか? | 左記のとおり。 |
アプリのパフォーマンスを測定しているか? | 左記のとおり。 |