ミドルウェア実行環境の多様化を考慮したインフラアーキテクチャの一検討

このエントリは第2回Web System Architecture研究会の予稿です.

発表資料

speakerdeck.com

はじめに

Webサービスのインフラを設計する上で、RDBやWebサーバを始めとした多くのミドルウェアは欠かせないコンポーネントの一つであり、それらの構築、運用も重要な要素である。 LAMP環境が提唱された1998年頃とは異なり、同じことを実現できるミドルウェアが複数あり、Webサービス開発者はミドルウェアの選択肢の幅が広がった。 また、2005年以降、サーバ仮想化技術の普及を始めに、クラウドベンダーによるミドルウェアのフルマネージドサービスやコンテナ技術の登場により、ミドルウェアの実行環境は多様化してきた。 同一のミドルウェアでも、実行環境が変わることにより、構築、運用手法や利用可能なツールが異なることがあり、それらの違いを表現可能なアーキテクチャの議論は十分にされていない。 本稿では、ソフトウェア設計で提案されているオニオンアーキテクチャ*1やクリーンアーキテクチャ*2の考え方を参考に、Webサービスにおけるインフラアーキテクチャの捉え方を再考、整理を行なっている。 再考したアーキテクチャを洗練することで、多様化したミドルウェア実行環境を、Webアプリケーションの機能要件のみならず、運用も考慮した選択手法を議論する際に利用できると考えている。 しかしながら、アーキテクチャ検討は不十分であり、発表時に提案したアーキテクチャについての議論を行ないたいと考えている。

本稿の位置づけ

筆者はWebサービスにおけるインフラアーキテクチャの体系化し、Webサービス毎に適切なアーキテクチャを自動的に生成する研究を個人的に取り組んでいる。 本稿は、前回の発表*3で整理した課題における「既存のインフラアーキテクチャの調査と分類」の一部である。

既存のインフラアーキテクチャ

Webサービス構築の全体的なインフラ設計をするための、汎用的で明確な命名がされているインフラアーキテクチャはほとんど存在しない。そのうちの有名なアーキテクチャとして1990年代にできた3層アーキテクチャと呼ばれるものがある。 3層アーキテクチャを図1に示す。

f:id:masayoshi:20180505163015j:plain
図1: 3層アーキテクチャ

このアーキテクチャはWebサーバ、アプリケーションサーバ、DBサーバの3つからなるアーキテクチャである。 図1に示すように、それぞれがプレゼンテーション層、アプリケーション層、データ層のレイヤーで表現される。 この3層アーキテクチャを実装するためのOSSの種類としてLAMP構成と呼ばれる造語が1998年に誕生した。LAMPはサーバOSとしてLinux、WebサーバとしてApache、DBサーバのMySQL、そしてWebアプリケーション実装をPerlで行うものである。当時はミドルウェアの種類も多くなかったため、このような造語が誕生したと思われる。 Webサーバ、アプリケーションサーバ、DBサーバはそれぞれワークロードが異なり、冗長化手法なども異なるため、スケーラビリティやキャパシティプランニングが容易になる。 Webアプリケーションはアプリケーションサーバのみにデプロイすればよく、WebサーバやDBサーバへのアプリケーションのデプロイは不要である。 3層アーキテクチャの特に重要な点は、3層というレイヤードアーキテクチャではなく、役割毎に違うサーバを分離しておくということである。 3層というのは、当時のWebサービスがシンプルな動的ページを返すサービスがほとんどであり、クライアントサーバモデルの基本が3層であるという実装上の話に過ぎない。 また、現在のWebサービスCDNやオンメモリKVSのキャッシュサーバなどを利用されるため、3層以上のレイヤーになることや、リクエスト処理のアプリケーションとバッチ処理のアプリケーションを分離するなど、データの流れや依存は複雑化しており、単純な階層化で表現することは困難である。

そこで本稿では、3層アーキテクチャからデータの流れによる階層化を除き、役割毎に別サーバに分離するアーキテクチャをロール分割アーキテクチャと呼ぶことにする。 ロール分割アーキテクチャの図2に、ロール分割アーキテクチャの例を図3を示す。

f:id:masayoshi:20180505163234j:plain
図2: ロール分割アーキテクチャ f:id:masayoshi:20180505163333j:plain
図3: ロール分割アーキテクチャの構成例

