Erlang上でモダンなプログラミングを可能とするElixir
Elixirのカンファレンスが4月1日、秋葉原ダイビルで行われた。
ご存知の方も多いように、ElixirはErlang VM(BEAM)がホストする言語の1つ。
1980年代に登場したErlangという並行処理指向のプログラミング言語をベースに、2000年以降の関数型言語の手法を取り入れるというアプローチは他にもあるが、Elixirは最も成功しているものの1つといえるだろう。
Erlangは大量の並行処理に実績のある言語だが、その文法やパッケージがちょっと今風ではない。
そこで、Erlang VM上にパッケージマネジメントやビルドツールといった環境を用意し、メタプログラミングやポリモーフィズム、Unicodeに対応するものとして構築したのがElixirだ。
Elixirの文法が提供するメリットとErlangの同時処理モデルのメリットを組み合わせることができる。
Elixirは2012年に登場し、2014年9月の1.0 リリース以降急速に広まり、実サービスでの事例も増えている。今回のカンファレンスは、そうした事例を日本でも紹介しよう、Elixirをさらに盛り上げようというもの。
当日行われたセッションのうち、ここでは「ニコニコを支えるErlang/Elixir」(株式会社ドワンゴ 原耕司さん)を取り上げる。
大規模システムにおけるErlang/Elixirの使いどころ
登場したのはドワンゴの原耕司さん。

ニコニコといえば、いわずもがなの大規模動画配信&生放送サイト。動画配信「ニコニコ動画」(ニコ動)のほうは1日3千万再生・総動画数1420万という規模、一方、生放送「ニコニコ生放送」(ニコ生)は1分間に100番組。
ニコ動・ニコ生の全体構成は図のとおり。

たとえば、ユーザーが生放送をしようとしたときに何が起こるかというと、まずユーザーがフロント、アプリサーバに対し、ログインを行う。
生放送の開始ボタンを押すと、その裏側で「生放送を作れ」というリクエストがDwango Media Cluster(DMC)に送られる。DMC内にリソースが確保され、ユーザーはDMCに映像データを送る。このDMCが視聴者に対し、生放送を送るという流れだ。
このDMCは主にErlangで書かれており、その量なんと55万行。なぜ、DMCを開発したのかというと、それまで既存のサーバ製品の組み合わせで運用していたのが、サービスが大規模になるにつれ、そこに拡張性やリソースの柔軟性が求められ、既存製品での対応では厳しくなったからだ。
スマートフォンの登場、リッチテキストのフォーマットからのFlashのリタイアなど、世の中的な変化も背景にある。ここで理想的なコンテンツ配信システムを作ろうということで、2014年12月に開発プロジェクトがスタート。
稼働状況としては、ニコ動の新規投稿動画すべて、ニコ生に関してはその一部の配信をDMCで回している。ニコ動の動画配信では1台で同時に数千動画配信できるレベルの安定稼働。このあたりは、並行分散処理に実績のあるErlangのすごさだ。
もちろん構成上の工夫も大きい。
DMCはさまざまなコンテンツ、機能を統一的に扱う仕組みを用いている。「レシピ」、データフローを抽象化したグラフ構造だ。

ニコ動、ニコ生の基本機能(投稿、配信、タイムシフト、スクリプトレベルの映像合成など)を一通り実現する必要がある。配信にも、アクセス元の接続回線に応じ、適切な画質にトランスコードしなければならない。扱うコンテンツは動画やコメント(テキスト)など、さまざま。
そして、課題として、
- スケールすること
- リソースの有効活用
を解決するものとして考えた結果だった。
基本動作としては、利用者が書いたレシピをDMCに投げるとそれを解釈して実行するということになる。
一方、API側に求められるのはレシピの登録・変更・削除だが、レシピ定義から生成するように自動化されている。つまり、レシピの仕様を変更したければ、定義を変更してmakeするだけで変更コードができあがるという具合。
実際、リリース後に新規機能追加などの調整が発生するが、API修正の自動化によって、エンジニア一人の生産性を約50%upできているという。
また、リソースを有効活用するための仕組みとして、処理をより一般化するということで、レシピよりも抽象化した「タスクグラフ」を定義。

