IBMがRustを使ってNode.jsのプロジェクトを書き換え。その背景とは?

2020年5月29日(金)
松下 康之 - Yasuyuki Matsushita
IBMがRustを使って既存の社内システムを書き換えた。その背景を探る。

IBMがRustを使ったソフトウェア開発を加速している。RustはMozilla Foundationが開発をリードするオープンソースのプログラミング言語だ。Rustの歴史はまだ浅いものの、DropboxやCloudflare、Microsoft、Facebookなどの多くの企業で利用が拡がっている。Microsoftが社内で2004年から統計を取った調査によれば、自社が開発したソフトウェア(C、C++を利用)における脆弱性のうち約70%がメモリーの操作に由来するとして、メモリーセーフなRustを採用する流れになっているという。

Microsoftのセキュリティレスポンスセンターの調査。70%がメモリー関連の脆弱性

Microsoftのセキュリティレスポンスセンターの調査。70%がメモリー関連の脆弱性

参考:A proactive approach to more secure code

Rustを採用する動機に、メモリーセーフ以外のポイントとして高速性を挙げる企業もいる。Bitbucketのブログとして公開された以下の記事では、「メモリー消費量が少ないこと」「C言語と比較しても遜色のない性能を出せる」としてRustが採用されたことが明らかにされている。

参考:Why we chose Rust as our programming language

C言語と比べても遜色のない高速性をRustは達成

C言語と比べても遜色のない高速性をRustは達成

今回はIBMのブログ記事を紹介しながら、IBMがRustを採用するに至った背景を解説したい。

参考:Why using WebAssembly and Rust together improves Node.js performance

RustとWebAssemblyを使ってNode.jsを高速化

RustとWebAssemblyを使ってNode.jsを高速化

対象となったチームはIBMの「Garage Method Team」とあるが、Webで公開されている情報などから判断するとRed Hatなどが展開する顧客向けのラボラトリー(Red Hatの組織はOpen Innovation Labsと呼ばれる)のように、新しいビジネスを一緒に開発するためにクラウドネイティブなソフトウェア開発を行う組織という位置付けだろう。

この組織では数多くのコンテンツをWebを含むさまざまな媒体に対して発行するために組織に属するライターが、Domain Specific Language(DSL)を使って記述し、そのコンテンツを格納したファイルを変換するシステムがNode.jsで書かれていたというのが背景だ。そして、そのアプリケーションを書き直すというのが今回の改修の概要だ。Garage Method TeamのWebページのソースを見てみれば容易に理解できるが、いかにもシステムから自動生成されたHTMLであることからもわかるように、ページを自動生成するためにライターがDSLに従ってコンテンツを書き、それをデータベースから書き出すというシステムであることがわかる。また改修の目的として、すでにDSLを覚えたライターに新しいDSLを強要することなく、コンテンツを書く側に新たな教育を必要とせず、同時にコンテンツ変換の高速化を実現するというのが目的だ。

その方法論として、以下の2つの選択肢が考えられる。

・すべてのコンテンツを一括で変換し、ライターが新しいDSLを覚える・すべてのコンテンツを一括変換もできるが、ライターがローカルのPCでその都度変換を実行可能で従来のDSLをそのまま使う

IBMは、2つ目の方法論を選択したというわけだ。これによって、ライターは新しいDSLを覚える必要はなくなった。

サーバーで一括実行とローカルPCでも実行できる方法を選択

サーバーで一括実行とローカルPCでも実行できる方法を選択

そして既存のシステムがNode.jsベースのシステムであることから、既存のツールなどとも共存でき、Typescriptで書かれたサーバー、クライアント双方のコードとも連携できること。これも条件として挙げられた。

Node.isとスムーズに連携できることが必須条件

Node.isとスムーズに連携できることが必須条件

そして最初のPoC(Proof of Concept、概念実証)ではScalaを使って書き直しを試みたという。Scalaが選ばれた理由は「関数型プログラミング言語としてすでに多くの事例があること」「言語解析に優れていること」「Node.js、JavaScriptとも連携できること」などが挙げられている。

Scalaを選択した理由

Scalaを選択した理由

しかしScalaでは主に速度の部分で満足できる結果を得られなかったという。テストを行うために5分以上処理時間が余計にかかり、ページ解析のテストでも開発環境で500~1000ms、本番環境でも300~450msという処理時間が必要だったという。

Scalaでは処理時間が遅かった

Scalaでは処理時間が遅かった

そこで次の選択肢として選ばれたのが、Rustというわけだ。Scalaで重要視したポイントがクリアできるばかりではなく速度も速く、プログラム自体もわかりやすいという利点があったという。同僚に対してScalaとRustで書いたコードのサンプルを送って評価してもらったところ、Rustのほうが理解しやすかったという。

