マイクロサービス化が進む背景について考えてみた
最近マイクロサービスって流行ってますよね。バズってると言ってもいいくらい。
個人的には、「マイクロサービスって結局何なの?」とか、「SOAと何が違うわけ?」とかいう議論は苦手です。
でも「なんでみんなマイクロサービスで作りたいのか?なんでマイクロサービスで作られるサービスが多いのか?」にはすごく興味があるんです。
僕は今、シリコンバレーにある日系SIerの小さな子会社で駐在員をやっていますが、このエリアに居ると、とにかく最近、
「サービス全体が、独立した小さなサービスの集合で構成されるようになってきている」
という流れがあるのは実感できます。もうそれが前提みたいになってるくらい。普通サービスって依存サービスを幾つか呼び出しますよね?ってところから始まるのが普通なくらい。
この記事では、この現象を「マイクロサービス化」と呼んでみたいと思います。
この定義の中の「『独立した』サービス」というのをそれぞれもう少し詳しく意味を決めておきましょう。『独立した』というのは、それが「単一でデプロイ、実行(Execute)可能である」という性質を指すことにしておきます。
さてここからが、この記事の本題です。この「マイクロサービス化」を推し進めるフォースについて考えてみました。3つくらい思いつきました。
1. コンウェイの法則
一つ目はこのコンウェイの法則。シリコンバレーの多くのWebサービスの会社では、プロジェクトや機能ごとにチームが構成される風土があるからです。なので、自然とそうなりやすいんじゃないかということです。
つまり、サービスというかWebサービス自体が収益源になっている会社が多いので、独立した意味のある単位で開発しないとそういう会社にとっては美味しくないからです。SaaSの会社で、何人も束になって、データモデルだけを一生懸命考えるチームよりも、小さくていいから顧客の要求に答えられる「実際に動作する機能」を作るチームのほうが望ましいというわけです。
2. Reactive Manifesto
もう一つは、"Reactive Manifesto"の冒頭に述べられているような、
- クライアント数の爆発
- 低レイテンシ・高スループット要求の激化
- 高可用性要求の高度化
といった背景が大きな後押しをしているのではないかと感じます。
ここからはReactive Manifestoの話の流れそのままなのですが、これらの要求を満たすためには、
- ハードウェアを極限まで使い切りたい
=> I/Oやネットワーク呼び出しでハードウェアを浪費したくない
=> 並行処理度を限りなく高めたい。全部非同期で処理したい。(Event Driven) - サービスが止まるのは困る
=> 故障は封じ込めたい、波及してほしくない。できたら自動で回復してほしい(Resilience)。 - クライアントが多くなっても応答要求を常に満たしたい(Responsive)
=> システムの容量は柔軟にタイムリーに調整出来たい(Scalable, Elastic)
=> リニアなスケーラビリティが欲しい
=> 並行処理度の高いプログラムがいい(アムダールの法則)
が必要になってきます。
この中でも、2つ目の「故障の範囲を限定的にしたい」という要求は特に、マイクロサービス化を進める大きな原因になっているのではないかと思います。
たとえば、Netflixのようなサービスを考えてみると、ユーザから常にアクセスにさらされているUI部分のサービスは絶対にとまっちゃならない。なぜならこのUI部分が収益源だから。Netflixのメインの画面が表示されないなんてことは一分一秒たりとも起こしたくないはずです。
マイクロサービスの議論で、悪の権化のように語られているモノリス。もしNetflixのWebサービスが、モノリスでできていて、ひとつのコンポーネントとしてデプロイされていたらどうでしょう。レコメンデーションエンジン部分にバグがあって、落ちてしまったら??もう目も当てられないですね。
でも、レコメンデーションエンジンの部分が独立して動いていれば、UI部分でレコメンデーションエンジンサービスの故障を検知したら、お薦めリストを表示しないというのもできるし、お薦めのデフォルトを呼び出すような事も可能になる。
こういう依存先サービスの故障を切り離すような機能をサーキットブレカーと呼ぶけれど、現にNetflixはこれをやるためにHystrixを作った(もちろんこれだけじゃない)。それに、サーキットブレーカの機能はReactive Manifestoでも言及されています。
3. ビジネス変化への迅速な追従
Reactive Manifestoは主に、ユーザへの応答要求、システムの高可用性に力点が置かれていました。
コレ以外に、もう一つマイクロサービス化を推し進めていると思うのは、このビジネス変化への素早い追従したい、という要求があげられると思います。ソフトウェア自体が収益源となる会社が増えてきている昨今、これは非常に重要な要求です。
システムの一部を変更が、システム全体の性能に影響を与えては行けないのです。いわゆる「モノリス」と呼ばれて忌み嫌われているものは、これが出来ないものなのではないでしょうか。一部分を変更したいだけなのに、全体の寸断を余儀なくされてしまうのです。
これだけだと、別にWebサーバのクラスタリングでいいじゃないかと思うのですが、Reactive Manifestoのような要求も合わさると、どうしても「小さめ」で「独立した」サービス群によって全体を構成せざるを得ないと思うのです。
まとめ
ということで、「マイクロサービス化」が進む理由を考えてみました。まとめるとこんな感じになるでしょうか。
- コンウェイの法則:
SaaSという性質上、機能的に独立した部分を作ったほうが良い。(DBAはチームごとに居ないと困る) - Reactive Manifesto
最近、アプリへの性能要求が激化しています。Reactive Manifestoで語られている性質を満たすために必要なことの中で、「故障を波及させない」という性質は、「独立した機能」への分割を進めるフォースとなる。 - ビジネス変化への迅速な追従
SaaSにとっては、システム自体が収益源。ビジネスを変化させることは常にシステムの変化が伴う。システムを迅速に、常に安全に変更させるためには、一部分の変更が全体に影響が無いように作る必要があり、これも「独立した機能」への分割を進めるフォースとなる。
番外1: Dockerとマイクロサービス
マイクロサービスと同じくらいバズってるので、Dockerとの関連も考えてみました。Dockerは、マイクロサービスのデプロイメントの一つの方法でしか無いのは多くの場所で議論されている通りです。
個人的には、Dockerは、「マイクロサービス化」を進める要因としては、あまり考えにくいと思います。マイクロサービス化とDockerは直接的には結びつかないと思います。
Dockerの普及を推し進めているのは、なんといってもコンテナイメージのコード化、言い換えればいわゆるインフラのコード化(Dockerfile)、差分イメージ管理(Dockerfileのfromができる)だと感じてます。
Dockerがマイクロサービスと並んで語られるのは、いわゆるImmutable Infrastracture、インフラのコード化というトレンドがマイクロサービス化というトレンドと幸運(!?)にも同時期に合流できたからではないかという印象を持っています(なぜこれらが同時期になったかは、大変興味がありますが、まだわかりません)。
デプロイの単位を作るのにDockerである必要は無いのです。jarでもzipでもdebでもいいはず。それが独立してデプロイ・実行できることに意味があるのです。
もう一つDockerが持っていて大切な機能は、計算リソース(CPUとかメモリとかディスクとかネットワーク帯域とかディスクとか)の分離です。cgroupですね。
せっかく作った「マイクロサービス」ごとに計算リソースを取り合ってほしくないわけです。もちろん「マイクロサービス」ごとにサーバを立てられればそれでいいです。これまではVMを使ってそれをやってきたわけです。
でも、VMはどうしてもOSをブートする時間がかかってしまうし。ただ隔離するだけならVMじゃなくていいでしょうということです。
現にTwitterなんかは、Mesos+Auroraでクラスタ上の負荷をスケジュールしていて、各負荷はThermosというcgroupsベースのコンテナ風のものを使って、計算負荷の割り当てを行っていました。
番外2: 不幸なSOA
結局、SOAは「早すぎた」だけな印象を受けています。当時の応答要求、高可用性要求、故障への回復力への要求、みたいのが、当時のコンピューティングパワーでいくと、一枚岩のアプリで十分賄えたんじゃないか、と感じてます。
それが理由に、SOAで台頭した技術要素はどれも、開発時の管理がし易い、メンテナンスがし易い、ガバナンスがし易いに効果があるようなものばかりです。「仕様」によってサービスの依存関係の分離をを容易にするWebService(WS-*)とか、サービスの依存関係のスパゲッティを局所化するESBのような部品です。サービスを記述しやすくするSCAとかもそうだと思います。
でも、現在の大規模なSaaS屋さんが抱えるリクエストというのは、とにかくどうやってもも一枚岩なアプリじゃ無理ですよね。とにかくたくさんのハードウェアで並行に処理しないと無理なレベルだと思うのです。
一枚岩なアプリで、同期処理がベースじゃ、並べたところでスケーラビリティが弱いし、リクエストのピークに対して無駄にインスタンス数の増減が起きてしまう(非同期&並行処理がベースなアプリに比べて)し、おまけに何処かが故障すると全部がひきずられて落ちるときたら、それは考えなおさざるをえないと思うのです。
独立した機能群で、全体を構成するというSOAが描いた設計思想と、最近のアプリケーションに要求されている高度な処理がうまくマッチして、やっとマイクロサービス化が進んできているんだと思うとき、SOAは不幸にも早すぎたんではないかなと思うのです。
終わり。
TODO
- 参考文献
- 文章中の事実への証拠リンクとか