Upgrade to Pro — share decks privately, control downloads, hide ads and more …

V8 as a container on CDN Edge worker

V8 as a container on CDN Edge worker

Koutarou Chikuba

September 21, 2022

Transcript

22 slides
  1. About Me @mizchi | 竹馬光太郎 主にフロントエンド | Node.js エンジニア Splatoon3

    は S+1 になりました 本資料は Edge Side Frontend という新領域 - Speaker Deck を元に v8 関連を中心に再構成したもの
  2. JavaScript Containers | Ryan Dahl https://tinyclouds.org/javascript_containers ※ Ryan は Node.js

    のオリジナル作者、現 Deno 開発者 JS Engine の V8 は Linux, Docker, に続く新しいコンテナ抽象である という主張 以下、引用は断りがない限り DeepL による翻訳
  3. Ryan Dahl の主張 (1) JavaScript は世界共通のスクリプト言語です。JavaScript の普遍 性のために、サーバーを単純化する新しいコンテナのような抽象 化が出現しています。 “

    “ 私はLinux コンテナがなくなると主張しているわけではありませ ん。その抽象化のレベルは常に有用です。ただ、人々が書く「ビ ジネス・ロジック」の多くには、むしろ低レベルすぎます。ウェ ブサイトを作るとき、systemd のコンフィギュレーションなどは 定型的なものです。 “ “
  4. Ryan Dahl の主張 (2) Web サービスの大部分は、Linux コンテナではなく、JavaScript コ ンテナの観点から考えることで、簡略化できるかもしれません。 “

    “ ウェブは人間のためのものであり、実行環境がスクリプティング 言語であることは理にかなっています。 “ “
  5. 自分の意見 ry の意見は JS びいき過ぎて言語の中立性を欠いている 例えば V8 Isolate と似たモデルを持つ言語として Dart

    もある 他の言語も( 程度はあるが) 実現可能 が、現状に即した選択肢としては JS を選ぶのは妥当 そもそも V8 自体がブラウザの一部として信頼できないユーザー コードを評価するものとして進化してきた ( 言語としての評価はどうあれ) 普及している 余談: OS ではなく言語レベルでセキュリティを担保しようという ry の姿勢は Deno の Permission の仕組みにも現れていそう
  6. V8 Isolate V8 のコード実行ごとのプロセス分離機構/ 分離単位 V8 Snapshot でメモリ状態をシリアライズできる Chrome/Node/Deno は実行環境の

    Snapshot をロードしてユーザ ーコードを実行 例: Google Chrome はビルド段階で作成された、 window や HTMLElement を初期化した Snapshot を持っている Embedded builtins · V8
  7. V8 as a Container とはどういうことか サーバーで大量の V8 Isolate を待機させておく デプロイ

    = ユーザーコード ( .js ) を配置 プロセス初期化時: V8 Isolate でユーザーコードを評価 リクエスト時: V8 Isolate で Request を引数にコードを実行 要はブラウザで大量のタブを開いて動かすのをサーバーとしてやる
  8. "How Workers works" https://developers.cloudflare.com/workers/learning/how-workers- works/ (by DeepL) 1 つのランタイムで数百、数千の Isolate

    を実行でき、シームレス に切り替えることができます。それぞれの Isolate のメモリは完全 に分離されているので、それぞれのコード片はランタイム上の他 の信頼されていないコードやユーザーが書いたコードから保護さ れています。( 中略) 機能ごとに仮想マシンを作成するのではな く、既存の環境の中に Isolate を作成します。このモデルにより、 仮想マシンモデルのコールドスタートが解消されます。 “ “
  9. V8 Isolates オーケストレーション => CDN Edge Worker コンテナ抽象を JS の

    V8 Isolate に決め打ちにすることで、高速な デプロイ、高速なプロセスの起動が可能に 結果として CDN Edge Worker に要求される機能を満たした Cloudflare Workers と ry の Deno 社による Deno Deploy はいず れも同じ発想で、その利点を生かした結果、普通の PaaS ではな く CDN Edge Worker として提供されていそう
  10. Cloudflare Workers の Pricing にみる実際 https://developers.cloudflare.com/workers/platform/pricing/ Free Bundled($5) Unbound CPU

    Time 10ms/req 50ms/req 30000ms/req Cost 100000/day 10 million / month, +$0.50/million 1 million / month, + $0.15/million プランに関わらずデプロイできる JS は 1MB まで。おそらく 128MB の V8 Isolate 実行単位に起因。 CPU Time に 非同期アイドル時間は含まない
  11. 制約から考える CDN Edge Worker の用途 L7 Proxy: 賢いネットワークミドルウェア アプリケーションの前に挟んでキャッシュ制御 既存の

    CDN に対する +α A/B テストや カナリーリリース 軽量な Server Side Scripting (Node.js 代替) 制限を許容してアプリケーション全部を CDN Edge 上で実装 例: npm は cloudflare workers で実装されてる フレームワーク毎のアダプタを介して CDN Edge Worker 化 Next.js | Remix | SvelteKit | Nuxt 等が対応
  12. WebAssembly on CDN Edge Fastly Compute@Edge は JS を介さず WebAssembly

    を実行 Fastly 以外の WebAssembly サポートは V8 を介している気がす るが、いずれにせよ .wasm が動く V8 Isolates オーケストレーションと同様、サンドボックス化された プロセスが応答 wasmtime/cranelift による事前最適化 基本的に C++/Rust をホスト言語としてコンパイル
  13. 例 1: メモリ初期化 ;; demo.wat => demo.wasm (module (memory (export

    "mem") 1) ;; 共有したメモリ空間を参照する accumlate を実装 (func (export "accumulate") (param $ptr i32) (param $length i32) …)) // main.js (wasm host) const mem = new WebAssembly.Memory({initial:10, maximum:100}); const obj = await WebAssembly.instantiateStreaming(..., {js:{mem}}); const i32 = new Uint32Array(mem.buffer); for (let i = 0; i < 10; i++) i32[i] = i; // JS 側から書き換える obj.instance.exports.accumulate(0, 10); https://webassembly.org/getting-started/js-api/
  14. 例 2: WASI Binding の実装 // node による wasi binding

    https://nodejs.org/api/wasi.html const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; const wasm = await WebAssembly.compile( await readFile(new URL('./demo.wasm', import.meta.url)) ); const instance = await WebAssembly.instantiate(wasm, importObject); (module (import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32))) (func $main (export "_start") ;; 呼び出し (call $fd_write (i32.const 1) (i32.const 0) (i32.const 1) (i32.const 20)) ) wasi_snapshot_preview1 はインターフェースを守ればなんでもいい
  15. まとめ V8 はウェブアプリケーションのためのコンテナ抽象として捉える ことができる( 諸説ある) V8 Isolates オーケストレーションによって CDN Edge

    Worker が可 能になっている WebAssembly による CDN Edge worker は言語中立だが、ビルドサ イズ面で実際の言語選択に自由度はない ランタイム決め打ちでプロセスを大量に確保して実行、という実行 モデルは V8 でも WebAssembly でも一緒

More Decks by Koutarou Chikuba

Other Decks in Programming