SlideShare a Scribd company logo
1 of 68
Download to read offline
ニコニコを支える
Erlang / Elixir
質問 → #elixirjp
はら @kojingharang
ドワンゴ
基盤開発本部
コンテンツ配信基盤開発部
先端サービス基盤セクション
セクションマネージャ
略歴
S社 JPEG2000, ProRes 等のコーデック実装 on Cell/B.E.
G社 Blink Web IDL compiler
D社 ニコキャス iOS アプリ, DMC
TopCoder maximum rating 1754
自己紹介
第一部
ニコニコとDMC
コンテンツ配信システムを作っています
ニコ動, ニコ生の全体構成
サーバ製品を頑張って10年運用してきたが
規模がデカくなりいろいろしんどくなってきた
〜 これまでのあらすじ 〜 スケール
リソース融通
〜 これまでのあらすじ 〜
世の中いろいろ変わったし
そろそろ新サービス出したいし
→ 理想的なコンテンツ配信システムを作ろう !
スマホ
脱Flash
映像合成
Erlang 2,400 ファイル, 55 万行
C++ 400 ファイル, 6万行
Rust 120 ファイル, 2万行
開発者 20 人
インフラ 4 人
サーバ たくさん
DMC の規模
ニコ動の新規投稿動画すべて
+ ニコ生の一部
を DMC で実現
稼働状況
ニコ動の新規投稿動画すべて
+ ニコ生の一部
を DMC で実現
すこぶる安定して動いています
1台で同時数千動画配信
Erlang VM すごい
稼働状況
第二部
DMC開発の舞台裏
2014/12
プロジェクトスタート
( 2014/12 高橋みなみAKB卒業発表 )
まず要求分析
自分ならどう作るか、
考えながら聞いてみてください !
ニコ動, ニコ生の基本機能が一通り実現できる
投稿, 配信, 高中低画質トランスコード, タイムシフト記録, 視聴, ...
様々なコンテンツを統一的に扱える
柔軟な映像合成ができる
要求
スケールする
リソースの有効活用
動画と生放送が同一ノードで配信できるとか
オフピーク時間帯は高画質視聴できるとか
要求
2015/1〜
設計 / 実装
様々なコンテンツを統一的に扱えるように
「レシピ」を設計した
レシピ = データフローを抽象化したグラフ構造
レシピの形式的定義
600行のテキスト
DMCの全てが書かれている
利用者が書いたレシピを解釈実行する
DMC の基本動作
API
レシピ(JSON or XML)の
登録, 変更, 削除を受け付ける
API
保守が面倒なので
めっちゃ自動化した!!!!!
API
レシピ定義からいろいろ全自動生成
● C++/Erlang モデル
● XML/JSON と C++/Erlangモデルの変換器
● C++/Erlang モデルの部分更新処理コード
● C++ モデルの Lua binder
● Validator, getElementById みたいなユーティリティ
● Doc
生成物は 6 万行くらい
API
レシピの仕様を変更したければ
定義を変更して make するだけ
API
レシピの仕様を変更したければ
定義を変更して make するだけ
完全勝利
API
レシピの仕様を変更したければ
定義を変更して make するだけ
完全勝利
完全勝利 完全勝利
API
レシピの仕様を変更したければ
定義を変更して make するだけ
完全勝利
完全勝利 完全勝利
API
リソースの有効活用
処理を抽象化した「タスクグラフ」を定義
生放送 動画
録画 旧システムへの送出
放送
受付
トランス
コード 配信
投稿
受付
トランス
コード 配信
処理を抽象化した「タスクグラフ」を定義
生放送 動画
Assign 関数がタスクグラフをクラスタに割り当てる
Assign : G, C -> G’
Assign 関数がタスクグラフをクラスタに割り当てる
Assign : G, C -> G’
G タスクグラフ
C クラスタ状態
G’ 割り当て済みのタスクグラフ
詳細設計, 実装
OTP を素直に使う
ハマりポイント
supervisor にメッセージを送りすぎてボトルネックになったり
互いに gen_server:call してデッドロックしたり
テストは eunit, ct
中間まとめ
大規模システムではグランドデザインが超大事
ElixirConf
だった
Elixirで作った周辺システム
のご紹介
DMC gateway
DMC
旧配信
システム
DMC
gateway
同じインターフェース
Elixir で書いた
● Elixir, Erlang 初めてのエンジニア1人で3ヶ月程度
● Elixirのここが良い
○ 変数への再束縛ができるので、var1, var2, var3 と書かなくていい
○ 特別にハマることがなくerlangライブラリも利用できた
○ ExUnitによる単体テスト → DocTestができるのは結構便利
○ (漠然とした印象になるが) Erlangよりは書きやすい印象
○ RPM生成もErlangより楽かもしれない (exrm-rpmと言うドンピシャのも
のがある)
DMC gateway
DMC gateway
● 大変だったところ
○ ErlangとElixir両方を触ってるとatomや変数の書き方などで混乱する
○ パイプ演算子に手こずった
本当にあった怖い話
レビューはしてるんだけど
テストもしてるんだけど
大規模運用してると
いろんなことが
あるんだなぁ
み○を
binaryがGCされない
リリース前の性能試験中に ErlangVM が OOM Killer で殺された
erlang:garbage_collect/0 を比較的こまめに呼ぶことで解決
Shared heap Process private heap
ProcBin
Refc bin Refc bin
Refc bin Refc bin
Refc bin Refc bin
Refc bin Refc bin
Refc bin Refc bin
Refc bin Refc bin
ProcBin ProcBin ProcBin ProcBin
ProcBin ProcBin ProcBin ProcBin ProcBin
こっちは余裕なので
GCされない
容量オーバー!
1つ1つがデカい
ある機能の deploy 後、1 時間に 2GB 程度メモリリーク
もともと緩やかにリークしてたことが判明
再現コードを書いていろいろ試行錯誤した結果、
%% close/1 時に未送信データのフラッシュを行わない
inet:setopts(Socket, [{linger, {false, 0}}])
で直った
TCPセッションがリークする
動画視聴プロセスが終了
→ monitor 元に DOWN が飛ぶ
→ 動画や生放送の視聴カウンタが減る
という処理がある
稀にリモートノードの視聴プロセスが終了しても DOWN が来ず
視聴カウンタが減らないことがあった
書いたコードを良く見てみたが使い方は正しそう
monitor したプロセスが死んでも DOWN がこない
結局、そういうこともあるという前提で
monitor_with_polling
関数を書いて解決 :(
monitor したプロセスが死んでも DOWN がこない
まとめ
開発手法
開発プロセス(当初)
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
開発プロセス(当初)
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
各チームからいろんな要求が !
開発プロセス(当初)
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
各チームからいろんな要求が !
「なるはや」案件がいっぱい
開発プロセス(当初)
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
各チームからいろんな要求が !
「なるはや」案件がいっぱい
優先度がころころ変わる
開発プロセス(当初)
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
各チームからいろんな要求が !
「なるはや」案件がいっぱい
優先度がころころ変わる
口頭のやり取りでいろいろ決まる
開発プロセス(当初)
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
各チームからいろんな要求が !
「なるはや」案件がいっぱい
優先度がころころ変わる
口頭のやり取りでいろいろ決まる
隠れ要求の発覚 → 手戻り
ニコ生, ニコ動, PC, スマホ, ゲーム機, TVなど多くの関係者
各チームからいろんな要求が !
「なるはや」案件がいっぱい
優先度がころころ変わる
口頭のやり取りでいろいろ決まる
隠れ要求の発覚 → 手戻り
開発プロセス(当初)
今は余裕
開発プロセス(今)
モデル化, 自動化
なぜ余裕ができたか?
キューの様子を
他チームに公開する
なぜ余裕ができたか?
要求
要求
要求
要求
要求
開発チームが
処理
要求 要求要求
要求 要求
要求
優先度付きキュー
プロジェクトごとに状態をdocで管理
要求fix → 設計完了 → 実装完了 → 開発環境で提供 → 本番環境で提供 → 運用開始
docを見ると次にやることが分かる
docに書いてないことはやらない
プロジェクト主担当は要求分析からデプロイまで全行程をやる
→カオス度減 & スキルアップ & 楽しい !
なぜ余裕ができたか?
開発プロセス(今)
40プロジェクトのスケジュールをスクリプトで自動生成
Assign : プロジェクト情報, メンバー情報 → スケジュール
「この件はいつ着手できる予定だよ」と即答できる
ガントチャート?
自動生成された開発スケジュール
便利ツール類もちゃんと時間を取って作る
リポジトリ名
クラスタ状態把握ツール
レシピ可視化ツール
エラーログの集計ツール
便利ツール類もちゃんと時間を取って作る

More Related Content

What's hot

18166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi200918166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi2009Muhammad Ali
 
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜UnityTechnologiesJapan002
 
Polyphony の並列化
Polyphony の並列化Polyphony の並列化
Polyphony の並列化ryos36
 
Try new transport protocol SRT (ver. 2)
Try new transport protocol SRT  (ver. 2)Try new transport protocol SRT  (ver. 2)
Try new transport protocol SRT (ver. 2)Tetsuyuki Kobayashi
 
【20211202_toranoana.deno#3】denoでFFI
【20211202_toranoana.deno#3】denoでFFI【20211202_toranoana.deno#3】denoでFFI
【20211202_toranoana.deno#3】denoでFFI虎の穴 開発室
 
【20220120 toranoana.deno#4】denoでffiの続き
【20220120 toranoana.deno#4】denoでffiの続き【20220120 toranoana.deno#4】denoでffiの続き
【20220120 toranoana.deno#4】denoでffiの続き虎の穴 開発室
 
Polyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAPolyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAryos36
 
関数型言語ElixirのIoTシステムへの導入に向けた基礎評価
関数型言語ElixirのIoTシステムへの導入に向けた基礎評価関数型言語ElixirのIoTシステムへの導入に向けた基礎評価
関数型言語ElixirのIoTシステムへの導入に向けた基礎評価Hideki Takase
 
Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性
Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性
Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性Yamamoto Reki
 
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようPythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようShinya Takamaeda-Y
 
ライブストリーミング低遅延化の取り組み @ DeNA
ライブストリーミング低遅延化の取り組み @ DeNAライブストリーミング低遅延化の取り組み @ DeNA
ライブストリーミング低遅延化の取り組み @ DeNAakirahiguchi
 
ドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkinsドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkinsGo Sueyoshi (a.k.a sue445)
 
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPCZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPCYoshifumi Kawai
 
Pry による repl 駆動開発について
Pry による repl 駆動開発についてPry による repl 駆動開発について
Pry による repl 駆動開発についてTomoya Kawanishi
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと信之 岩永
 
Polyphony IO まとめ
Polyphony IO まとめPolyphony IO まとめ
Polyphony IO まとめryos36
 
Perl/CGI 入門
Perl/CGI 入門Perl/CGI 入門
Perl/CGI 入門keroyonn
 

What's hot (20)

18166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi200918166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi2009
 
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
 
Polyphony の並列化
Polyphony の並列化Polyphony の並列化
Polyphony の並列化
 
Try new transport protocol SRT (ver. 2)
Try new transport protocol SRT  (ver. 2)Try new transport protocol SRT  (ver. 2)
Try new transport protocol SRT (ver. 2)
 
【20211202_toranoana.deno#3】denoでFFI
【20211202_toranoana.deno#3】denoでFFI【20211202_toranoana.deno#3】denoでFFI
【20211202_toranoana.deno#3】denoでFFI
 
【20220120 toranoana.deno#4】denoでffiの続き
【20220120 toranoana.deno#4】denoでffiの続き【20220120 toranoana.deno#4】denoでffiの続き
【20220120 toranoana.deno#4】denoでffiの続き
 
Polyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAPolyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGA
 
関数型言語ElixirのIoTシステムへの導入に向けた基礎評価
関数型言語ElixirのIoTシステムへの導入に向けた基礎評価関数型言語ElixirのIoTシステムへの導入に向けた基礎評価
関数型言語ElixirのIoTシステムへの導入に向けた基礎評価
 
Inside FastEnum
Inside FastEnumInside FastEnum
Inside FastEnum
 
Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性
Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性
Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性
 
Rust-DPDK
Rust-DPDKRust-DPDK
Rust-DPDK
 
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようPythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
 
ライブストリーミング低遅延化の取り組み @ DeNA
ライブストリーミング低遅延化の取り組み @ DeNAライブストリーミング低遅延化の取り組み @ DeNA
ライブストリーミング低遅延化の取り組み @ DeNA
 
ドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkinsドリコムを支える課金ライブラリを支えるJenkins
ドリコムを支える課金ライブラリを支えるJenkins
 
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPCZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
 
Pry による repl 駆動開発について
Pry による repl 駆動開発についてPry による repl 駆動開発について
Pry による repl 駆動開発について
 
ドリコムのインフラCI
ドリコムのインフラCIドリコムのインフラCI
ドリコムのインフラCI
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 
Polyphony IO まとめ
Polyphony IO まとめPolyphony IO まとめ
Polyphony IO まとめ
 
Perl/CGI 入門
Perl/CGI 入門Perl/CGI 入門
Perl/CGI 入門
 

Similar to ニコニコを支える Erlang / Elixir

Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコムResemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコムGo Sueyoshi (a.k.a sue445)
 
runC概要と使い方
runC概要と使い方runC概要と使い方
runC概要と使い方Yuji Oshima
 
2011年10月21日
2011年10月21日2011年10月21日
2011年10月21日nukaemon
 
こんな辛いテストはいやだ
こんな辛いテストはいやだ こんな辛いテストはいやだ
こんな辛いテストはいやだ Takuya Mikami
 
Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)
Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)
Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)NTT DATA Technology & Innovation
 
griffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jgguggriffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jggugkimukou_26 Kimukou
 
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜	【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜 虎の穴 開発室
 
20130316 プログラミング言語Go
20130316 プログラミング言語Go20130316 プログラミング言語Go
20130316 プログラミング言語GoYoshifumi Yamaguchi
 
DLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングDLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングterurou
 
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築gree_tech
 
Opa - Cloud Language
Opa - Cloud LanguageOpa - Cloud Language
Opa - Cloud LanguageTozo Tanaka
 
ICSをビルドしてみた
ICSをビルドしてみたICSをビルドしてみた
ICSをビルドしてみたkinneko
 
Linux daemonとsupervisordの美味しい関係
Linux daemonとsupervisordの美味しい関係Linux daemonとsupervisordの美味しい関係
Linux daemonとsupervisordの美味しい関係Kazushige TAKEUCHI
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)Yoshifumi Yamaguchi
 
静的サイトどこにする?
静的サイトどこにする?静的サイトどこにする?
静的サイトどこにする?ogawatti
 
OCaml でデータ分析
OCaml でデータ分析OCaml でデータ分析
OCaml でデータ分析Akinori Abe
 

Similar to ニコニコを支える Erlang / Elixir (20)

ドリコムJenkins勉強会資料
ドリコムJenkins勉強会資料ドリコムJenkins勉強会資料
ドリコムJenkins勉強会資料
 
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコムResemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
 