どういうことかというと、グラフの各頂点ごとに実行できる機能の制約が決まる。
たとえば、「放送受付」には太いネットワーク帯域がいる。動画の「配信」のところでいうと、ネットワーク帯域に加えてストレージも必要。あるいはトランスコードのところはCPUが……と、その制約ごとにノードを定義するのだ。
あとは、Assign関数を定義し、クラスタの現在の状況と照らし合わせながら、Assign関数がタスクグラフの各頂点を、制約を満たす一番空いているノードに割り当てる。
クラスタ状態は各ノード間で共有し、Assign関数の型としては、タスクグラフとクラスタ状態を持って割り当て済みのグラフを返すというものになっている。

では、Elixirはどこに使われているかというと、周辺システムのDMC gatewayの部分だ。

Erlang/Elixirがはじめてのエンジニア一人が3ヶ月程度で組むという規模感で、要求自体もそこまで厳しくはなく、開発はスムーズに進んだ。Elixirの良かった点として、
- 変数への再束縛ができる(var1、var2、var3と不毛な変数の名付けをしなくていい)
- Erlangライブラリもすんなり使えた
- ExUnitによる単体テスト
- RPM生成もラク
を挙げ、全般的にErlangよりも書きやすい印象だったという。
一方、手こずった点として、
- ErlangとElixir、同時に書くことで変数の書き方などに混乱する
- パイプ演算子
を挙げる。
どれほどレビューをしようと、テストをしようと大規模システムを運用しているといろいろなことがある。binaryがGCされない問題、TCPセッションのリークなど、それらに対しては再現コードを検証し1つ1つに対応したという。
動画配信というと非常に特殊なサービスで、だからこそErlang/Elixirがマッチしたのではないか、という部分もあるが、既存の製品を用いずに大規模システムを構築(運用)の事例として非常に興味深い。
まとめとしては「Erlangはマイナーだが役に立つ」(原さん)。
力武さんの「Erlang and Elixir Factory SF Bay 2017」報告
最後にどうしてもふれたいのが、TL特別枠で発表された「Erlang and Elixir Factory SF Bay 2017 参加報告」(力武健次技術士事務所所長 / ペパボ研究所客員研究員 力武健次さん)だ。
Erlang Factoryとして2009年から始まるこのイベントに2010年から参加しているという力武さん。
「だんだんElixirの話題が入ってきて、今年からいよいよイベント名にElixirという文言が入った。対等な言語として扱われるようになった」(力武さん)。Elixirの位置付けが変わってきているという。

会議の中身は、Erlang/OTP、あるいはElixir、Phoenixに関係していれば何でもあり、と間口は広い。
最近は、Erlang/Elixirに興味を持っているエンジニアがトレーニングを受けに来る人も多く、そういう人たちが来てもおもしろい内容ということで、会議の内容は少しずつ変わってきているという。

会議は間の3日間で、最初の3日間および最後の4日間トレーニング(有償)。お金を払って、がっつりトレーニングを受けに来るという場所になっているのだ。
Erlangソリューションズが提供するトレーニングの中身も、Erlang、Elixir両方できて当たり前という感じになってきているという。

力武さんは、毎年発表するためのネタを考えて、企画を通して参加している。今回はOTP Moduleとどう付き合えばよいか、という話。その他、Erlangのはまりどころを発表してきたそう。
力武さんは
「真面目にお願いしたい。日本の人が誰もこないんです。この8年間、毎年行っているのは私だけなんです。日本からアメリカに移住してこられた方、もう一人、日系の方、Mack Sugiyama、その3人。これはまずい。ここにいる人、特に今日発表された方は、来年、ぜひ発表をしていただきたい。日本から外に出して欲しい。いまのみなさんの成果を外に出してください」
という。
今回の「Elixir Conf Japan 2017」は生みの親であるJosé Valimさんも登壇、300人超が参加する大規模なものとなった。コミュニティの盛り上がりをより広げることが、新しい言語の可能性を広げることにつながるのだろう。