図2、3の赤い線はリクエスト処理の依存を表す。 2007年頃からは現在Webサービスではよく利用されるRedis,Cassandra,MongoDBなどのKVSミドルウェアを始め、より高度なWebサービスを作るため、様々なミドルウェアOSSとして実装され、多くのWebサービス事業者が利用出来るようになった。 ロール分割アーキテクチャミドルウェアを多様化にも対応可能であり、複数のミドルウェアを組み合わせや、アプリケーションの処理内容によって、複数のアプリケーションに分離した場合でも表現ができる。 図3の例では、WebサーバのNginx、RDBMySQL、アプリケーションに加え、キャッシュサーバとしてRedisを追加し、バッチ処理用のアプリケーションを別サーバに分離している。 このように、ロール分割アーキテクチャミドルウェア毎にサーバを別にするため、多数のサーバを構築、管理する必要が出てくる。Webサービスの高度化と増加するサーバ、ミドルウェアの運用コストとのバランスが重要になり、効率の良い運用、管理手法の重要度が増した。 多くのサーバの構築に利用されるChefなどのプロビジョニングツールなどが登場したのもこの頃である。 ミドルウェアは多様化しているものの、ミドルウェアの実行環境であるOS部分は統一可能であることが多いため、ミドルウェアの構築やアプリケーションのデプロイなどは例えばSSHを利用して自動構築、デプロイするツールを利用することで自動構築することが可能であった。 また、監視ツールなどもミドルウェア固有のパラメータの取得はミドルウェア毎に対応が必要なものの、CPU利用率やネットワークの死活監視、プロセスの生存確認などはOSの機能やSNMPなどのプロトコルを利用して取得が可能であった。 これらを言い換えると、Webサービスの提供とは直接関係のない構築、管理のためのアプリケーションやミドルウェア(例えばSSHサーバ)がミドルウェア実行環境がOS上であることが前提だったため、Webサービスのインフラ設計と、サーバ(正確に言えばOS)の構築、管理の仕組みはある程度分離して考えることが可能であったということである。

既存のインフラアーキテクチャの問題点

上述した既存のインフラアーキテクチャの問題点は、ミドルウェアの実行環境が多様化した際にWebサービスのリクエスト処理などは考慮できるものの、ミドルウェアの構築や監視など、Webサービスを運用していく上で重要となるインフラ管理、運用を考慮しきれていないことである。 現在、以下の2つの要因でミドルウェア実行環境の多様化が発生している

1つめはコンテナ技術である。コンテナ技術には様々な実装形態があるが、本稿ではDockerを例に説明する。 Dockerでは対象のアプリケーションをコンテナ上で実行できるが、Dockerは基本的に1コンテナに1アプリケーションという設計で作られている。例えばWebサーバであるNginxとSSHサーバであるOpenSSHを同じコンテナ上で動かすことはDockerの設計とは合わない。コンテナ上にNginxを構築するにはDockerが提供しているDockerfileという仕組みを利用して構築する。ChefなどのSSHが前提のプロビジョニングツールを利用した構築には不向きである。 2つめはミドルウェアのマネージドサービスである。本稿ではAWSを例に説明をする。 RDBサーバとしてMySQLを利用する場合、AWSのマネージドサービスとしてRDSとAuroraが存在する。RDSやAuroraを構築する方法は通常のOS上にMySQLを構築する方法とは大きく異なり、AWSが提供しているAPIを利用して構築する必要がある。ツールとしてはAWSが提供するCloudformationといったサービスやAWS APIに対応したTerraformなどのOSSを利用できる。SSHを利用したプロビジョニングツールの利用は基本的にはできない。 これらはミドルウェアの監視にも同じことが言える。OSの機能を使った監視(例えばPSコマンドによる監視)はマネージドサービスには利用できない。コンテナ上でも一部制限があるものが多い。 特にFaaSであるAWS Lambdaなどによるサーバレス環境は特に運用、管理に注意が必要である。マイクロサービスが実行されるサーバレス環境の管理手法とコンテナ、仮想サーバの管理手法などと併せて考える必要がある。本稿ではマイクロサービスへの議論までは行わないが、サーバレスなアプリケーションはミドルウェアのマネージドサービス管理手法の応用で対応が可能であるのではないかと筆者は考えており、今後検討が必要である。

