Upload
tsunenori-oohara
View
9.258
Download
2
Embed Size (px)
Citation preview
Drecom @ohrdev
地獄のElixir入門
自己紹介• 自分 大原常徳 ( エロスマ ) @ohrdevドリコム広告事業部入社 4 年目• 仕事 動画広告周りのシステムの開発 / メンテ• 生活・趣味
– お寺巡り、写経、仏像彫り– 丸太・流木探し(仏像用)– 週末は光の戦士 ( 白魔導士 Lv.50)– ダイエット– エロい広告バナー画像収集
• エロいカリスマ -> エロスマ
今日のお話 ( 3行で )
ElixirっていうErlangの上で動く言語の紹介するよ
Agenda• 言語の紹介
– Erlang/Elixir の紹介– エコシステムについて– 環境構築
• 弊社広告事業部での使われ方– 利用モジュール– サービスの構成
• 所感– 良い / 悪い所– ハマった所
• まとめ
Erlang の紹介• 平行処理指向のプログラミング言語• 分散化された環境• 障害耐性 ( フォルトトレラント )• ( ある程度の ) リアルタイム性• 無停止稼動 ( ホットスワップ )• ActorModel(Shared Nothing Artchitecture)• OTP(Open Telecom Platform)• 超軽量プロセス / メッセージング• GC はプロセスレベルで実行• Prolog チックな syntax• Immutable な変数• 単一代入変数 ( 1回しか値を代入できない )• パターンマッチを多用 ( メッセージパッシングでは特に )
Erlang の紹介 - ざっくりネットワークサーバーの DSL( と考えるとしっくり )OTP を使わなければ使う意味がなさそう無停止更新は大変、面倒くさいエコシステムはそれなりに整っている関数型脳というよりアクターモデル脳1 回しか変数に値を代入できない制御構造はパターンマッチ・再帰・ガードで表現
Erlang 分散アーキ (VM)
スケジューラー
------------------------------
CPU 数のスレッドVM
実行キュー( プロセス )
VM がいい感じにマイグレーションする(最適化 )
Ex)キュー数が多いスレッドから少ないスレッドへ、キューを移動
Erlang 分散アーキ (m-process)
Erlang 分散アーキ (cluster 、 s/w)
OS
VM
BEAM-files BEAM-filesBEAM-filesBEAM-files
s
s s s w w
s
w w
w w w s s
www
OSOS OS
VM VM VM
SupervisorWorker を監視
Worker処理を実行- 再起動戦略- 再起動頻度
- 子プロセスの起動方法プロセスメモリ :300word 〜起動 :micro sec 単位上限 :2.6 億程度
プロセス Tree
プロセス
----------------------------------------(FIFO)
プロセス1
プロセス2
メールボックスメッセージPID2 ! msg.
my_m:my_f( Arg1,…) の処理内容
receive
PID2 = spawn(my_m, my_f, [Arg1,…]).
spawn
-modle(my_mod).
my_f(Arg1,Arg2,…) -> receive msg -> do_something end.
プロセス0
OTP• Open Telecom Platform• アプリケーション作成に役立つ標準モジュール・ライブラリ・原則集• Erlang の基本機能 (Link/Monitor/Timeout/Exit/etc) を使って並行アプリケーションを書く際のパターン• 代表的なビヘイビア ( パターン )
– プロセス同士の共通パターン / 振る舞いを形式化したもの– gen_server ビヘイビア : クライアント / サーバー– gen_fsm ビヘイビア : 有限ステートマシン– gen_event ビヘイビア : イベントハンドリング– supervisor ビヘイビア : supervisor-worker のプロセス監視ツリー– application ビヘイビア : 複数モジュールからなるアドホックなアプリケーション– Etc
• OTP を使う為に Erlang を使う
Elixir の紹介• Jose Valim(RailsCoreTeam/devise/etc) によって開発• Erlang の仮想環境 (BEAM) 上で動作する汎用 script 言語• Erlang の関数をシームレスに call できる• Erlang の AST を操作できる (LISP のマクロ ) 、メタプログラミング• Protocol によるポリモーフィズム (Clojure の defprotocol)• 言語レベル (FirstClassDocument) でドキュメントをサポート• Erlang の ActorModel(Shared Nothing Artchitecture)• パターンマッチ• OTP(Open Telecom Platform) を bundle• Ruby チックな syntax
Elixir の紹介 - ざっくりErlang を Ruby チックにかける!変数への値の代入は何回でもできるLisp のマクロ (AST を直接操作 ) 使えるErlang<->Elixir のオーバーヘッド (ほぼ ) なし(天真爛漫に Erlang の module を call できる )モダン
Erlang のコンパイルソースコード
xxx.erl文字列 Token AST
erl_scan erl_parse
実行ファイルxxx.beam
compile
VM に load& 実行
erl_eval
Elixir のコンパイルソースコード
xxx.exElixir AST Erlang AST
実行ファイルxxx.beam
compile
VM に load& 実行
erl_eval
AST レベルで変換 オーバーヘッドなし
Elixir の OTP アプリケーションで実現
シームレスにerlang のコードを
call できる
エコシステム• ライブラリの hosting 、配布フォーマット
– Ruby -> rubygems ( https://rubygems.org )– Elixir/Erlang -> hex ( https://hex.pm )
• 統合 Buildツール– Ruby -> rake– Elixir -> mix– Erlang -> rebar (http://qiita.com/ohr486/items/b33cfcf0978ec51afc63 )
• WebAppFW– Ruby -> Rails– Elixir -> Phoenix (https://github.com/phoenixframework/phoenix )
環境構築• Erlang の環境が必要
– Erlang のバージョン管理ツール : kerl– http://qiita.com/ohr486/items/3a5229bcdf9c4d5fbfe6
• Mac– brew install erlang; brew install elixir
• Win– スイマセンやった事無いです・・・
• *nix– Ansible の role 作りました
• https://galaxy.ansible.com/list#/roles/2930• https://github.com/ohr486/ansible-elixir
弊社広告事業部の事例• 動画広告ネットワークサービスで採用• API サーバーを Elixir で実装
– 大量のリクエストをさばける API サーバーが欲しかった– http://qiita.com/ohr486/items/a6bf071f1fe26f5108ab
• (管理、広告掲載サイトは Rails )• API サーバーから RDB へのアクセスは無し、全て Redis(Dynamo) から取得• 非同期処理は Sidekiq を利用
– Elixir から、 Rails の Sidekiq へ enqueue– Sidekiq互換 (Sidekiq の Elixir 実装 ) の exq を利用
適用箇所
API serverElixir App
管理系system(RoR)
redis
Job Server(Sidekiq)
redis
MySQL
enqueue
nginx
LB
GoogleBigQuery
利用モジュール• Web(http):cowboy (erlang のデファクトモジュール )• WSGI(相当のもの ):plug (ruby の rack)• API DSL:maru (grape の elixir 実装 )• Json:poison• SentryClient:raven-elixir• Job:exq (sidekiq の elixir 実装 )• AwsLib:erlclud (ErlangLib)• Coverage:coverex• Dotenv:dotenv• RedisDriver:exredis• ReleaseManager:exrm• PackageManager:hex• etc
所感• Erlang 周りのエコシステムをある程度把握しておくと捗る• OTP ありきで考えた方が良い• アクターモデル脳大事• 腹をくくって英語のドキュメントを読む
良い所• Erlang の資産を利用できる• Erlang のエコシステムに乗っかれる• OTP がクソ便利、 Elixir バンドルの OTPも大体が揃っている
– 揃ってなければ Erlang のモジュールとして call すれば良い• メタプログラミングできる
– Phoenix(Rails インスパイアされた WAF) のコードがかなり参考になる
悪い所• ( 日本語の ) ドキュメントが弱い、コミュニティが少ない• 採用事例が少ない ( ので採用ハードルが高い、上司説得工数が高い )• Ruby 程ライブラリ数が多く無い (粒は揃ってる )• Erlang 周りの情報もアンテナをはる必要がある (Erlang 実装に影響される )• 足回りが整備されきっていない( deploy/log/update/monitor/etc )• チューニングするには Erlang の知識が必要
ハマった所• デプロイ
– mina を採用– ベストプラクティスがまだ無い、 Phoenix 周りの情報が参考になりそう
• 監視系– Erlang/Elixir 標準のロガーは今ひとつ使い辛い
• モジュール使うなら lagerだけど、 too muchだった• Plug の middleware に埋め込む
– Newrelic 使いたい(のでなんとかしている所)• Newrelic の native(C++)SDK を erlang の組み込みモジュールとして実装• Elixir から呼び出し
– Nginx をかまして req/res 監視する• ホットコードスワップ ( 無停止更新 )
– 苦労の割に報われない感があった• デプロイで工夫するようにした
まとめ• 弊社広告事業部では Elixir を広告配信 API サーバーで採用しています• 言語もですが、バンドルされている OTP が強力です
– ネットワークサーバーを書く為の DSL と考えるとしっくりきます• まだ採用事例は多くありませんが、今後トレンドになるのでは• マルチプロセッサマシンに相性が良い、スケールがし易い• アクターモデルのパラダイムで考える必要がある
– 何も考えずに作ると性能が出ないので注意
最後に
落ち込んだり(地獄 )するけど
私達元気(天国 )です
ドリコム広告事業部はアドテク好きなエンジニアを募集しています。http://www.drecom.co.jp/recruit/
[PR]