並行性、メンテナンス性、対障害性に優れるが、はやっていない「Elixir」
Web開発者の多くは、常に納期の短い仕事に追われている。なんとかサービスをリリースした後も増え続けるクライアント、複雑化するコード、肥大化するサーバー構成、障害対応のコスト増加……と、悩みは尽きない。こうしたつらい状況を改善するための3つの要素として、幾田氏は「並行性」「メンテナンス性」「耐障害性」を挙げる。
「『Elixir』は、それら3つをすべて備えている。Web開発のための優秀なツール類も完備しており、まさにWeb開発者の悩みを解決するために存在するような言語」(幾田氏)
もちろん、gumiでもゲームの認証/課金サービスやAPIサーバー、プロキシサーバーなどでElixirを採用しているという。
しかし、現状は決してWeb開発の現場で引く手あまたというわけではない。幾田氏が紹介したある求人サイトの正社員求人数を言語別に比較したデータ(2019年2月時点)によると、Rubyが1万件以上、Node.jsとScalaがそれぞれ1000件以上であったのに対して、Elixirの求人数はわずか163件。むしろ「はやっていない」状況だ。
なぜElixirは、はやらないのだろうか? 大きな理由として考えられるのが、「学習コストが高い」と思われていることだ。納期が短い仕事を抱える中で、学習コストが高い(と思われている)言語はなかなか採用されにくい。
「主に『並行処理』と『関数型』といった言葉に対する重々しいイメージから、Elixirは学習コストが高いと思われがちだが、実際はそうではない。特にWebシステムの開発に関して言えば、Elixirは学習コストのわりには恩恵が大きい言語だとお伝えしたい」と幾田氏は続けた。
並行処理を意識せず、「逐次処理を書くだけ」でOK
Elixirをおすすめする根拠として、幾田氏はまず、「並行処理」について説明した。Elixir入門者にとっては、そもそも並行処理の概念自体の学習にコストが必要なイメージがあるが、その点から否定する。
「Elixirのフレームワーク『Phoenix』でWebサービスを開発するなら、逐次処理を書くだけで、軽量プロセスによる並行処理の恩恵を享受できる。少なくとも最初のうちから並行処理について学習する必要はなく、しばらく忘れていてもよい」
これは、通常のOSでいう、コンテキストスイッチ等の複雑な処理を、Phoenix(Elixir)の動作環境であるEVM(Erlang VM)側で吸収してくれるからだという。
EVMは、OSと似たプロセスの仕組みを持つ。その具体的な仕組みとして、幾田氏は次の3点を挙げて説明した。
- 独立したCPUを持つ
- 独立したメモリを持つ
- ネットワーク上の一意な住所を持つ
独立したCPUを持つ
EVMは、各軽量プロセスにCPUを使う権利を与える。軽量プロセスが一定量処理をすると、別の軽量プロセスに権限が移るようになっている。1つの軽量プロセスがCPUを専有しにくい仕組みなので、極論、軽量プロセス内で無限ループしたとしてもシステム全体に影響が出にくい。そのため、各軽量プロセス内はシンプルな逐次処理となる。
独立したメモリを持つ
EVMは、軽量プロセスごとにメモリを確保して与える。1つのプロセスは、ヒープ、スタック、メールボックス、プロセス制御ボックスの4種類で構成されている。この仕組みにより、プロセスを終了するとメモリを解放できるので、システム全体でメモリリークが発生しにくい。また、プロセスごとにGC(ガベージコレクション)が走り、GC中にコンテキストを切り替え可能。そのため、GCでシステム全体が停止するといったことはない。
ネットワーク上の一意な住所を持つ
EVMは、各軽量プロセスに一意なアドレス(PID)を割り当てる。軽量プロセス同士はPIDを使ってメッセージを送受信し、共有メモリを使わずに連動可能。通常は、軽量プロセス同士をリンクした状態で、片方がクラッシュしたらもう一方に終了シグナルを送信し、シグナル受信側もクラッシュすることになるが、trap exit = trueを設定してリンクすれば、終了シグナルをメッセージとして受信することにより、プロセスの再起動などを行うこともできる。
このように、EVMの軽量プロセスは「耐障害性」を向上するのに有効な仕組みを持つ。ただし、EVM=OSであるため、OSの運用で考慮するべきことは、EVMでも考慮しなければならない点に注意したい。以下の点などだ。
- CPUを100% 使い切るプロセスは、システム障害に発展するケースが多い
- メモリを大量に消費するプロセスは、システム障害に発展するケースが多い
- プロセスの起動と停止を高速に繰り返すとCPU負荷が上がり、システム障害に発展するケースが多い
- 戦略なくプロセスを大量に起動し、それらを連携させると、システム設計が複雑になるケースが多い
また、極端に遅いわけではないが、「速さ」はそれほどでもないようだ。純粋な1プロセスによる計算では、C、Java、Node.jsより遅く、Python、Ruby、PHPよりは速いレベルだという。
「つまり、Elixirは『並行処理の学習コスト不要で、ほどほどに遅くない、とても楽で安全な言語』と言える」(幾田氏)