DockerでNginxを動かしても、仮想マシン上でNginxを動かしてもHTTPリクエスト処理は可能であるため、Webアプリケーションの要件は満たせるが、構築、運用の要件によって使い分ける必要がある。 一般的に単体で見ればコンテナ技術やマネージドサービスが効率よく構築、運用が可能であるが、一つのWebサービスでコンテナ技術やマネージドサービスと従来の仮想マシン上で実行するミドルウェアが混在する場合、バランスを取ったほうがよいケースも存在しうる。

ミドルウェア実行環境の多様化により、Webサービスの機能要件だけではなく、運用管理手法も併せて選択する必要があるが、既存のインフラアーキテクチャでは表現が不十分である。 現在はロール分割アーキテクチャから下層のServerを除き、ミドルウェアクラウドサービスの依存や、リクエスト処理フロー、データフローを記載したインフラアーキテクチャ図によって表現されることが多いが、これらだけではアプリケーションの要件を満たすか議論することはできるが運用、管理を同じアーキテクチャで議論できない。別のアーキテクチャで運用、管理を表現し議論すると、アプリケーションの要件やデータフローなどの確認が難しい。 そのため、アーキテクチャを見ただけでその選択により何のトレードオフが発生するかをイメージすることが難しく、識者でなければ把握することが難しい(コンテナを選択するとChefが選択できないなど)。

提案手法

ミドルウェア実行環境の多様化を考慮し、かつ運用、管理手法を表現できるアーキテクチャをオニオンアーキテクチャなどのソフトウェア設計手法を参考に検討する。 ソフトウェア設計手法を参考にする理由を下記に示す。

ソフトウェア設計手法と同じくまずは実装ベースのレイヤードアーキテクチャを考え、そこから見方を変えることで、よりアプリケーションの要件と運用、管理を考慮しやすいアーキテクチャを再考していく。 ソフトウェア開発は、実装を自らが行ないその際のクラスの依存関係がシンプルになるようにするためのアーキテクチャであるのに対し、インフラ設計はミドルウェアなど既に存在する実装から選択し、その選択によるツールの依存関係を知りたい、もしくはシンプルにしたいと言うように実際には異なる点も多々ある。 そのため、そのまま適用できるわけではないので、参考にしつつ取り入れられるところを取り込んでいく形となる。 具体例として以下を環境を想定して話をすすめる。

  • WebアプリケーションがRDBを利用したいので、MySQLを選択する例をとる
  • MySQLを仮想サーバ上に構築する場合、コンテナ上に構築する場合、マネージドサービス上に構築する場合における構築ツールとの関係と監視手法との関係、Webアプリケーションとの関係を考える
  • コンテナを使う場合にはDockerを使うことにする
  • AWSMySQL互換のマネージドサービスとしてRDS、Auroraを検討する
  • 構築ツールとしてサーバにはChef、コンテナにはDockerfile、RDS,AuroraにはCloudformationを使う

実装ベースの単純なレイヤードアーキテクチャ

実装ベースのレイヤードアーキテクチャを図4に示す。

f:id:masayoshi:20180505163732j:plain
図4: 実装ベースのレイヤードアーキテクチャ

このアーキテクチャでは図4のように、上からUI、Middleware、Infrastractureとする。これはソフトウェア設計のレイヤードアーキテクチャと似た命名をしている。 UIはミドルウェアが提供するAPIプロトコルである。ソフトウェア設計と異なる点としてはUIは自分たちで設計し実装するため自由に設計できるが、ミドルウェアの場合は追加が困難なことも多い。 Middleware層はミドルウェアの実装を指す。ここも自分たちで実装することも出来るが、多くの場合は既に存在するミドルウェアを選択すると考えられる。 Infrastractureはミドルウェアの実行環境を指す。OSやコンテナ、マネージドサービスであったりする。

ここで具体例を当てはめたのが図5である。

f:id:masayoshi:20180505163858j:plain
図5: レイヤードアーキテクチャの例