2番目のPoCに選ばれたのがRust

2番目のPoCに選ばれたのがRust

実行速度が12倍から15倍、文字解析のルールについてScalaでは少ないルールでも実行が遅かったものが、Rustではより多くのルールを追加しても25から30msで処理が終わったということからもわかるように、Scalaに比べて高速な実行が可能となったという。

Scalaに比べて大幅に高速実行が可能なRust

Scalaに比べて大幅に高速実行が可能なRust

以下の表はBitbucketのブログから引用したものだが、RustはC言語と比べても高速な実行速度を達成している。

RustはC言語と比べても遜色のない高速な実行が可能

RustはC言語と比べても遜色のない高速な実行が可能

またデベロッパーコミュニティでの人気という意味ではStack Overflowが毎年行っているデベロッパーに対する調査の結果を見れば、Rustが大きな人気を得ていることがわかる。2019年の調査では「4年連続で最も愛されている言語」としてRustが挙がっている。

参考:Developer Survey Results 2019

4年連続で「最も愛されている言語」となったRust(Stack Overflow調べ)

4年連続で「最も愛されている言語」となったRust(Stack Overflow調べ)

「Loved(最も愛されている}」というカテゴリーは、実際に使っているデベロッパーが今後も使い続けたいと思っていることを表している。一方「Dreaded(恐ろしい、嫌がるの意味だろう)」というカテゴリーではVBAとObjective-Cがトップを争い、「Wanted(必要)」というカテゴリーではPythonが挙がっていることは注目したい。Pythonを使う必要はあるが、Rustほど愛されてはいないという感覚だろう。

またRustが持つメモリーセーフな特徴は、冒頭のMicrosoftのブログ記事で引用されているMatt Miller氏が行ったプレゼンテーションでもあるように、多くの脆弱性に効果的であることを示している。約70%の脆弱性がメモリーセーフに関連するインシデントであり、特にバッファーオーバーフローの脆弱性は多く報告されていることも明らかだ。

Linuxにおけるバッファーオーバーフローの脆弱性の推移

Linuxにおけるバッファーオーバーフローの脆弱性の推移

IBMの記事のサマリーとしてWebAssemblyとの親和性についても触れられており、Node.jsやJavaScriptを置き換えるものではなく、より高速な実行が必要な場合に利用することで補完的な存在としてWebAssemblyが位置付けられていることがわかる。wasm-packによってRustとWebAssemblyが容易に連携できることも評価のポイントだろう。

RustとWebAssemblyの親和性でNode.jsを補完する位置付け

RustとWebAssemblyの親和性でNode.jsを補完する位置付け

メモリーに関する脆弱性を減らすことが可能であること、高速な実行速度、少ないリソース消費などの特徴から、Rustを後押しする大きな流れが来ていることはまちがいない。Rustでよく言われる弱点の一つ、学習コストが高いという部分も、IBMの今回の事例によればコードの読み易さという部分ではさほど大きくないということがわかる。どちらかと言えば変数のオーナーシップの概念そしてオブジェクト指向ではないという辺りが最大の障壁ではないだろうか。

Cargoというビルドツールが標準装備されていること、crates.ioというRustコミュニティリポジトリーが存在することなど、エコシステムは充実しつつある。後はメモリーセーフと高速性という利点と学習コストとのバランスをどう取るか? という段階であろう。より安全なソフトウェアを開発するために、Rustという選択肢があることは覚えておいて損はない。

参考:crates.io: Rust Package Registry

著者
松下 康之 - Yasuyuki Matsushita
フリーランスライター&マーケティングスペシャリスト。DEC、マイクロソフト、アドビ、レノボなどでのマーケティング、ビジネス誌の編集委員などを経てICT関連のトピックを追うライターに。オープンソースとセキュリティが最近の興味の中心。

連載バックナンバー

システム開発イベント

OpenShift Commons Gatheringで語られたOpenShiftに最適なCI/CDとは

2021/3/2
レッドハット株式会社のクラウドソリューションアーキテクト、北山晋吾氏によるCI/CDのセッションを紹介。
働き方イベント

オンラインならではの工夫でリアル開催を凌ぐ盛り上がりに! 「3年後の未来を描け! 悩み爆発 クリエイター1000人祭り」レポート

2021/2/9
2020年12月にオンラインで開催された「3年後の未来を描け!悩み爆発クリエイター1000人祭り」を紹介します。
ITインフライベント

ビルドからリリースまでを抽象化するWaypointにディープダイブ

2021/2/4
HashiCorpがリリースしたWaypointの内部構造など詳細について解説されたセッションを紹介する。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています