Upgrade to Pro — share decks privately, control downloads, hide ads and more …

mod_mruby: スクリプト言語で高速かつ省メモリに拡張可能なWebサーバの機能拡張支援機構

mod_mruby: スクリプト言語で高速かつ省メモリに拡張可能なWebサーバの機能拡張支援機構

MATSUMOTO Ryosuke

December 20, 2013
Tweet

More Decks by MATSUMOTO Ryosuke

Other Decks in Technology

Transcript

  1. 目次 1.  本研究の概要   2.  従来のWebサーバの機能拡張   3.  提案するアーキテクチャ  

    4.  アーキテクチャの実装   5.  パフォーマンス評価   6.  まとめ   2
  2. 研究の背景 •  Webサービスの大規模・複雑化   –  Webサービスの無料・低価格化に伴う普及   –  スマートフォンからサービスを利用する機会の増加  

    –  Webサーバへのアクセス数が日々増加   •  Webサービスの低価格化と安定性向上が課題   –  セキュリティやリソースの管理の効率化   –  サービスの運用・管理コストの低減   –  サービス形態によってWebサーバの機能を最適化   4
  3. Webサーバの機能拡張 •  Webコンテンツでは難しい処理を実現可能   –  Webコンテンツ処理前後に処理を差し込む   –  効率の良いアクセス制御やリソース制御を実現  

    –  Webサービスの運用・管理を効率化   •  従来のWebサーバの機能拡張手法   –  C言語による実装が定番   •  高速かつ省メモリ ⇔  保守性や生産性が低い   –  スクリプト言語による実装   •  保守性や生産性が高い ⇔ 低性能・安全性の問題   5
  4. 本研究 •  スクリプトで高速・省メモリにWebサーバを拡張   –  従来手法の目的やアーキテクチャを整理して考察   –  Webサーバプロセスへのインタプリタ組込みを最適化  

    –  性能面と安全性を両立したアーキテクチャの設計   –  サーバプロセスを再起動する事なく機能拡張の変更が可能   –  複数の異なるWebサーバの振る舞いを共通のDSLで記述   6
  5. Webサーバの機能拡張の目的(1) 1.動的コンテンツの高速処理を主な目的   •  レスポンス生成をいかに効率よくするか   •  CGIはforkのコストが大きい   • 

    手法の分類   •  インタプリタを直接サーバプロセスに組込む   •  mod_php、mod_perl、mod_ruby  …   •  インタプリタやCGIプロセスを事前に起動   •  FastCGI、Java  Servlet、Ruby  On  Rails  …   8
  6. Webサーバの機能拡張の目的(2) 2.レスポンス生成以外の内部処理が主な目的   •  本研究のスコープ   •  アクセス制御やリソース管理等   • 

    Webサーバそのものの振る舞いを定義   •  高速・省メモリを重視してC言語による実装が主流   •  Apacheモジュール、nginxモジュール …   •  生産性・保守性を重視してスクリプトによる実装   •  mod_lua、mod_perl、mod_ruby  …   •  サーバプロセスへのインタプリタ組込み方式の違い   •  インタプリタ共有方式(mod_perl・mod_ruby等)   •  複数インタプリタ方式(mod_lua)     9
  7. サーバプロセスへのインタプリタ組み込み方式 1.  インタプリタ共有方式(mod_perl、mod_ruby等)   –  サーバプロセス起動時に単一のインタプリタを確保   –  インタプリタを複数のスクリプトで共有して実行  

    –  グローバルな状態(グローバル変数やクラス)を共有   –  高機能でコストの高いインタプリタを採用する場合に最適   2.  複数インタプリタ方式(mod_lua)   –  スクリプト実行単位でインタプリタを確保   –  グローバルな状態は独立   –  インタプリタが確保するメモリも都度開放して省メモリ   –  低機能で高速・省メモリな組込みスクリプト言語が最適   10
  8. 従来のスクリプトによる機能拡張 従来の機能 拡張   mod_perl   mod_ruby mod_lua   言語

    C Perl   Ruby   Lua インタプリタ   初期化処理 ** 事前 都度 ライブラリ   読み込み ** 事前 都度 コンパイル 事前 都度 都度 コードの変更 不可 可 可 グローバル状態 共有 共有 非共有 11
  9. 従来のアーキテクチャの課題 •  インタプリタ共有方式は安全性に課題   –  性能面では効率の良い組込み方式   –  グローバル状態が複数スクリプトで干渉  

    –  インタプリタの確保するメモリの増加   •  複数インタプリタ方式はオーバーヘッドが大きい   –  組込みスクリプト言語自体の軽量・高速処理の恩恵   –  インタプリタ確保・開放のコストが高い   –  依然としてC言語による実装より性能が低い   •  これらの利点を両立できないか?   13
  10. 複数インタプリタ方式のオーバーヘッド 状態遷移保存領域の確保   ライブラリ読み込み   構文木解析   バイトコード生成   VM上で実行

      リクエスト処理時にサーバプロセスからスクリプトがフック   スクリプト読み込み   •  速度面でボトルネック   •  省メモリが可能   •  グローバル状態が独立 状態遷移保存領域を開放   •  状態遷移保存領域   インタプリタがスクリプト を実行するために必要な 情報を保存しておく領域 14
  11. 提案するアーキテクチャ概要 •  高速性   –  性能が要求される状況では複数スクリプトでインタプリタを共有   –  リクエスト毎に実行されるスクリプトはインタプリタを共有  

    –  リクエスト毎に実行されない場面では個別にインタプリタを確保   •  省メモリ   –  メモリ増大の原因となるバイトコードのみを開放   •  安全に拡張機能の実装が可能   –  グローバル変数・クラス・例外フラグのみを開放   –  サーバプロセスの再起動なく変更を反映   •  組込みスクリプト言語を採用   –  コンテンツ実装が目的ではないので多機能は不要   –  基本機能から機能を取り外し可能なスクリプト言語   –  実行される状況に合わせて複数のインタプリタを確保   15
  12. 提案するアーキテクチャ概要 16 呍 呍 呍 親サーバプロセス   子サーバプロセスA   リクエスト処理用インタプリタ

    起動時処理用インタプリタ リクエスト以外の処理用インタプリタ 子サーバプロセスB   リクエスト処理用インタプリタ 起動時処理用インタプリタ リクエスト以外の処理用インタプリタ スクリプト スクリプト スクリプト スクリプト スクリプト
  13. 提案するアーキテクチャの処理(通常) 構文木解析   バイトコード生成   VM上で実行   リクエスト処理時にサーバプロセスからスクリプトがフック   スクリプト読み込み

      状態遷移保存領域   とライブラリを共有 バイトコード、グローバル変数・クラス、例外フラグを開放   •  状態遷移保存領域   インタプリタがスクリプト を実行するために必要な 情報を保存しておく領域 •  サーバプロセス起動時 にインタプリタを確保   •  複数のスクリプトで同一 のインタプリタを再利用 17 排他処理   マルチスレッドWebサー バアーキテクチャに対応
  14. 提案するアーキテクチャの処理(キャッシュ) 構文木解析   バイトコード生成   VM上で実行   リクエスト処理時にサーバプロセスからスクリプトがフック   スクリプト読み込み

      状態遷移保存領域   とライブラリを共有 グローバル変数・クラス、例外フラグを開放   •  バイトコードをキャッシュ しておく事も可能   1.  サーバプロセス起動時 にコンパイル   2.  バイトコードテーブルに 保存   3.  バイトコードIDから取り 出し 18 バイトコードテーブル  
  15. アーキテクチャの実装 •  インタプリタ   – mruby   – C言語と親和性の高い組込みスクリプト言語   •  Webサーバソフトウェア

      – Apache  hSpd   – nginx   •  mod_mruby(+  ngx_mruby)と命名   – 今回はmod_mrubyを対象に実装を紹介   20
  16. mrubyの特徴 •  組み込みスクリプト言語mruby   1.  組込み機器を考慮してリアルタイム性を向上   2.  Rubyの最小限の機能でメモリフットプリントが軽量  

    3.  モジュールやクラス、メソッドの細かい取り外しが可能   4.  RubyのISO規格を尊重して設計   5.  C言語と親和性の高い組み込みAPI   6.  C99に準拠した記述で実装されており高い移植性   Webコンテンツ技術者がRubyの延長で扱える   生産性・保守性と高速・軽量性の両立に最適   21
  17. mod_mrubyの実装 •  特徴   –  インタプリタを共有する事で高速・省メモリに動作   –  スクリプト間でグローバル変数やクラスの干渉を防止  

    –  Webサーバの振る舞いをRuby  DSLで容易に記述可能   –  Apacheをリスタートする事なく変更可能(キャッシュも可能)   •  出来ることの例   –  オリジナルのリバースプロキシ(20行程度)   –  複雑な条件によるリダイレクト   –  サーバの負荷によって処理を変更   –  Apacheの内部情報を利用したアクセス制御   –  管理者が自由にリソース制御をDSLで記述可能   22
  18. Apache  hSpd  設定例 LoadModule  mruby_module  modules/mod_mruby.so     #  handler

     middleフェーズでtest.rbをコンパイルして実行   <LocaZon  /mruby-­‐test>          mrubyHandlerMiddle  /path/to/test.rb   </LocaZon>     # サーバプロセス起動時にtest.rbをバイトコードにコンパイル   # しておいてhandler  middleフェーズでバイトコードを実行   <LocaZon  /mruby-­‐test-­‐cache>          mrubyHandlerMiddle  /path/to/test.rb  cache   </LocaZon> 23
  19. リソース制御の応用例[1] 28 r = Apache::Request.new! ! if r.user == “matsumoto_r”!

    cpu = Cgroup::CPU.new “cpu_group”! ! # CPUを10%に制御したい場合! cpu.cfs_quota_us = 10000! cpu.create ! cpu.attach! end [1]松本亮介,  岡部寿男,  リクエスト単位で仮想的にコンピュータリソースを分離するWebサーバのリソース制御 アーキテクチャ,  情報処理学会研究報告 Vol.2013-­‐IOT-­‐23,  No.4,  2013年9月.
  20. mod_mrubyとngx_mruby •  できるだけ同じ記述で拡張できるように設計   •  Webサーバの実装の違いをmruby  DSLで吸収   •  Rubyのアプリケーション開発者が開発の延長でWebサーバ

    の機能拡張も行える   Apache   API mruby  script  1   mod_mruby mruby  script  2   呍 呍 呍 呍 mruby  script  n   Nginx   API ngx_mruby mruby  script  3 Apache   Core Nginx   Core mruby   DSL   for  Web 29
  21. 同一の実装例 if  server_name  ==  “NGINX”    Server  =  Nginx  

    elsif  server_name  ==  “Apache”    Server  =  Apache   end   Server::rputs  “Hello  #{Server::module_name}  World!”   #  mod_mruby  =>  "Hello  mod_mruby  world!"   #  ngx_mruby  =>  "Hello  ngx_mruby  world!"     30
  22. 実験 クライアント CPU Intel  Core2Duo  E8400  3.00GHz Memory 4GB NIC

    Realtek  RTL8111/8168B  1Gbps OS CentOS  5.6 Webサーバ CPU Intel  Xeon  X5355  2.66GHz Memory 8GB NIC Broadcom  BCM5708  1Gbps OS CentOS  5.6 Middle  Ware Apache  2.2 1.  メモリ量の評価   2.  クライアントからWebサーバにアクセスして処理性能を評価   •  どのURLにアクセスしても“Hello  World”出力する内部機能   •  同時接続数100総接続数10万アクセスで評価   •  サーバプロセスの生成破棄が発生しないようにチューニング   32
  23. 0   5000   10000   15000   20000  

    25000   0   10000   20000   30000   40000   50000   apache  process  memory  usage[kb] Total  Requests バイトコード開放無し バイトコード開放 実験結果1 メモリ増加量 33 ※mod_mruby組込み前のサーバプロセスは4400Kb、mod_mrubyを組込む事で600Kb増加
  24. 実験結果2 速度比較 mod_hello   mod_perl   mod_ruby   mod_lua   mod_mruby

      言語 C Perl   ruby   Lua mruby 初期化処理 ** 事前 都度 事前 ライブラリ   読み込み ** 事前 都度 事前 コンパイル 事前 都度 都度 都度   コードの変更 不可 可 可 可 グローバル変数 共有 共有 非共有 非共有 性能   (Response/sec) 9861.17   3346.38 4769.04 5209.11 9021.54   (※9752.37) 34 ※ バイトコードをキャッシュした場合(コードの変更は不可)
  25. まとめ •  まとめ   –  スクリプト言語による高速かつ省メモリなWebサーバ機能拡張 アーキテクチャを提案   –  従来手法の目的やアーキテクチャを整理して考察

      –  Webサーバプロセスへのインタプリタ組込みを最適化   –  性能面と安全性を両立したアーキテクチャの設計   –  Webサーバにおける単純なHelloWorld出力の機能拡張処理で あればC言語と遜色ない性能   –  C言語による拡張実装とも両立が可能   •  今後の課題   –  実用的な機能拡張(リバースプロキシ等)による性能比較   36