pyてよn日記

一寸先は闇が人生

サーバーレスアーキテクチャの基本

 巷でよく聞く「サーバーレスアーキテクチャ」に関して,いろんな記事をつまみ食いしてまとめた.

  • かなり参考にさせていただいた記事

codezine.jp

qiita.com

d.nekoruri.jp

employment.en-japan.com

注意

 本記事はネット情報を寄せ集め,自分なりに解釈をした記事になっているため,情報が正確ではない可能性があります.間違っている箇所等々ありましたら Twitter やコメントで気軽にご指摘ください.

サーバーレスアーキテクチャの概念

 「サーバーレスアーキテクチャ」は以下のような設計思想.

  • サーバ固有のリソースに依存しない
  • イベントドリブンでリソースが動的に割り当てられる
  • リクエストに応じて必要なだけの計算リソースをリアルタイムで確保するアーキテクチャ(上の言い換え).
  • サーバを常時起動しない(AWS EC2 などの IaaS では常にサーバを起動している).
  • サーバを自前で用意しない.

サーバーレスアーキテクチャの実現

 サーバーレスアーキテクチャを実現するには,イベント駆動型コード実行サービスを利用する.イベント発生時に粒度の細かい関数(Function)を実行する,ということで,IaaS,PaaS 等と対比して「Function as a Service(FaaS)」と呼ばれる.以下のようなベンダーからサーバーレスアーキテクチャを実現するためのマネージドサービスが提供されている.

サーバーレスアーキテクチャの利点

aws.amazon.com

 AWS 公式の解説を参考.サーバーレスアーキテクチャには,主に以下のような利点がある.

  • サーバーの管理が不要
    サーバーのプロビジョニング(前もって必要なリソースを割り当てること)やメンテナンスが必要ない.ユーザ側がソフトウェア,ランタイムのインストール,メンテナンスを行う必要がない.

  • 柔軟性のあるスケーリング
    アプリケーションは自動的にスケーリングされる.個々のサーバー単位ではなく消費単位 (スループットやメモリなど) で動的にリソースが割り当てられてスケーリングする.

  • 価値に対する支払い
    サーバー単位ではなく,安定したスループットや実行時間に対して支払う.

  • 自動化された高可用性
    サーバーレスには,可用性と耐障害性機能が組み込まれている.これらの機能がデフォルトで提供されるため,ユーザがこれらを設計する必要はない.

  • ステートレス設計による柔軟なアプリケーションの構築
    関数の粒度,ステートレスな設計(せざるを得ない)により,機能間の依存関係は小さくなる(システムが疎結合).うまく設計できれば非常に柔軟な構造のアプリケーションを構築できる.

 大雑把に言うと,

  • ユーザがインフラ(設備自体やそれらの運用,障害など)のこと考えずにアプリケーションの中身(ソースコード)に集中できる.
  • 安価でリクエストが多くなってもスケーリングが楽チン.

至れり尽くせりのマネージドサービスということですね.

サーバーレスアーキテクチャの欠点

 サーバーレスアーキテクチャには,主に以下のような欠点がある.

  • ベンダー(サービス提供者)によるが,制限・制約がある.

    • 同時実行数
    • 秒あたりの実行上限数
    • デプロイ可能なメモリの最大サイズ
    • 一回の実行にかかる時間(タイムアウト制限)
  • レスポンスの即時性に難がある

    • イベント発生のたび動的にリソースが割り当てられる,という特性上,イベント発生の間隔が短い場合はプーリング処理されるが,間隔が長い場合は初回の実行に時間がかかる傾向がある
  • 設計の難易度が高くなる

    • メリットの項で書いたことの裏返し.コード実行後はインスタンスが消滅するため,ステートレスで機能間の依存性がない設計が必要となる

「サーバーレス」だけどサーバはある

 ざっと「サーバーレスアーキテクチャ」について調べたところで出てきたのが以下の記事.サーバーレスであるあるな「サーバーレスにはサーバーがない?」という議論(誤解?)に関する記事.理解を深めるのに非常に参考になった.

