Fastly のネイティブ WebAssembly コンパイラ & ランタイム「Lucet」を発表
本日、Fastly の WebAssembly コンパイラ兼ランタイムであるオープンソースの Lucet を発表できることを非常に喜ばしく思います。WebAssembly は Web ブラウザがネイティブに近い速度で安全にプログラムを実行できるよう作成されたテクノロジーで、2017年初頭から4つの主要ブラウザに取り入れられています。
Lucet は WebAssembly をブラウザの枠を超えて利用し、Fastly のエッジクラウド上でより速く、より安全に実行できるプラットフォームを構築するために設計されています。WebAssembly は Rust や TypeScript、C、C++ などの多くの言語で既にサポートされていて、開発過程ではさらに多くの言語で WebAssembly がサポートされています。Fastly は、お客様が Fastly VCL の域を超えてより多くのロジックをエッジに移し、任意の言語を使えるようにしたいと考えています。Lucet は、 WebAssembly を使用した Fastly のエッジコンピューティング用実験プラットフォームである Terrarium に搭載されているエンジンです。Lucet は、まもなく Fastly のエッジクラウドでも利用できるようになる予定です。
Lucet の主な設計要件は、Fastly が扱う1つ1つのリクエストを実行できるようにすることでした。これは、単一プロセスで1秒間に何万件というレベルで発生するリクエストに対して WebAssembly インスタンスを生成するということです。これには JavaScript エンジンのブラウザよりもはるかに低いランタイムフットプリントが必要になります。Lucet は、わずか数キロバイトのオーバーヘッドメモリにより WebAssembly モジュールを50マイクロ秒以下でインスタンス化することができます。比較すると、Chromium の V8 エンジンでは JavaScript もしくは WebAssembly プログラムのインスタンス化に約 5 ミリ秒の時間と数十メガバイトのオーバーヘッドメモリが必要です。
Lucet を使うと、Fastly のエッジクラウドはセキュリティを損なうことなく同一プロセスで同時に数千もの WebAssembly プログラムを実行することができます。Lucet のコンパイラとランタイムは共に動作して各 WebAssembly プログラムがそれぞれの独自リソースにのみアクセスできるようにします。これは、 Fastly のお客様が当社が常に提供しているセキュリティと安全性を損なうことなく、より一般的で汎用な言語でプログラムを記述し実行できるようになるということを意味しています。
Lucet は、WebAssembly の実行責任を WebAssembly モジュールをネイティブコードにコンパイルするコンパイラと、リソース管理およびランタイム障害を捕捉するランタイムという2つのコンポーネントに分離しています。Lucet は WebAssembly をネイティブコードに事前 (AOT) コンパイルするよう設計されているソフトなので、ブラウザエンジンが利用している実行時 (JIT) コンパイル戦略と比較してランタイムの設計とオーバーヘッドが大幅に簡素化されています。
Lucet の構築方法
Lucet は Cranelift Code Generator 上に構築されています。この Cranelift プロジェクトは Firefox の WebAssembly や JavaScript JIT エンジンを使えるよう Mozilla によって作成されたもので、現在は Firefox Nightly のプレゼンスフラグで有効にできます。Fastly は Cranelift の設計と実装に 取り組んでおり、これにより Firefox ユーザーの Web 体験についても向上させることができることを嬉しく思っています。
Lucet は WebAssembly System Interface (WASI) をサポートします。WASI は、WebAssembly プログラムへのファイルシステム、ネットワーキング、その他システム機能に低レベルのインターフェイスを公開するために新たに提案された安全標準です。Lucet チームは Mozilla やその他と協力して、このシステムインターフェースの設計、実装、および標準化に取り組んでいます。
Fastly は、このプロジェクトに2017年から取り組んでいたので、ついに公開できることに非常に喜んでいます。また、Lucet は Fastly で初めてプログラミング言語の Rust を使ったプロジェクトでもあったので、このプロジェクトでのRust の大きな成功を報告できることを嬉しく思います。この言語を使う新規 Rust ユーザーは、迅速に生産性を向上できたことがわかりました。ライブラリエコシステムでは、WebAssembly と動作する多くの有効なライブラリを提供します。Lucet の開発初期、Fastly は C 言語でランタイムの最初のバージョンを実装しました。しかし、最近になって C 言語のランタイムを Rust に戻して移植し、その処理内で安全性や同時実行性バグを複数発見し修正しました。
Terrarium プロジェクトのエンジンとして、Lucet は数か月の稼働テストで2018年後期の開始以降、数千ものさまざまな WebAssembly プログラムを実行してきました。また、詳細なサードパーティのセキュリティ評価対象にもなっています。
Lucet のクイックデモ
まずは GitHub から Lucet をクローンしてください。
$ git clone --recurse-submodules https://github.com/fastly/lucet
README にはDocker を使った開発環境のセットアップ方法が記載されています。Docker が既にインストールされている場合の手順は1つだけです。すべて完了するには数分かかることがあります。
$ cd lucet
$ source devenv_setenv.sh
では、ちょっとした C プログラムを作成して Clang で WebAssembly にコンパイルします。
$ mkdir demo
$ cd demo
$ cat > hello.c <<EOT
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc > 1) {
printf("Hello from Lucet, %s!\n", argv[1]);
} else {
puts("Hello, world!");
}
return 0;
}
EOT
$ wasm32-unknown-wasi-clang hello.c -o hello.wasm
これで WASI で利用するよう設定された Lucet コンパイラを使って、WebAssembly をネイティブコードにコンパイルできるようになりました。
$ lucetc-wasi hello.wasm -o hello.so
最後に、WASI を使うよう設定された Lucet ランタイムでネイティブコードを実行します。
$ lucet-wasi hello.so
Hello, world!
$ lucet-wasi hello.so world
Hello from Lucet, world!
ドキュメントやその他の例は Lucet リポジトリで確認できます。
エッジクラウドのその先へ
オープンソースの Lucet に Fastly が注目しているのは、WebAssembly に Web ブラウザやエッジクラウドの域を超える大きな可能性が秘められているからです。たとえば、Lucet の WASI 対応は、ユーザーが任意のプラットフォーム (クラウド、エッジ、ブラウザ、ノートパソコンやスマートフォンのネイティブなど) でその強力なセキュリティ保証を保ったまま実行できる WebAssembly プログラムへの大きな一歩です。Fastly は、動的言語、インタプリタ、JIT コンパイラ上に構築された現在のソリューションよりも少ないリソースを使いながら、スクリプティングや拡張を許容するあらゆるプログラム内で WebAssembly を実行できるようにしたいと考えています。
最も重要なことは、Fastly は Lucet、Cranelift、WASI、およびその他の WebAssembly 対応テクノロジーのオープンソースコミュニティと協力していきたいということです。Fastly はオープンソース上に構築されているので、オープンソースのサポートに積極的に取り組んでいます。オープンソースコードなしには Lucet を構築できませんでした。Fastly はこれまで夢見たこともないような新しいことを Lucet が実現できることを願っています。