【レポート】可用性のモデル #reinvent #arc321

はじめに

本記事はAWS re:Invent 2017のセッション「ARC321 - Models of Availability」のレポートです。

本セッションはすでに動画、スライドが公開されています。

動画

スライド

概要

When engineering teams take on a new project, they often optimize for performance, availability, or fault tolerance. More experienced teams can optimize for these variables simultaneously. Netflix adds an additional variable: feature velocity. Most companies try to optimize for feature velocity through process improvements and engineering hierarchy, but Netflix optimizes for feature velocity through explicit architectural decisions. Mental models of approaching availability help us understand the tension between these engineering variables. For example, understanding the distinction between accidental complexity and essential complexity can help you decide whether to invest engineering effort into simplifying your stack or expanding the surface area of functional output. The Chaos team and the Traffic team interact with other teams at Netflix under an assumption of Essential Complexity. Incident remediation, approaches to automation, and diversity of engineering can all be understood through the perspective of these mental models. With insight and diligence, these models can be applied to improve availability over time and drift into success.

大雑把には以下のような発表でした。

  • Netflixのシステムやチームなどのバックグラウンドの紹介
  • 複雑なマイクロサービスアーキテクチャの可用性を担保するためにやっていることの紹介

登壇者

  • Casey Rosenthal - Traffic, Chaos, Intuition Engineering Manager, Netflix

レポート

Netflixのチーム構造について

アーキテクチャ

7つのマイクロサービスがあり、それぞれが連携している。 DはCとFと接続し、CとFは全ての処理をせず、CはAに処理を依頼し、FはBとGに接続する。 AはBとEとGに接続し...このように、理解の難しい複雑な連携をしている。

これは複雑で理解しがたい。しかもここには少し嘘があって、本当はもっとたくさんのマイクロサービスがある。

図の円がマイクロサービスを表していて、円をつなぐ線はプロセス間の通信である。

なぜこんな複雑なアーキテクチャを作ったのか?

コンサルタントとしての仕事を通してたくさんのアーキテクチャを見てきたが、多くの組織が、この3つの要素を最適化する傾向にあった。

  • パフォーマンス
  • フォールトトレランス
  • 可用性

FinTechであればフォールトトレランスを、ゲームであれば可用性を重要視する。 チームは1つの要素を、優れたチームであれば2つ、3つの要素を最適化していくが、バランスが大切である。

4番目の要素

Netflixには4番目の要素「開発速度」があった。 これは、開発速度のためのエンジニアリング上の決定についてであり、アジャイルやスクラムなどのプロセスによって開発速度を最適化することについての話ではない。

例えば、

  • クラウドへの移行によってインフラよりもサービスそのものに集中できるようになった
  • マイクロサービスアーキテクチャによって、必要に合わせてマイクロサービスごとのアップデート、デプロイが行える
    • マイクロサービスアーキテクチャを選択したのは開発速度の最適化のためである

チームの構造

Netflixのエンジニアチームは5,6人からなっており、それぞれをまとめるチーフアーキテクトのようなロールはない。 各マイクロサービスは チームに帰属 している。 チームはサービスの機能だけの責任を追うのではなく、デプロイのライフサイクルのような運用機能についても責務を持っている。

複雑なシステム

複雑なシステムとは理不尽なシステムであり、理不尽とは 推測し難い システムのことである。

複雑なシステムを理解しようとしている人には、理解することよりも複雑でなくする方法を探すことを勧めている。 しかしそれは簡単ではない。

ビール・ゲームによって複雑さの実感を得る

ビールゲームのルールを簡単に説明すると、

  • 顧客 ・・・ビールが好き
  • 小売 ・・・ビールを売る
  • メーカー・・・ビールを作る

という独立した 発注書でのみコミュニケーション可能な 組織が、効率良く受発注を行うことを目的とするゲームである。

このゲームは、ブルウィップ効果(突然のインプットの変化に対して、アウトプットがリカバーできないほど大きな影響を受けること)という現象により大抵の場合うまくいかない。 ここで大切なのはどこかのチームが間違っていたわけでもなければ、不合理な誤った決断をしたわけでもないということだ。

マイクロサービスの場合

マイクロサービスに適用して考えてみよう。

この間Netflixでホラー映画を見ていた時、あるシーンで驚いてコーヒーをこぼした。一度停止した映像が再開しないので、なんども更新ボタンを押した。 あるタイミングで大量のリクエストがNetflixに送信された。

ここにマイクロサービスが二つある。顧客の属性サービスと、顧客サービスである。

  • 顧客サービス
    • 各ノードに分散して情報を持っている
    • IDをハッシュキーに分散している
  • 属性サービス
    • 顧客に合わせたコンテンツを配信するための情報を持っている
    • 顧客サービスに接続できないとデフォルトのコンテンツを提供する

属性サービスが顧客サービスに接続できないと、属性サービスはデフォルトの振る舞いを提供する。 サービスはリソースの使用状況によってスケールする。

顧客サービスに同一顧客から大量のリクエストが飛ぶと、1つのノードにアクセスが集中する。 フォールバックモードになり、メモリから結果をサーブするようになる。このモードはCPUやディスクをあまり使わない。 そのためノードは他のノードにデータを渡してスケールインする。

属性サービスは顧客サービスからレスポンスが返ってこないと、デフォルトの挙動を顧客に提供する。 顧客にはいつもと違ったコンテンツが表示される。 いつものコンテンツを表示するため、各顧客が更新ボタンを連打する。 顧客サービスの全てのノードがフォールバックモードになる。 クラスターがさらに縮退する。

この結果、顧客サービスの振る舞いを原因として属性サービスが動かなくなる。

どうしてこうなった

当然顧客は責められない。誰が失敗したのか?誰も失敗していない。 システムは考えられて構築されていた。エンジニアは全知全能ではない し、あらゆる影響を想像することはできない。 何が問題なのか?おそらくそれは複雑さである。

Economic complexity

複雑さを増したり、プロダクトの配信を失敗させる4つの要素がある。

  • 状態
  • 関係
  • 環境
  • 不可逆性

ソフトウェアに置いて、状態は管理できなくなる傾向にある。ロードマップや顧客のリクエストによって駆動するからだ。 複雑なシステムに置ける関係は、マイクロサービスの例のように部分ごとに独立して成長できる。 環境に対して我々ができることは少ない。 不可逆性に取り組むことにした。

クラウドへの移行、継続的デリバリ、アジャイル、コンテナ、サーバーレスは一度決定したことを覆すことを可能にし、そのことは複雑さのコントロールに繋がる。 これらは複雑さとの対決に役立つが、複雑さは本質的なものと本質的でないものに分けられる。

本質的でない複雑さは家の汚れのようなもので、目的があって作られるものではない。 ソフトウェアにおける本質的でない複雑さを取り除く方法はよくわかっていない。

本質的な複雑さにフォーカスした。

複雑さを取り除こう

あるときシンプルなアプリケーションがあって、そこにオプションを追加することを検討していた。 私が理由を聞くと、可用性を上げるためであった。 ここでオプションによる解決を強く拒否した。

シンプルであることと可用性についての最も良いシナリオは、それぞれが独立していることだと思う。 最も悪いシナリオは、それらをいっぺんにまとめて対応しようとすることだ。

可用性を上げる方法はたくさんある。コンシステンスハッシュ、レプリカ、他にもたくさんあるが、それらは同時にシステムの複雑さを増す。

複雑さをコントロールする

そして、複雑さを排除したり減らすよりもそれをコントロールすることを提案する。

ソフトウェア産業で働く限りは、おそらく複雑なシステムと働くことになる。 つまり、どのような挙動をするかわからないシステムと働くことになる。

Chaos Engineeringはこれを適切にナビゲートする。 NetflixはChaos Engineeringの有名な2つのプロジェクトを作った。 Chaos MonkeyとChaos Kongだ。

我々がデータセンターからクラウドに移行したとき、単一障害点のダウンによる障害があった。 クラウドではシステムは水平にスケールし、大量のサーバーを実行させていた。 その中のいくつかのインスタンスは時折落ちた。

もし重要なシステムなら、これによってサービスは停止するだろう。

チームにはチーフアーキテクトがいないという話をした。CTOもだ。 よって、決まりごとを守らせるためのメカニズムは存在しない。 ベストプラクティスはたくさんある。少なくとも3つのAZにデプロイするとか・・・。 しかし、我々はそれを強制する事は出来ない。そのようなメカニズムはNetflixには存在しない。

Chaos Monkey

我々はインスタンスの消滅の問題を解決するために、 Chaos Monkeyでマイクロサービスのあるノードをランダムに選び、落とすようにした。 もし弾性のあるシステムを設計できなければ、これを解決する事は出来ないだろう。

エンジニアはこれを理解し、解決に勤めようとした。 長い間我々のシステムは単一障害点によるサービス障害を起こしていない。 小さなスケールにおいてこれはとても有効だった。

Chaos Kong

大きいスケールについてもみてみよう。Chaos Kongだ。 発想は同じだ。我々はリージョンレベルの障害においても耐えられるシステムを求める。 Chaos Kongは定期的にリージョンを停止させる。 これによって、新しい機能に対してもリージョンの停止をシミュレートすることができる。

全てを予測することはできない

何があったのか知ることができるのはことが起こった後であり、それを常に検知する事は出来ない。 さらに、システムはどんどん危険な状態になっていく。 複雑なシステムに対して、サービスが落ちる前に危険を察知できる事は稀である。 外的要因が何かを起こすことを予測する事は出来ない。

Chaos Monkey/Chaos Kongはそれを可能にした。 それらは、システムが安全であるという知見を与える。

障害のある環境の中にいることで、さらに可用性のある状況を保つことができる。

PRINCIPLES OF CHAOS ENGINEERING

本番環境におけるこのようなやり方は、純粋な利益にはならない。 おそらく敵も多く作っているだろうから、これを正式化し原則をドキュメント(PRINCIPLES OF CHAOS ENGINEERING)化した。

これは、システムの弱点に対する実験を容易化をいつ、どのように行い、どのように改善されるかの大雑把な定義である。

テストと実験の違い

いわゆるテストと、実験は異なるものである

単体テストは、インプットに対して機能の出力を確認するもの さらに賢いテストは、組み合わせをテストする

  • テスト・・・既知の結合価の定義と特性の確認(すでにわかっていることの確認)
  • 実験・・・直感を破棄することによる新しい知見の創造

Chaos Engineeringのためのベストプラクティス

  • 定常状態での振る舞いについての仮説を立てる
  • 本番環境での実験
  • 継続的な実行のための実験の自動化

カオスエンジニアリングは本当のカオスを引き起こしたいわけではない。 顧客に悪い影響を与えるような実験はすべきではない。まず既知の問題が解決されてから実験を行うべきである。

ChAP

マイクロサービスのレベルでカオスエンジニアリングを実践するために作られた。

  • デプロイ済みの本番環境とは別に、特定のマイクロサービスの比較用、実験用のクローンを2つ作成する。
  • ごく一部のトラフィックがこのそれぞれのクローンを経由するようになる
  • これらのクローンに対するモニタリングによって、マイクロサービスに対する「実験」を可能にする
  • CI/CDと統合し継続的かつ頻繁に実験を行う

ChAP: Chaos Automation Platform

Vizceral

リージョン間およびインターネットとの通信を可視化するツールである。

  • どこからどこに?
  • どのくらいのスピードで?
  • どんなリクエストが?

のような、通信の状況を可視化できる。

Netflix/vizceral: WebGL visualization for displaying animated traffic graphs

まとめ

  • システムの複雑さはできる限り取り除くべきである
  • しかし全ての複雑さを取り除くことはできない
  • 予期しない状況が発生することを前提とすべきである
  • Chaos Monkey
    • AWSのインスタンスを意図的に落とすことで、インスタンスのダウンに抵抗力のあるシステムを作る(ことを前提にできる)
  • Chaos Kong
    • AWSのリージョンを意図的に落とすことで、リージョンのダウンに抵抗力のあるシステムを作る(ことを前提にできる)
  • ChAP
    • 変更に対するモニタリング用の仕組み。マイクロサービスに対する本番環境を利用した実験を可能にする
  • Vizceral
    • プロセス間の通信を可視化する