🚀

サーバーレスの次はなんなんだ

2024/04/20に公開

はじめに

この記事は、同人誌サークル「めもおきば」から不定期刊行している技術解説本「めもおきばTecReport」に書いたものを公開用に再編集したものです。


めもおきばTecReport 2023.12

この記事のほかにも「私もSecHack365に参加したい!」や、「2023年振り返りと2024年技術予想」としてこんなキーワードを取り上げているので、気になったらぽちっとしてください!

メガクラウドと特化型クラウド/ハイパーバイザーのSoC化/ライセンスとクラウドベンダー/イベント駆動型API/LLM時代のAIペアプロ力/生活必需品としてのGPU・NPU/Passkey/ウェブアクセシビリティ/リアルイベントの再開

サーバーレスの次はなんなんだ

サーバーレスと呼ばれる技術ムーブメントが盛り上がり始めて8年近くが経ちました。各クラウドベンダーのFaaS(Function-as-a-Service)は、「関数」と呼ばれる比較的小さなプログラムを動かすという点では安定期に入り、コンテナエコシステムとの融合なども進んでいます。そしてFaaS以外の「サーバーレス」を自称するクラウドサービスが、実態はともあれ、たくさん登場しています。

この記事では、サーバーレス技術について現状をおさらいしてから、いくつかの視点から、その少し先の話をしていきます。

現状のおさらい

関数(Function)という単語を頭にかぶったFaaSは、呼び出しのエントリーポイントが何らかの関数やメソッドであることからそう呼ばれていますが、要するにFaaSとは任意のプログラムを一定の制約下で動かすことができるフルマネージドなPaaSです。

一般的なFaaSでは、ミリ秒単位で実際にかかった実行時間が計測され、メモリ量などと掛け合わせて消費したリソースに対して従量課金されます。

この従量課金であるというのが重要で、これを実現し利益を出すためにクラウドベンダーは様々な努力をしています。たとえば一つの物理マシン上で異なる顧客のプロセスを安全に無駄なく動かすためにマイクロVM(AWSであればFirecracker)を用意しなくてはいけません。同時にたくさんリクエストが来たときにも関数が実行できるように、同時に起動するプロセス数を管理し、ロードバランサーからの振り分け先を変えなくてはいけません。今使っている物理マシンだけでは足りなければ、別の物理マシンを追加し、プロセスを立ち上げることも必要です。

そして、このようにクラウドベンダーが「よしなに(=フルマネージド)」やってくれる一方で、そのために開発者も「クラウドに向いた」アプリケーションを書く必要があります。これは古くから言われる「The Twelve-Factor App[1]」における「プロセス」が示すように、ファイルシステムやメモリ上に保存が必要なデータを記録・共有できず(ステートレスかつシェアードナッシング)、すべて外部のデータベースやクラウドサービスに投げる必要があります[2]

そしてこれはあくまで原始的なFaaSについての話で、こういったクラウドらしい制約下でのソフトウェアによって、様々なクラウドサービスが実現されています。現在では各クラウドベンダーが「サーバーレス」を自称するものがいくつもあります。

著者自身の考えとしては、まずクラウドコンピューティング(そしてコンピューターサイエンス)の進化の流れがある中で、そのなかでいくつかの特徴を持つものに対してサーバーレスという名前が後付けでついたものという認識をしています。なので、サーバーレスかどうかは1/0とはっきり分けられるものではなく、グラデーションになっていると考えています。

サーバーレスの特徴

サーバーレスらしさの特徴をよく表現しているのが、Momento社による「サーバーレスの定義[3]」で、ここで紹介しておきます。

  1. プロビジョン不要、管理不要
  2. 最低料金のない使った分だけの支払
  3. 1つのAPI呼び出しで利用可能
  4. 計画停止がない
  5. インスタンスが無い

これらをすべて満たすクラウドサービスであれば、「かなりサーバーレス」だと言えますし、一部しか満たさないものは「ちょっとサーバーレス」です。

現実的に考えていくと、たとえば実際のリクエストを受け付けるためには、最低限特定のポートをLISTENして待ち受けるプロセスが動いている必要がありますし、完全な従量課金の実現はかなり難しいものです。言い換えると、ある程度のリソース消費についてはクラウドベンダーが「負担」していることになります。

プロビジョン不要、管理を全部任せるといっても、現実にはどこかにサーバーがあるわけで、ある顧客のプロセスをサーバー単位で割り当ててオートスケールしているのであれば、従量課金の計測単位は1台、2台とどうしても大きくなります。

本当にサーバーレスらしいサービスを実現するためには、仮想マシン単位で考えていては困難です。最初からマルチテナントのクラウドサービスとして、巨大なリソースプールに処理を薄く広く「ばらまいて」振り分けていくことになります。

でもこれって、クラウドコンピューティングの定義[4]そのものだったりします。

  • オンデマンド・セルフサービス
  • 幅広いネットワークアクセス
  • リソースの共用
  • スピーディな拡張性
  • サービスが計測可能であること

というわけで、クラウドらしいソフトウェアをクラウドらしく動かすことができていたら、それはきっととても「サーバーレスらしい」アーキテクチャなのではないでしょうか。

