Elixir 勉強会 tokyo.ex#7 × 歌舞伎座.tech #13 参加レポート

elixir-flame-i-catch

Elixir勉強会が歌舞伎座.techと合同で2017年1月11日に株式会社ドワンゴ様のセミナールームにて行われました。

tokyo.ex#7

今回はこの勉強会のレポートを書きます。
当日は参加者が約100人と大盛況で、ドリンク、寿司、ピザも提供されました(スポンサーの皆様ありがとうございます!)。

raft_fleetの紹介

Shunsuke Kirinoさんより、ErlangVM上でRaftという分散合意アルゴリズムを実装したライブラリの発表がありました。 https://skirino.github.io/slides/raft_fleet.html#/

Erlang/Elixirがノード間のメッセージバッシングに優れていることやActor Modelが好きでこのライブラリを開発したそうです。 発表ではraft_fleetの仕組みや開発で苦労したところの話がありました。

私はRaft自体知らなかったのですが以下の資料が参考になりました

分散型コンセンサス・アルゴリズム プロトコル まとめ
Raft

ニコニコ動画・生放送でのErlangの利用

@mtgtoさんよりErlangで実装したニコニコ動画、生放送のシステムの仕組みと大規模システムをErlangVMで運用して学んだことについての発表でした。
ニコニコ動画、生放送のシステムはトランスコードの部分はC/C++なのですがそれ以外は全てErlangで実装されているとのことです。

  • 行数:10万行
  • コミット数:1万コミット
  • プルリクエスト数:2000個

ここまでの大規模なシステムでのErlang実用事例はなかなかないので非常にありがたかったです。
発表資料は以下です。
ニコニコ動画・生放送でのErlangの利用

以下、私のメモを書いておきます。

システム構成

  • トランスコードの部分だけC/C++、それ以外は全てErlang
  • OTPのgen_serverの仕組みを多用、spawnは直接使わない
  • ビルドツールはrebar2, 3, Mix
    • 開発当時はrebar3もelixir1.0もなかった
    • Mixの依存解決が欲しくてrebarと併用
  • テストはxref,diayzer
    • EUnit
    • Common Test (CLIからの結合テスト)
    • xref(リファレンスチェック)
    • Dialyzer(静的型チェックツール遅い)
  • CI
    • jenkins、マージ時に走る。一回30分かかる、Dyayzerが遅い
    • CIはDockerのコンテナ上で走る(同一ポートで走らせたかった)
  • デプロイ
    • relx + fpmでRPM作成
    • relaxでリリースバイナリ作成
    • systemdで自動起動できるようにしている
    • Ansibleで並列デプロイ

ErlangVMで大規模運用して学んだこと

サーバ監視

  • Zabbix + Kibana
  • ElasticSearchでログ突っ込んでビジュアライズ

実際に起きたトラブル

  • メモリリーク
    • 運用後、徐々に空きメモリが減っていく
    • 動画配信サーバで飲み発生
    • 最初はそこまでひどくなかったが最後は一週間もたなかった
    • 調査したところ、portによるリークが原因であることが判明
    • TCP通信で利用されるPortが低確率で解放されないことがあった
  • NIFコードでクラッシュ(Native Implemented Function)
    • ErlangVMからNativeの外部プログラムを呼び出すことがよくある
    • やり方はportとnifがある
    • Cを呼べるとなんでも実行できるが、ErlangVMに守られなくなる
    • 死んだらVMごと死ぬ
    • bugをひたすら潰す、gdbでやった
    • 呼び出していたライブラリで発生していた、ライブラリのソースコードが公開されていたのが救い
  • ログ出力で応答不能
    • アクセスが多くてスケジューラーが詰まって処理できなくなる
    • 処理できなくてエラーログ増え、その結果さらにスケジューラーが詰まるという悪循環
    • とりあえず出力するログの量を減らした
    • ロギングライブラリを更新し、大量のログが出るときには出力を諦めるようにした

その他

  • reconは不具合調査で神だった
  • gen_tcp:send/2はtimeoutで失敗したときにどこまで送ったかわからない
  • ちょっとずつ送る
  • 複数サーバで実行、一台がCPU暴走するとErlangクラスター内の全てが暴走
  • 利用ライブラリのバグだったので潰した

なぜErlangにしたか

  • ホットコードローディングの仕組みがあるのでプロセス無停止で更新できる
  • 大規模なサーバ間通信クラスターを構築しやすい
  • 安定している & 枯れている
    • 始めた時はElixirは1.0もなくて当然使えなかった
  • Erlang開発経験者はほとんどいない
    • 言語自体は小さいのでなんとかなる
    • OTPはやるしかない
  • どちらかというとErlangより大規模サーバーの開発の方が難しい
    • どういったログ出力すると不具合調査しやすいかとか

Elixir Conf Japan 2017

elixirconf2017

株式会社アカツキの@seizansさんよりElixir Conf2017が開催されることが発表されました。
このような国内での大規模なElixirのカンファレンスは初めてで、なんとElixir作者のJose Valimがキーノートスピーカーとして参加します!
コミュニティを盛り上げ、Elixirがすでに実戦投入できる技術であることを実感できるイベントになりそうです。

LT、懇親会

ビールと寿司とピザとともにLT、懇親会です。写真を撮り忘れてしまい会場の雰囲気が伝えられないのですが非常に賑やかにプログラマー同士の交流ができて楽しかったです。
LTの発表資料のリンクを乗せておきます。  

Phoenixでディレクトリリスティングを取るには
ExAwsでAWSのAPIを使う
CowboyとPhoenixの速度比較
Using Neo4j from Elixir (and Next Generation Access Control)
軽量プロセスとSTG

運営者の皆様、お疲れ様でした!

AWS Cloud Roadshow 2017 福岡