BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース レジリエントなアーキテクチャを実現する方法

レジリエントなアーキテクチャを実現する方法

原文(投稿日:2018/09/13)へのリンク

スケールするシステムを管理するには限界ぎりぎりまでシステムを追い込んでも、回復できるようにする必要がある。そして、障害を受け止めることも必要だ。Adrian Hornsby氏はふたつのブログ記事で、自身の10年以上にわたる大規模システム運用の経験と発見したパターンを共有している。

AWSのテクニカルエバンジェリストである氏は、10インスタンスくらいまでの小さなシステムでは、障害なしで運用されているのが普通の状態で障害は珍しいが、その状態を大規模システムで達成するのはほとんど不可能に近い、という。部分的な障害が起きているのが普通の状態であり、収益に影響するかもしれないが、ほとんどのウェブアプリケーションにとってはこの状態は大きな問題ではない。この状態を活用するために、氏が推奨するのはレジリエントにするためのコストと失う可能性のある収益のバランスを取ることだ。

氏はレジリエントなアーキテクチャを構築するために役立つパターンをいくつか紹介している。しかし、氏はレジリエンスが必要なのはソフトウェアだけではないことを強調する。インフラレイヤ、ネットワークとアプリケーション設計も重要であり、人や文化も同様に重要だ。

冗長性
クラウドへアプリケーションを配置する場合、氏がもっとも重要だと考えているのが冗長性だ。可能であれば、異なるゾーン、リージョンに複数のインスタンスを配置することで可用性が向上する

オートスケーリング
次はアプリケーションのキャパシティを必要に応じて自動で調整する仕組みだ。このような仕組みは今では一般的なものになっている。オートスケーリングは技術によってスピードが異なる。それゆえ、アプリケーションのニーズに合致したものを採用するのが重要だ。氏によれば、コンテナプラットフォームによってスケーリングの速度は以前よりもかなり高速になっている。

Infrastructure as code
Infrastructure as codeを使って得られる重要なメリットが再現可能性だ。氏はデータセンターで複数の環境を手動で構成することとテンプレートを使って何度もそのテンプレートを自動で実行することを比較している。

もし、何らかの原因で環境がおかしくなったり、削除されてしまった場合でも、バックアップからデータをリストアしてテンプレートを使ってリビルドできる。すべてを手動でやるよりもリスクが少なく高速だ。

また、氏はInfrastructure as codeを知識の共有と考えている。このコードはチームが手を入れている他のコードと同じように扱われる。変更はすべてプルリクエストで検証されるだろう。

不変のインフラ
すべての配置で、すべてのコンポートが置き換わり、更新は行われない、というのが不変のインフラだ。不変サーバーパターンをベースに氏は次のふたつのルールを示している。

  • 動いているシステムに対してアップデートをしない。
  • 常に、プロビジョンされたリソースの新しいインスタンスからスタートする。

不変インフラの場合、氏はカナリアデプロイを使って新しいアプリケーションのデプロイの失敗のリスクを低くすることを推奨している。この手法を使うことで本当の本番環境で試験でき、必要があれば素早くロールバックできる。

ステートレスなアプリケーション
オートスケーリングと不変インフラを活用するには、アプリケーションはステートレスでなければならない。つまり、すべてのリクエストは前のリクエストやセッションから独立して扱われなければならず、ローカルディスクやメモリに情報を保持してはいけない。Memcachedのようなキャッシュシステムを用いてのみ、オートスケーリンググループ内で状態を共有する。

障害の拡大を避ける
氏の経験では、局所的な障害が異なる種類の依存を通じてシステム全体を落としてしまう、というのが一般的な障害の原因だ。ひとつの典型的な例が過負荷。例えば、ひとつのクラスタがダウンした後、すべてのトラフィックがもうひとつのクラスタに寄る。このような障害を避けるため、氏が推奨するのが次のようなパターンだ。

  • タイムアウト。スローダウンしているデータベースに同じ量のトラフィックが流れ続けると障害に発展する。タイムアウトを短くしておくことで障害を防ぐことができる。
  • 冪等なオペレーション。エラーの場合、クライアントは同じリクエストを複数回送ってくる。これが原因で障害になる場合もある。これを避けるためには冪等なリクエストを用いる。
  • サービスのデグレーション。高負荷に対処するひとつの選択肢として、デグレードさせたサービスを提供する、という方法もある。例えば、パーソナライズされたリストではなく汎用のリストを返す、といったような方法だ。
  • 拒否。最終手段として、リクエストをドロップする。重要でないリクエストからドロップするのが望ましい。

まとめとして氏は、クラウドで大規模な分散システムを運用する場合、エラーが断続的に起きるのは普通の状態であり、そのようなエラーに対してどのように反応すればよいかを知るのは難しい、と書いている。氏が推奨するのは、統計を集め、どのような場合にエラーに対処するかわかるような閾値を決める、という方法だ。また、自動化の重要性についても強調している。弾力的で信頼性が高いアプリケーションをしっかりとテストされたかたちでデプロイするには、可能な限り自動化する必要がある。

 
 

Rate this Article

Adoption Stage
Style
 
 

この記事に星をつける

おすすめ度
スタイル

BT