[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
SlideShare a Scribd company logo
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
Supervisor
Workerを監視
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.ex
Elixir 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 server
Elixir App
管理系
system(RoR)
redi
s
Job Server
(Sidekiq)
redi
s
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]

More Related Content

地獄のElixir(目黒スタートアップ勉強会)

Editor's Notes

  1. プロセスの他言語との比較 Golang: メモリ:8k byte、上限:数十万、管理:しない Erlang: メモリ:300word=240 byte、管理:treeを作る Scala: メモリ:数百byte、スレッド256〜 プロセス間でメモリは強要しないSharedNothingArchitecture(golangは仕組みあり)
  2. Erlangのメールボックスは、FirstInFirstOut Scalaはこのキューを制御可能(うらやましい)