ソフトウェア開発の主戦場の変化

太古の昔のCGI時代、ウェブアプリのアプリケーションはサーバーサイドで完結し、ブラウザ側ではHTMLとCSSのレンダリングと、文字を光らせたり動かしたりとちょっとばかしの装飾のためにJavaScriptなどを動かしていました。

それから時が経ち、Google MapではじまるAjax時代と、Ruby on Railsによるウェブアプリケーションフレームワーク時代がやってきました。ブラウザ上のフロントエンドアプリケーションを上手く開発するためにPrototypeやjQueryといったDOMを操作しやすいライブラリが開発され、RailsもHTMLのレンダリングだけでなくREST APIの書きやすさや、Ajaxとの統合を目指したりしていました。

現在はReactとVueという仮想DOMをもとにしたフレームワークの全盛期です。そしてその上でNext.jsなどのフレームワークが登場しました。以前Railsなどが果たしていたようなウェブアプリケーションの主戦場は、いまやフロントエンド側に移り変わりつつあります。

詳しくは後ほど紹介しますが、Cloudflare WorkersがJavaScriptを採用した影響は大きく、フロントエンド開発者がサーバーサイド側のエコシステムに貢献するチャンスをさらに増やしたというのがこの後を考える上で重要なポイントです。

フロントエンド・サーバーサイドの開発生産性

一つの機能を新しくつくるためには、フロントエンドとサーバーサイドの双方で開発し、その間でデータを連携する必要があります。

一番素直にやるのが、OpenAPIやGraphQL、gRPCといったスキーマを中心としてインターフェースを定義して開発するやりかたです。スキーマからの自動コード生成など様々なエコシステムが整っています。フロントエンドとサーバーサイドで異なる言語を使っている場合はこの方法が一般的でしょう。

また異なるアプローチとしては、Node.jsでサーバーサイドでもTypeScriptを(トランスパイルして)動かすことで、フロントエンド・サーバーサイド双方で一つの型定義を共用しようというtRPCのようなものもあります。

サーバーサイドが、複数のマイクロサービスで実現されている場合などは、いったんフロントエンドからのリクエストを受け付けるBFF(Backend for Frontend)を設置して、バックエンド側の仕様とフロントエンドの仕様をつなぎあわせることもあります。たとえばAWSではAppSyncというGraphQLのBFFサービスがあります。

このように、フロントエンドとサーバーサイド双方での開発が必要で、認知負荷を下げ開発生産性を上げようという努力がされています。

クライアント開発言語のサーバーサイドへの侵食

フロントエンド側のNext.jsなどでは、パフォーマンスなどのためにSSR(Server-Side-Rendering)、ISR(Incremental Static Regeneration)などといったサーバーサイドと密に連携する仕組みがあります。こういったフレームワークを活用するには、サーバーサイドでも同じ言語、フレームワークを採用するとメリットがでてきます。

こういった仕組みを活用するため、VercelやNetlifyといったFaaSが組み込まれた新しいホスティングサービスが登場しました。さらに、パフォーマンスを重要視する用途にCDNエッジコンピューティングサービスを活用しようという流れができます。ここでCloudflare Workersなどが上手くはまることになります。

あたらしいFaaSのありかた

旧来のFaaSでは、様々な言語のソフトウェアを動かそうとしているため、言語環境の下のマイクロVMのレイヤーでセキュリティ上の隔離(サンドボックス)を行っています。ところがこれはマイクロVMといってもプロセスを1から起動するのでどうしても一定の時間が掛かってしまいます。

ところが、サーバーサイドがJavaScriptでよいのであれば、Node.jsやChromeのJavaScriptランタイムであるV8にサンドボックスの仕組みがあるので、それを利用すればとても高速かつ安全に関数の実行ができます。Cloudflare Workersなどは、このV8サンドボックスをつかっています。効率が良いため、課金対象として計算される実行時間も、I/O待ちを除いたCPU時間での課金[5]を採用しました。

これと正反対の視点からスタートして同じところにたどり着いたのが、WebAssembly(Wasm)によるCDNエッジコンピューティングです。Wasmは、様々な言語からコンパイルされたアプリケーションをサンドボックスの中で実行できる新しい技術です。Wasmもやはり基本仕様としてサンドボックスを実現しているため、軽量に実行できます。Wasmでアプリケーションを動かせるFastly Compute@Edgeなどがあります。

このようにCDNエッジコンピューティングの実行環境は、サンドボックスによる隔離を前提としたV8やWasmをベースにしています。どちらが今後より主流になるかはまだまだ未知数です。

FaaSのプログラミングモデル

安定期に入ったとはいえ、メガクラウドのFaaSも進歩をつづけています。

Azure Functionsでは、これまでどの言語においてもほとんど共通のインターフェースを採用していましたが、PythonとJavaScriptではそれぞれの言語らしいインターフェースへの移行をしようとしています。Python[6]ではデコレーター、JavaScript[7]ではExpress.js等のフレームワークと似たインターフェースを提供しています。