d.nekoruri.jp

 以下,記事をまるっと引用.

 3年ぐらい同じ事を言い続けてるんだけど、そもそもサーバーレスという言葉の由来はソフトウェアアーキテクチャの話1。
   一つのタスクの実行期間を超えて、ファイルシステムやメモリ上の変数などサーバ固有のリソースに依存しないという、12 Factor Appから死ぬほど言われ続けている制約を満たすプログラミングモデルがサーバーレスの本質です。この制約に視点を置くとサーバーレスとしか言いようがない。
  これを真面目にやろうとすると、キューやPub/Subによる非同期タスク(イベント駆動)が必要になってきます。これを整理したのがリアクティブシステム、わかりやすく関数という枠にはめたのがAWS LambdaをはじめとするFaaSです。
  その一方で、これを満たしたソフトウェアは、AWSなりAzureなりGCPなりクラウド基盤側が勝手にサーバを増やしたり減らしたりできて、完全従量制にできたりメリットがたくさんでてきます。そういうゼロからスケールできるフルマネージドサービスの性質もサーバーレスと呼んでいます。
  メリットが分かりやすいためクラウドベンダーが主張したいのはこちらの性質なんですが、でもこれって「所有せず利用する」というクラウドコンピューティング全体の流れの延長線上でしかないんですよね
2。

 そして「サーバーレス」に関する解釈.

この設計と運用の二つの性質が混ざったのが現在の「サーバーレス」です。
というわけで、サーバーレスという単語に関しては、
 × サーバが無い
 ○ プログラマがサーバを気にしない
 ◎ プログラマがサーバを(設計上)気にしてはいけない+(運用上)気にしない
  と捉えるのが良いと思います。単純に「サーバが無い」というだけの解釈をしやすいのは事実なので、こういう理解をした方が楽しいよ、という話です。
  日本語圏だとサーバと言えばサーバマシン(ハードウェア)を指すことがほとんどですが、英語Wikipedia見ると、サーバマシンよりも先にクライアント・サーバにおける提供側の"a computer program or a device"が先に来ますし、サーバの仮想化はVirtual ServerではなくVirtual Machineなんですよね。この英語と日本語でのニュアンスの違いが大きいのかなという気はします。

 なるほど(?).「一つのタスクの実行期間を超えて,ファイルシステムやメモリ上の変数などサーバ固有のリソースに依存しないという制約を満たすプログラミングモデルがサーバーレスの本質」,「この制約に視点を置くとサーバーレスとしか言いようがない」という説明で腑に落ちた(気がする).「サーバー固有のリソースに依存しない」という思想のことを「サーバーレス」というのか.「サーバーレス」という言葉は「サーバがない」ことを意味する言葉ではないということである.

分からないこと:CGI とサーバーレスアーキテクチャの違い

 サーバーレスアーキテクチャについて少し学んで見た結果,分からないことがある.それは「CGI とサーバーレスアーキテクチャとの違い」である.

  • CGI:Web サーバ上で外部プログラムを動作させるための仕組み.Web サーバがクライアントから受け取ったリクエストを Web サーバ上で動作するプログラムへ渡し,プログラムはリクエストを参照して処理(HTML を動的に生成),Web サーバに返す.
  • サーバーレスアーキテクチャ:イベント発生時(クライアントからのリクエストなど)に API Gateway 経由でリクエスト.API サーバで処理,処理結果(JSONXML などのレスポンス)をクライアントに返す.

 情報の流れとしては,

  • CGI:クライアント -> Web サーバ -> CGI -> Web サーバ -> クライアント
  • サーバーレスアーキテクチャ:クライアント -> API サーバ -> クライアント

という感じか?(間違っている可能性大)

 どちらもリクエストに応じて外部のプログラムを呼び出すという点で同じだと思うのだけど,知識不足で明確にここが違うと言えない.もし分かる方がいましたらコメントとかで教えていただけるとありがたいです.

