ブラウザを超えて:サーバーレスWebAssembly入門
公開: 2022-03-10WebAssemblyがすべての主要なブラウザーと世界中のユーザーの85%以上でサポートされるようになったため、JavaScriptはもはや町で唯一のブラウザー言語ではありません。 聞いたことがない場合は、WebAssemblyはブラウザで実行される新しい低水準言語です。 これはコンパイルターゲットでもあります。つまり、C、C ++、Rustなどの言語で記述された既存のプログラムをWebAssemblyにコンパイルし、それらのプログラムをブラウザーで実行できます。 これまで、WebAssemblyは、デスクトップアプリケーション、コマンドラインツール、ゲーム、データサイエンスツールなど、あらゆる種類のアプリケーションをWebに移植するために使用されてきました。
注: WebAssemblyをブラウザー内で使用してWebアプリケーションを高速化する方法の詳細なケーススタディについては、以前の記事を確認してください。
Webの外のWebAssembly?
今日のほとんどのWebAssemblyアプリケーションはブラウザ中心ですが、WebAssembly自体は元々Web専用に設計されたのではなく、実際にはサンドボックス環境向けに設計されています。 実際、そのシステムをサポートするWebAssemblyランタイムがある限り、任意のOSまたはコンピューターアーキテクチャでバイナリを実行するための一般的なアプローチとして、WebAssemblyがブラウザーの外部でどのように役立つかを調査することに最近多くの関心が寄せられています。 この記事では、WebAssemblyをブラウザーの外部でサーバーレス/サービスとしての機能(FaaS)方式で実行する方法について説明します。
サーバーレスアプリケーション用のWebAssembly
一言で言えば、サーバーレス関数は、コードをクラウドプロバイダーに渡し、そのコードのスケーリングを実行および管理できるようにするコンピューティングモデルです。 たとえば、APIエンドポイントを呼び出すたびにサーバーレス関数を実行するように要求したり、ファイルがクラウドバケットにアップロードされたときなどのイベントによって駆動されるように要求したりできます。 「サーバーレス」という用語は、サーバーが途中で明らかに関与しているため、誤称のように見えるかもしれませんが、サーバーの管理、展開、スケーリングの方法について心配する必要がないため、私たちの観点からはサーバーレスです。
これらの関数は通常、PythonやJavaScript(Node.js)などの言語で記述されていますが、代わりにWebAssemblyを使用することを選択する理由はいくつかあります。
- 初期化時間の短縮
WebAssemblyをサポートするサーバーレスプロバイダー(CloudflareやFastlyを含む)は、他の言語を使用する場合よりも少なくとも1桁速く関数を起動できると報告しています。これは、同じプロセスで数万のWebAssemblyモジュールを実行することで実現されます。 WebAssemblyのサンドボックス化された性質により、コンテナーが従来使用されていた分離をより効率的に取得できるため、これが可能になります。 - 書き換えは必要ありません
ブラウザでのWebAssemblyの主な魅力の1つは、すべてをJavaScriptに書き直すことなく、既存のコードをWebに移植できることです。 クラウドプロバイダーはサーバーレス関数を記述できる言語を制限しているため、この利点はサーバーレスのユースケースでも当てはまります。通常、クラウドプロバイダーはPython、Node.js、その他いくつかの言語をサポートしますが、C、C ++、Rustはサポートしません。 。 WebAssemblyをサポートすることで、サーバーレスプロバイダーはより多くの言語を間接的にサポートできます。 - より軽量
ブラウザでWebAssemblyを実行する場合、計算の実行はエンドユーザーのコンピュータに依存しています。 これらの計算が集中しすぎると、ユーザーはコンピューターのファンが動き始めたときに満足できなくなります。 ブラウザの外部でWebAssemblyを実行すると、アプリケーションを軽量に保ちながら、WebAssemblyの速度と移植性のメリットが得られます。 さらに、WebAssemblyコードをより予測可能な環境で実行しているため、より集中的な計算を実行できる可能性があります。
具体例
Smashing Magazineに関する前回の記事では、低速のJavaScript計算をWebAssemblyにコンパイルされたCコードに置き換えることで、Webアプリケーションを高速化する方法について説明しました。 問題のウェブアプリは、DNAシーケンシングデータの品質をプレビューするためのツールであるfastq.bioでした。
具体的な例として、ブラウザ内でWebAssemblyを実行する代わりに、サーバーレスWebAssemblyを利用するアプリケーションとしてfastq.bioを書き直してみましょう。 この記事では、WebAssemblyをサポートし、V8ブラウザーエンジン上に構築されたサーバーレスプロバイダーであるCloudflareWorkersを使用します。 別のクラウドプロバイダーであるFastlyも同様のサービスに取り組んでいますが、Lucetランタイムに基づいています。
まず、DNAシーケンシングデータのデータ品質を分析するためのRustコードを記述しましょう。 便宜上、Rust-Bioバイオインフォマティクスライブラリを利用して入力データの解析を処理し、wasm-bindgenライブラリを利用してRustコードをWebAssemblyにコンパイルすることができます。
DNAシーケンスデータを読み込み、品質指標の概要を含むJSONを出力するコードのスニペットを次に示します。
// Import packages extern crate wasm_bindgen; use bio::seq_analysis::gc; use bio::io::fastq; ... // This "wasm_bindgen" tag lets us denote the functions // we want to expose in our WebAssembly module #[wasm_bindgen] pub fn fastq_metrics(seq: String) -> String { ... // Loop through lines in the file let reader = fastq::Reader::new(seq.as_bytes()); for result in reader.records() { let record = result.unwrap(); let sequence = record.seq(); // Calculate simple statistics on each record n_reads += 1.0; let read_length = sequence.len(); let read_gc = gc::gc_content(sequence); // We want to draw histograms of these values // so we store their values for later plotting hist_gc.push(read_gc * 100.0); hist_len.push(read_length); ... } // Return statistics as a JSON blob json!({ "n": n_reads, "hist": { "gc": hist_gc, "len": hist_len }, ... }).to_string() }
次に、Cloudflareのラングラーコマンドラインツールを使用して、WebAssemblyへのコンパイルとクラウドへのデプロイという手間のかかる作業を行いました。 完了すると、シーケンスデータを入力として受け取り、データ品質メトリックを含むJSONを返すAPIエンドポイントが提供されます。 これで、そのAPIをアプリケーションに統合できます。
動作中のアプリケーションのGIFは次のとおりです。
完全なコードはGitHub(オープンソース)で入手できます。
すべてをコンテキストに入れる
サーバーレスWebAssemblyアプローチをコンテキストに入れるために、データ処理Webアプリケーション(つまり、ユーザーから提供されたデータの分析を実行するWebアプリ)を構築する4つの主な方法を考えてみましょう。
上に示したように、データ処理はいくつかの場所で実行できます。
- サーバ側
これは、ほとんどのWebアプリケーションで採用されているアプローチであり、フロントエンドで行われたAPI呼び出しは、バックエンドでデータ処理を起動します。 - クライアント側のJavaScript
このアプローチでは、データ処理コードはJavaScriptで記述され、ブラウザーで実行されます。 欠点は、パフォーマンスが低下することです。元のコードがJavaScriptでなかった場合は、最初から書き直す必要があります。 - クライアント側のWebAssembly
これには、データ分析コードをWebAssemblyにコンパイルし、ブラウザーで実行することが含まれます。 分析コードがC、C ++、Rustなどの言語で記述されている場合(私のゲノミクスの分野ではよくあることですが)、これにより、JavaScriptで複雑なアルゴリズムを書き直す必要がなくなります。 また、アプリケーションを高速化する可能性もあります(たとえば、前の記事で説明したように)。 - サーバーレスWebAssembly
これには、FaaSの種類のモデル(この記事など)を使用して、コンパイルされたWebAssemblyをクラウド上で実行することが含まれます。
では、なぜ他のアプローチよりもサーバーレスアプローチを選択するのでしょうか。 1つには、最初のアプローチと比較して、WebAssemblyの使用に伴う利点、特にJavaScriptに書き直さなくても既存のコードを移植できるという利点があります。 3番目のアプローチと比較すると、サーバーレスWebAssemblyは、ユーザーのリソースを数値計算に使用しないため、アプリがより軽量であることも意味します。 特に、計算がかなり複雑な場合、またはデータがすでにクラウドにある場合は、このアプローチの方が理にかなっています。
ただし、一方で、アプリはネットワーク接続を確立する必要があるため、アプリケーションの速度が低下する可能性があります。 さらに、計算の規模や、より小さな分析部分に分割できるかどうかによっては、サーバーレスクラウドプロバイダーによってランタイム、CPU、およびRAMの使用率に制限が課せられるため、このアプローチは適切でない場合があります。
結論
これまで見てきたように、サーバーレス方式でWebAssemblyコードを実行し、WebAssembly(移植性と速度)とサービスとしての機能アーキテクチャ(自動スケーリングと使用ごとの価格設定)の両方のメリットを享受できるようになりました。 )。 いくつか例を挙げると、データ分析や画像処理などの特定の種類のアプリケーションは、このようなアプローチから大きな恩恵を受けることができます。 ネットワークへの追加のラウンドトリップのためにランタイムが低下しますが、このアプローチにより、一度により多くのデータを処理でき、ユーザーのリソースを浪費することはありません。