UIにはMySQLプロトコル、MiddleWareにはMySQLかRDSかAuroraが、InfrastractureにはOS、コンテナ、AWS(マネージドサービス)が入る。 Webアプリケーションはどの場合にもMySQLプロトコルを使って通信をする。 構築ツールはChefはOSにSSH経由で、Dockerfileはコンテナへ、CloudformationはAWSAPI経由で実行される。 外部から一番下層のレイヤーに接続しており、レイヤードアーキテクチャとしては少々おかしい。 構築ツールはMySQLを構築するためのものなので、実装ベースのレイヤードアーキテクチャでは再下層に接続するのは自然である。

実装ベースのレイヤードアーキテクチャの問題点を以下に示す。

  • 外部からの接続で最下層レイヤーを参照している
  • UIやMiddleWareはミドルウェア実装を選択した時点で記載内容が決まっている
  • ミドルウェア選択の際に利用できる情報がない

2つめと3つめはインフラ設計においてミドルウェアの選択が重要であるが、その選択の際に必要となる依存関係などがわからない、表現できないため既存のインフラアーキテクチャと大きく変わりはない。

オニオンアーキテクチャを参考にしたインフラアーキテクチャ

オニオンアーキテクチャを図6に示す。

f:id:masayoshi:20180505164806j:plain
図6: オニオンアーキテクチャ

オニオンアーキテクチャは名前の通り、玉ねぎのように同心円状で表されるアーキテクチャである。似たようなアーキテクチャとしてヘキサゴナルアーキテクチャ*4、クリーンアーキテクチャがあげられる。名前の違いなどあるものの、抽象度の高いDomain Modelを中心に置き、Interface、Infrastracture、TestsをDomainから分離している。
この特徴を参考にインフラアーキテクチャへ置き換えたものを図7に示す。

f:id:masayoshi:20180505164931j:plain
図7: オニオンインフラアーキテクチャ

図7に示したアーキテクチャを本稿ではオニオンインフラアーキテクチャと呼ぶことにする。 domainはミドルウェア実装の本来のdomainを示す。例えば今回の例であればRDBMSということになる。 実際の設計者はWebアプリケーションにおいてRDBを利用したいという要望があり、それからミドルウェアの選択に移ることが多いだろう。 その次のMiddlewareでは実際のミドルウェア実装を示す。今回はMySQLなどが該当する。 一番外枠はUI、Infrastracture、ManagedServiceである。UIとInfrastracutureは基本的にレイヤードアーキテクチャと同じものが該当する。 Middleware Serviceは下層のMiddlewareに対して互換をもつ実装やマネージドサービスが該当する。 実際に今回の具体例を上記のアーキテクチャに当てはめた例が図8である。
f:id:masayoshi:20180505165151j:plain
図8: オニオンインフラアーキテクチャの具体例

Webアプリケーションはレイヤードアーキテクチャと同じく、MySQLプロトコルで接続する。 ここでは省略しているがWebアプリケーションはそのままオニオンアーキテクチャを利用し、WebアプリケーションのInfrastractureとRDBのUIが接続している。 簡易的にプロビジョニングツールは、Domainとしてprovisioningとなり、それぞれのツールがInfrastructureにつながり構築を表現する。 実際にはこの他にWebサーバやKVSなど他のDomainのオニオンインフラアーキテクチャも記載し、それぞれをWebアプリケーションからの接続、Provisioningからの接続を書き記すことで、依存関係を把握することが出来る。可能な限り依存関係の接続は少ないほうが、シンプルなより良いアーキテクチャの選択となる。例えばProvisionigのツールとしてCloudformationでWebサーバ、KVS、RDBMSのすべての接続が可能であるならば、図のChefやDockerfileは使う必要はなく、そういった選択を出来るかUIとWebアプリケーションとの接続も併せて同じアーキテクチャ内で検討することが出来る。

レイヤードアーキテクチャに比べて以下の改善点が見られる

  • Domainを導入したことにより、ミドルウェア実装の表現が可能になった。
  • レイヤードアーキテクチャが並べてあるよりも、Interfrastructureの選択とProvisioningツールとの関わりがわかりやすくなった。
  • また、外部との接続は外郭のみとなり、レイヤードアーキテクチャよりは違和感がすくなくなった。