また、CDNエッジコンピューティング向けとして登場したフレームワークHonoもAdapterという抽象化によって、AWS LambdaやAzure Functionsへの対応を進めています。

CDNエッジコンピューティング

ここまでいくつか登場したCDNエッジコンピューティングサービスが、この数年で急速に存在感を増しています。

AWSやAzureといった既存メガクラウドと、CDNエッジコンピューティングの一番の違いは、マルチテナント・マルチリージョンがシステム全体の前提となっていることです。そもそものCDNというコンテンツ配信のネットワークサービスというものがマルチテナントによる統計多重効果からスタートしています。

AWSでLambda@Edgeをさわった人であれば、設定はグローバルであるものの内部にはリージョンの考え方が残っていることをご存知かも知れません。マルチテナントと考えると、セキュリティ隔離などをきちんとやろうとすればするほどコールドスタートのコストがかかるという課題がありましたが、すでに紹介したとおり、JavaScriptやWasmのサンドボックスを前提とすることで解決しています。

こういった制約の強いやりかたは、メガクラウドの視点から見ると、CDNエッジコンピューティングは一種の破壊的イノベーションに見えているかも知れません。

さまざまなサーバーレスなサービス

ここまで自分の書いたソフトウェアを動かす動作環境としてFaaSやCDNエッジコンピューティング環境について紹介してきましたが、データストアをはじめとする様々なクラウドサービスもまた、分散システムとして様々な課題を解決しています。

この記事の最初に紹介した「サーバーレスの特徴」のとおりグラデーションがありますが、いくつか基本となるしくみは共通しています。

ひとつはCompute LayerとStorage Layerの分離です。たとえばTiDB Serverlessではデータの最終保管先にAmazon S3を利用しています[8]。Snowflakeなども同じようにComputeとStorageを分離するアーキテクチャです。これを突き詰めたのがWarpStream[9]です。Apache Kafka互換のデータストリーミング基盤を、Amazon
S3の上に構築し、送信側(Producer)と受信側(Consumer)はそれぞれS3上のデータに直接アクセスすることで、常駐して動くアプリケーション無しでこれを実現しています。

Computeは状態をすべてStorageに書いてしまうので、あとはStorage側をいかに守るかです。これも基本のパターンはReplicationとShardingです。Replicationは一つのデータを複数のマシンに分散します。Shardingはデータに含まれる特定のキーを使って、保存先のマシンを分散させます。

こうして様々なデータストア系のクラウドサービスがサーバーレス的になっていっています。最後にいくつか紹介しておきます。

RDBMSでは、SQLiteベースのCloudflare D1、先ほども紹介したTiDB Serverless、Neon、PlanetScale、Vercel Postgresなどがあります。キャッシュとしては最近人気のMomentoのほか、UpstashはRedisやKafkaを提供しています。

検索システムもまた一つのデータストアの形です。AlgoliaやMeilisearch Cloudなどがあります。さらにベクトル検索という分野があり、特に最新の技術というわけではありませんが、最近LLMのRAGという文脈で急に需要がきたものです。CloudflareのVectorizeや、Momento Vector Indexなど新しいサービスが参入しています。たとえばグラフDBなんかも古くからある分野ですが、なんらかの理由で注目を浴びたりするかも知れません。

さいごに

サーバーレスの少し先を見通すための考え方をいろいろと紹介してきました。

おさらいとして、いくつかのキーワードを最後にあげておきます。

  • サーバーレスとはクラウドをクラウドらしく利用すること
  • マルチテナントを前提とした薄く広いアーキテクチャ
  • マルチテナント・マルチリージョン前提のCDNエッジコンピューティング
  • 軽量な言語系のサンドボックスによるコールドスタート軽減
  • フロントエンド側都合(SSR、ISR等)によるサーバーサイドへの浸透
  • フロントエンド・サーバーサイド間のインターフェース、スキーマ、型管理

それでは、楽しいサーバーレスライフを!

脚注
  1. The Twelve-Factor App (日本語訳) https://12factor.net/ja/ ↩︎

  2. 一時ファイルや、キャッシュメモリなどを再利用するという話はここでは置いておきます。 ↩︎

  3. https://www.gomomento.com/blog/fighting-off-fake-serverless-bandits-with-the-true-definition-of-serverless ↩︎

  4. NIST によるクラウドコンピューティングの定義 (IPAによる翻訳)
    https://www.ipa.go.jp/security/reports/oversea/nist/ug65p90000019cp4-att/000025366.pdf ↩︎

  5. https://blog.cloudflare.com/workers-pricing-scale-to-zero/ ↩︎

  6. https://techcommunity.microsoft.com/t5/azure-compute-blog/azure-functions-v2-python-programming-model-is-generally/ba-p/3827474 ↩︎

  7. https://techcommunity.microsoft.com/t5/apps-on-azure-blog/azure-functions-node-js-v4-programming-model-is-generally/ba-p/3929217 ↩︎

  8. https://logmi.jp/tech/articles/329530 ↩︎

  9. https://www.warpstream.com/blog/kafka-is-dead-long-live-kafka ↩︎

Discussion