runC概要と使い方
runC概要と使い方runC概要と使い方
runC概要と使い方
 
らくちん Go言語
らくちん Go言語らくちん Go言語
らくちん Go言語
 
2011年10月21日
2011年10月21日2011年10月21日
2011年10月21日
 
こんな辛いテストはいやだ
こんな辛いテストはいやだ こんな辛いテストはいやだ
こんな辛いテストはいやだ
 
Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)
Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)
Kubernetes 基盤における非機能試験の deepdive(Kubernetes Novice Tokyo #17 発表資料)
 
Runtime c++editing
Runtime c++editingRuntime c++editing
Runtime c++editing
 
griffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jgguggriffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jggug
 
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜	【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
 
20130316 プログラミング言語Go
20130316 プログラミング言語Go20130316 プログラミング言語Go
20130316 プログラミング言語Go
 
DLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングDLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミング
 
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
Docker と ECS と WebSocket で最強のマルチプレイ・ゲームサーバを構築
 
Opa - Cloud Language
Opa - Cloud LanguageOpa - Cloud Language
Opa - Cloud Language
 
ICSをビルドしてみた
ICSをビルドしてみたICSをビルドしてみた
ICSをビルドしてみた
 
Linux daemonとsupervisordの美味しい関係
Linux daemonとsupervisordの美味しい関係Linux daemonとsupervisordの美味しい関係
Linux daemonとsupervisordの美味しい関係
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)
 
静的サイトどこにする?
静的サイトどこにする?静的サイトどこにする?
静的サイトどこにする?
 
OCaml でデータ分析
OCaml でデータ分析OCaml でデータ分析
OCaml でデータ分析
 
ゆるかわPhp
ゆるかわPhpゆるかわPhp
ゆるかわPhp
 

ニコニコを支える Erlang / Elixir