Location via proxy:
[ UP ]
[Report a bug]
[Manage cookies]
No cookies
No scripts
No ads
No referrer
Show this form
Submit Search
elixir in production
•
Download as PPTX, PDF
•
18 likes
•
6,978 views
Tsunenori Oohara
Elixir Meetup #1 in Drecom
Read less
Read more
1 of 38
Download now
Downloaded 12 times
More Related Content
elixir in production
1.
Elixir in Production Elixir Meetup
#1 in Drecom
2.
Agenda • 発表の趣旨 • 自己紹介 –
最近のElixir事情 • 運用システム構成 – 利用しているツール/ライブラリ群 • 運用(負荷テスト)時のトラブル(とその地雷処理) – 事例1.ログ – 事例2.コネクションプール – 事例3.アセット – その他 • まとめ
3.
発表の趣旨 • 本番運用事例の紹介をする事で – 本番採用事例が増える一助に –
採用ハードルが少しでも低く • 本番運用時のトラブル対応の紹介をする事で – あるあるの事例と思うので、知見共有する事で同 様のトラブル回避の手助けに なったら良いなと思います
4.
自己紹介 • おーはら(@ohrdev) • 写経(仏教的)/仏像彫り/寺社仏閣 •
広告エンジニア(Drecom) – Erlang/Elixir/Phoenix – Ruby/Rails – (Lisp/Scala)
5.
最近のElixir事情 • コミックマーケットC89でPhoenix本発売 – アランビックの錬金術師 –
http://hayabusa333.tumblr.com/ – BOOTH: https://hayabusa333.booth.pm/items/186705 • Elixir 1.2 released – https://github.com/elixir- lang/elixir/blob/v1.2.0/CHANGELOG.md
6.
最近のElixir事情 • Programming Elixir
1.2 (Dave Thomas) – https://pragprog.com/book/elixir12/programming -elixir-1-2 – Β版 • Programming Phoenix – https://pragprog.com/book/phoenix/programmin g-phoenix – Β版
7.
運用システム構成 • 広告配信API/ミニコンテンツ(ゲーム) – F/W:
maru( WAF/API DSL ) / Phoenix( WAF ) – DB: Redis( exredis + poolboy ) / Dynamo( ex_aws ) – Job: exq( + Sidekiq ) – 環境変数: dotenv – Deploy: exrm / mina / asset_sync(自製) – テスト: meck / power_assert – 監視: sentry( raven-elixir ) / monit / 社内監視tool – プロビジョニング: ansible( 自製galaxy-role ) – インフラ: AWS( EC2 / AutoScaling / ELB / S3 / CF )
8.
利用ツール/ライブラリ • WAF: – maru:
https://maru.readme.io/ • 特徴: – シンプル/Api DSL(grape like) • 出来ない事: – セッション管理/DBコネクション/テンプレート描画 – Phoenix: http://www.phoenixframework.org/ • 特徴: – フルスタック(一通り揃ってる)/maruに比べると複雑 – アセットコンパイルはbrunch.ioを採用(node/npmが必要)
9.
利用ツール/ライブラリ • DB: – Redis: •
exredis: https://github.com/artemeff/exredis • poolboy: https://github.com/devinus/poolboy – Dynamodb: • ex_aws: https://github.com/CargoSense/ex_aws – MySQL/PostgreSQL/Mongodb/etc • 弊社サービスでは採用していないのですが、恐らく ecto: https://github.com/elixir-lang/ecto 一択
10.
利用ツール/ライブラリ • Job: – exq:
https://github.com/akira/exq (+ sidekiq) – http://qiita.com/ohr486/items/9db88866786ee8b b89d9 • 環境変数: – dotenv: https://github.com/avdi/dotenv_elixir
11.
利用ツール/ライブラリ • エラー監視(sentry): – raven-elixir: https://github.com/vishnevskiy/raven-elixir
12.
利用ツール/ライブラリ • 死活監視/自動再起動 – monit •
DB/ミドルウェア/外部サービスの監視 – supervisor(OTP) • 言語の一部(OTP)として提供される • きちんとチューニング/設定しておくと安心できる – 半年の本番運用で2回程お世話になった – パラメータの設定不備でプロセスが死亡する事象が発生した が、自動的にプロセスを監視/再起動して、サービスを落す事 なく復旧/修正まで凌げた
13.
利用ツール/ライブラリ • プロビジョニング: – ansible
+ galaxy-role: https://galaxy.ansible.com/detail#/role/2930 – Erlang/Elixir/Phoenix のバージョンupの頻度はか なり早いので、自動化しておくべき – ErlangとElixirのバージョンの相性がある為、両方 のバージョンを指定できると捗る
14.
運用(負荷テスト)時のトラブル • Elixirの開発/本番運用を約1年程やってきて、 地雷はそれなりに踏み抜いてきました • 今回は特に –
開発時には発見し辛く、負荷テスト/本番運用時 に現れる – サービス規模/トラフィックがある程度大きくなるま で現れない といった事例をピックアップしています
15.
事例1.ログ • 事象:大したリクエスト数でもないのに、iowait が高まりLA /
CPU使用率が上昇
16.
事例1.ログ • 検証: – サンプル http://github.com/falood/maru_examples –
abで負荷をかけて計測(echo_server) $ ab -n 10000000 -c 2 http://xxx.xxx.xxx.xxx:8800/ $ vmstat -a 1
17.
事例1.ログ • 検証: – vmstatの結果:
boが異常値 $ vmstat -a 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free inact active si so bi bo in cs us sy id wa st 2 0 0 6807288 45796 562724 0 0 21 1242 11712 5338 37 25 30 8 0 1 1 0 6807156 45796 562988 0 0 0 4528 28259 5784 15 15 51 20 0 1 1 0 6806908 45800 563184 0 0 0 4484 28252 5717 15 16 50 20 0 0 1 0 6806660 45796 563384 0 0 0 4548 28171 5843 15 16 50 19 0 2 0 0 6806412 45796 563584 0 0 0 4556 28003 5825 15 15 51 20 0 1 1 0 6806288 45796 563780 0 0 0 4484 28262 5787 15 16 50 20 0 1 1 0 6806040 45796 563984 0 0 0 4488 28604 5868 14 17 50 19 0 2 1 0 6805792 45796 564180 0 0 0 4472 28473 5888 13 18 50 19 0 1 1 0 6805668 45800 564384 0 0 0 4480 28193 5772 15 16 50 19 0 1 1 0 6805420 45796 564580 0 0 0 4472 28356 5746 14 17 50 20 0 2 0 0 6805420 45796 564784 0 0 0 4492 28445 5757 14 16 50 19 0 1 1 0 6805172 45796 564980 0 0 0 4504 28393 5787 15 16 50 20 0 1 1 0 6804924 45796 565184 0 0 0 4456 28411 5671 13 17 50 20 0 2 0 0 6804676 45796 565380 0 0 0 4488 28169 5786 14 15 51 20 0 1 1 0 6804428 45800 565576 0 0 0 4504 28053 5761 13 17 50 20 0
18.
事例1.ログ • 検証: – loggerのbackendがデフォルト(console)だと、 O_SYNCモードでログファイルがopenされる https://github.com/erlang/otp/blob/maint/erts/etc/com mon/run_erl_common.c –
naoyaさんの記事(Linux I/O のお話 write 編) http://d.hatena.ne.jp/naoya/20070523/1179938637 – 『アプリケーションがSYNCモードでファイルを開い ていたり、明示的にfsync() してたりするとそこで waitが発生するのはいわずもがな、です。』
19.
事例1.ログ • 事象:大したリクエスト数でもないのに、iowait が高まりLA /
CPU使用率が上昇 • 原因:loggerのバックエンドがデフォルトの consoleだった(為、ログファイルをO_SYNC モードで開いていた)ので、毎秒ディスクへの 同期とフラッシュが走っていた
20.
事例1.ログ • 対応 – 本番環境のloggerのbackendをconsoleから変更 –
※ ElixirのLoggerのbackendは公式にはconsoleし か提供されていない • https://github.com/elixir- lang/elixir/tree/master/lib/logger/lib/logger/backends • https://github.com/onkel-dirtus/logger_file_backend • https://github.com/basho/lager – logger_file_backendはカスタマイズに難ありだっ たのでbackendを自前実装した
21.
事例1.ログ • 教訓: – 本番環境のログのbackendは必ずfileベースのも のに変更すること –
負荷テスト時のサーバー状況のチェックは必ず実 施する事(あたりまえですが)
22.
事例2.コネクションプール • 事象:リクエストを大量に長時間なげ続け ると、ElasticCache(Redis)のコネクション数が あふれる
23.
事例2.コネクションプール • 状況: – 各種DBドライバのコネクション管理事情 •
PostgreSQL/MySQL/MSSQL/SQLite3/MongoDB – ecto: https://github.com/elixir-lang/ecto – コネクション管理(内部的にはpoolboyで実装)を含む • Redis – exredis: https://github.com/artemeff/exredis – クライアントのみ、コネクション管理は含まれない • Dynamodb – ex_aws: https://github.com/CargoSense/ex_aws – APIベースなのでコネクション管理なし – Read/Write Capacity Unitの設定で担保
24.
事例2.コネクションプール • 状況: – (コネクション管理をしていなかったので)リクエスト 毎にRedisのコネクションを確立していた –
ElasticCache(Redis)のコネクション • コネクションタイムアウト:デフォルト5分 • コネクション上限数:2万 – 開発時は、コネクション数自体が少なく、上限に いくまでにタイムアウトで切断されていたので気 がつかなかった、高負荷をかけて初めて発覚
25.
事例2.コネクションプール • 事象:リクエストを大量に長時間なげ続け ると、ElasticCache(Redis)のコネクション数が あふれる • 原因:Redisのコネクション管理をしていなかっ た/するドライバを使っていなかった
26.
事例2.コネクションプール • 対応: – コネクション管理を含むRedisドライバを使用 •
https://github.com/quarkgames/exredis_pool • https://github.com/le0pard/redis_pool • 問題点: コネクションプールの設定が貧弱/十分に チューニングできない – poolboyでコネクションプールを自前実装 • 参考: たのしいpoolboy(@hagiyatさん) • http://qiita.com/hagiyat/items/a28683d01223bfc204d 9
27.
事例2.コネクションプール • 教訓: – Redisを使う際は、コネクション管理に注意、必ず コネクション管理機構を実装する事 –
poolboyは良実装(Erlangの良いお手本コード) – 負荷テスト時のサーバー状況のチェック(ry
28.
事例3.アセット • 事象:AWSのデータ転送量の費用が増大 • 原因:EC2上にdeployしたphoenixアプリのア セット(画像/css/js/font/etc)の転送量だった
29.
事例3.アセット • Phoenixのアセットの参照: – digest:
静的ファイルを圧縮してmanifestを作成 • phoenix.digest (mixコマンド) • manifest.jsonに、圧縮前後のファイルパスのmapping をJSON形式で出力する – cache_static_manifest != true (config.exs) • 静的ファイルを priv/static 以下から参照 – cache_static_manifest == true (config.exs) • manifest.jsonをパースして、ets(ErlangのIn-memoryスト レージ)にマッピング情報をストア • 静的ファイル参照時に、圧縮後のファイルを参照させ る
30.
事例3.アセット • 改善前の手順 – 1.
アセットの参照方法をmanifestに – 2. 圧縮ファイルとmanifest.jsonを作成 • MIX_ENV=prod mix phoenix.digest – 3. MIX_ENV=prod でアプリを起動 – 4. 2.のマッピング先(圧縮後ファイル)が参照 # config/prod.exs config :my_app, MyApp.Endpoint, http: [port: xxxx], url: [host: “xxxx”], cache_static_manifest: “priv/static/manifest.json”, server: true
31.
事例3.アセット • アセット参照の実体(static_path/2) – Phoenix.Route.Helpers
# static_path/2 • https://github.com/phoenixframework/phoenix/blob/ master/lib/phoenix/router/helpers.ex – MyApp.Web # web ( web/web.ex ) • import MyApp.Router.Helpers – static_path/2 がimportされて利用可能に – View/css/javascript # static_path/2 • static_path/2 でアセットを参照
32.
事例3.アセット • アセット参照の実体(priv/static参照) – http://xxx.xxx.xxx.xxx:4000/images/hoge.png •
priv/static/images/hoge.png が参照される – http://xxx.xxx.xxx.xxx:4000/css/var.css • priv/static/css/var.css が参照される
33.
事例3.アセット • 対応: – Phoenixにはasset_sync相当のライブラリが(自分 が調べた限り採用できそうなのものが)存在しな かった –
Railsのasset_sync相当のライブラリを自前実装 • 対象ファイルのアセットファイルをs3にupload • static_path/2を、s3/cloudfrontを参照しにいく様に差換 える • アセットファイルをバージョン管理(sync/cleanup)
34.
事例3.アセット • 対応: – asset_sync(phoenix版)は、もう少し本番運用した 後、hexに公開予定 –
仮リポジトリ/参考実装(テスト/ドキュメント/残ン 実装対応中): • https://github.com/ohr486/asset_sync – 注意: • 2016/1 現在、ex_awsのs3は東京リージョンから一部機 能が利用できません • https://github.com/CargoSense/ex_aws/pull/101 の修正がhexにpublishされるまでパッチを当てるなりし て下さい
35.
事例3.アセット • 教訓: – インフラコストはちゃんと監視する事 –
Phoenix on AWSで画像を扱う際は、転送量に注 意、必要に応じてCloudFrontへ – 負荷テスト時のサーバー状況のチェック(ry
36.
その他 • 地雷処理の為にやった事/必要だった事 – ドキュメント(英語)を読む •
日本語の情報はまだまだ不足 – 実装コード(Elixir/Erlang)を読む • Erlangの参照ライブラリを読むケースはそれなりにある (ErlangのライブラリをwrapしただけのElixirライブラリ) – awesome-elixir/awesome-erlangのチェック • 他の実装ライブラリや、似た様な機能を探す際に便利、 定期的に追いかけておくと何かと捗る
37.
その他 • 地雷処理の為にやった事/必要だった事 – 地雷処理できる人を増やす活動 •
Erlangが読めるように – Elixir独自の機能はありますが、やはりベースはErlangです – ErlangをRubyのSyntaxで記述している感じ • OTPの概念を理解できるように – OTPの理解無しにElixirのアプリ運用はできない(と感じた) • 関数型言語を理解する – 社内勉強会(すごいE本/コップ本読書会) – Erlangに自信が無い場合は、時雨堂さんにコンサ ルをお願いすれば良いんじゃないでしょうか
38.
まとめ • 弊社にて運用しているElixirのサービスについ ての紹介をしました • 本番運用時に発生したトラブルとその対応を 紹介しました •
(完璧では無いですが)十分に本番で運用でき ています • まだまだ足りない機能/ライブラリがあるので、 もっと充実してきて欲しいです(自分ももっと公 開していきます)
Download