しかし、以下の問題点が存在する。

  • ProvisioningがMiddleware ServiceとInfrastractureにの両方と繋がっている
    • Provisioningの規模を小さく抑えるために考慮する際に、接続箇所が2つあるのは検討がしにくいのではないか
  • Domainの記述ではRDBMSとして同じでも実際の機能が大きく異なる点も多いがそれらを表現しきれていない
    • 依存関係の明確化と機能の明確化は異なるのでそれぞれ違うアプローチを試みるのが良いかもしれない

まとめ

既存のインフラアーキテクチャミドルウェアの観点からみて問題点を考察した。 ミドルウェアの実行環境の多様化による運用管理の考慮事項の増加は、昨今のインフラ設計において無視できないものであり、それらを考慮したインフラアーキテクチャをソフトウェア設計の考え方の一部を適用し、改善できないか再考した。 まだ、整理や考察が足りない箇所があるが、新規性や有用性がより明確に出てくる可能性があると考えている。

議論したいこと

  • アーキテクチャというよりはどちらかというとUMLのようなものに近いかも?
    • 依存の可視化を行ない、選択を容易にするという観点でもUMLのほうが近い気もする。
    • 実際に実装するわけではないのでこの辺はそのままアーキテクチャとして持ってくると違和感があるかも
  • RDB, Webサーバ, KVSという感じにDomainを作っていきそれぞれをつなげてみるともっと見えてくるかもしれない
  • プロビジョニングツールのような運用管理ツールはミドルウェアとは少し違う同心円状かも?
  • プロビジョニングだけではなくモニタリングも入れたい
    • 現状上手い形が見つからずもう少し整理が必要そう
    • なにかいい案が無いだろうか
  • もう少し整理されると面白そうで新規性や有用性も見えてくる気がしている

議論で出た内容

  • OSのレイヤー(ハードウェア、カーネルシステムコール、システムライブラリ)や、リングプロテクションに似ている
    • OSなど権限がはっきりし、レイヤーを明確に分離する場合にはこういった表現が使える
      • レイヤーをオーバして成功した例も存在する(SDNなど)
  • 現在は過渡期なので実行環境が混在しているが、最終的には全部はマネージドサービスになるのではないか
    • 今回はミドルウェアの実行環境を想定したが、下のレイヤーが変化、多様化することはいつでも発生しうるため、それらを考慮したアーキテクチャを考えることは重要
  • UMLというのは時代と逆行してそうで筋が悪そう
  • ミドルウェアというのも既に死語になりつつあるのではないか
  • プロビジョニングツールなどが複雑になってしまうのは、筋の悪い間違った(レイヤーをオーバーしたような)使い方をしているだけなのではないか
    • そういった使い方が、図示したときに可視化されることによって、ユーザーがレイヤーをオーバーした使い方をしていることが分かることは重要

あとがき

今回は既存のWebサービスにおけるインフラアーキテクチャを調査を開始し、それらからミドルウェアの実行環境の多様化に焦点を当てて、ソフトウェア開発手法を参考に適用したものを検討した。 現在は既存のものを調査、整理している段階であることもあり、予稿や資料の作成、発表をするにあたって、まだまだしっかりとした言葉の定義や検討内容が不十分であると感じた。 しかし、多様化と複雑化を解決するためによりソフトウェア的な解決方法(という言い方で良いのかわからないが)をとるようになったインフラの設計手法は、複雑かつ巨大なソフトウェアを開発するために進化したソフトウェア開発手法を参考にできることがあるのではないかという考えは今回の整理でより強くなった。 今後はソフトウェア開発手法の変化と、インフラの多様化を更に調査、整理することで、体系化への一歩を進めたいと思う

*1:Jeffrey Palermo (.com). The Onion Architecture : part 1. Retrieved May 5, 2018 from http://jeffreypalermo.com/blog/the-onion-architecture-part-1/

*2:8th Light. The Clean Architecture. Retrieved May 5, 2018 from https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html

*3:Webサービスにおけるインフラアーキテクチャの体系化とインフラアーキテクチャの選択自動化の研究課題についての整理と考察. Retrieved May 5, 2018 from http://masayoshi.hatenablog.jp/entry/2017/12/27/235456

*4:Alistair.Cockburn.us. Hexagonal architecture. Retrieved May 5, 2018 from http://alistair.cockburn.us/Hexagonal+architecture