終わりに

 大方参考にした記事から持ってきた内容ではあるが,自分の中で「サーバーレスアーキテクチャ」について整理する良い機会となった.調べる前は「サーバーレスアーキテクチャ」というサービスがあるものだと思っていたが,実際は「サーバーレスアーキテクチャという設計思想があり,その設計思想を実現するためにベンダーから各種マネージドサービスが提供されている」といった常識レベルのことすら分かっていなかった.

 実際に調べてみて,自分のようなインフラの知識が少ない人にとって楽にアプリケーションが作れそうという印象を受けた.まだ,アプリケーションの設計といったコードを書く一段階上のレイヤーの勉強が足りないため,設計思想をよく理解して適切な用途で使うことはできないが(それは当たり前),実際に触ることから初めて徐々に理解していきたい.

 まず使うとしたら,S3 に静的ファイルをホストして,フロントから API Gateway に登録したエンドポイントを叩く SPA かなと考えている.とりあえず AWS Lambda を触ってみようと思う.

補足

用語

プロビジョニング provisioning

 使用されるコンピュータリソース(ネットワーク,ストレージ,メモリなど)をあらかじめ予測し,それらを割り当てておくこと.また,それによりサーバを運用可能にすること.

可用性 availability

 システムが継続して稼働できる能力のこと.障害などが起きた時にシステムがどれだけ継続して稼働できるかを表す.ここでの障害とは機器やパーツの故障,災害などのアクシデントを意味する.長い時間,システムを稼働し続けられることを高可用性(High Availability)という.

 一般的に,可用性は「一定時間のうち,システムを稼働可能な時間の割合(%)」を意味する「稼働率」で表現される.「冗長化」などで可用性を向上させることができる.

 可用性と関連して「信頼性」,「耐障害性」という言葉があるが,これらの意味は以下の通り.

  • 可用性:システムが継続して稼働できる能力.
  • 信頼性:障害に強い,障害が発生する頻度が少ないこと.一般的に,信頼性は「平均故障間隔」(システムがどのくらい稼働したら故障するか)で表現される.
  • 耐障害性:障害が起きてもシステムを稼働し続けられること.耐障害性が高いシステムは稼働率も高いため,可用性が高いシステムと言える.耐障害性は可用性の重要な要素の一つである.

疎結合 loose coupling

 システムの構成要素間の結びつき,互いの依存関係,関連性などが弱く,独立性が高いこと.逆に,要素間の結びつきが強く独立性が低い状態のことを「密結合 tight coupling」という.

 疎結合な設計のアプリケーションは,

  • 互換性
  • 拡張性
  • 担当・責任の分担のしやすさ
  • 不具合発生時の原因究明のしやすさ

などの利点があるが,要素間の連携,通信にかかる負荷が大きく,性能や必要な容量などで不利になることがある.

モノリシックとマイクロサービス

www.fiorano.com

「モノリシック」と「マイクロサービス」はそれぞれアーキテクチャで,しばしば比較対象とされる.

  • モノリシック
    アプリケーションの全ての機能が一つのプロセスとして稼働する.UI,ビジネス処理ロジックは単一のプロセスとして実行される.必要なデータは全ての機能で共有する DB に格納されている.アプリケーションの機能の変更の際に,変更の規模に関わらずアプリケーション全体の設計をし直す必要がある.また,UI の機能のみなどの一部分の機能のスケールが難しく,アプリケーション全体をスケールしないといけない.

  • マイクロサービス
    ビジネス処理機能の単位でサービスとする.各サービスは独立したプロセスとして稼働する.マイクロサービスは,他のマイクロサービスとはデータも含め独立しており,各サービスの独立性が守られている.それぞれが単独のプロセスとして稼働する.

 マイクロサービスの利点としては以下のようなものが挙げられる.

  • 独立してデプロイできる(変更,置換が他のマイクロサービスに影響しない)
  • 独立してスケールできる(マイクロサービスごとにインスタンスをスケールできる)
  • 各マイクロサービスの独立性があり,相互の影響がない.

 以下,モノリシックの語源に関する引用.

モノリシックとは、一般的に「一枚板の」や「統制された」、「画一主義的な」などの意味を持つ英語である。
IT業界では、モノリス (monolith) という言葉は、『The Art of Unix Programming』 という本の中で “大きすぎるプログラム” を指す用語として使用され、以降 Unix コミュニティなどで使われ始めました。モノリシック (monolithic) はモノリスの形容詞です。また、日本では、Monolithic Program を “一枚岩プログラム” と訳したりします。(引用元:モノシリックとは?

参考

分かりやすく書かれている先人の記事に感謝.