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. mod_mruby:  スクリプト言語で高速かつ省メモリ
    に拡張可能なWeb  サーバの機能拡張支援機構
    京都大学大学院 情報学研究科  
    岡部研究室 松本 亮介

    View full-size slide

  2. 目次
    1.  本研究の概要  
    2.  従来のWebサーバの機能拡張  
    3.  提案するアーキテクチャ  
    4.  アーキテクチャの実装  
    5.  パフォーマンス評価  
    6.  まとめ  
    2

    View full-size slide

  3. 本研究の概要
    3

    View full-size slide

  4. 研究の背景
    •  Webサービスの大規模・複雑化  
    –  Webサービスの無料・低価格化に伴う普及  
    –  スマートフォンからサービスを利用する機会の増加  
    –  Webサーバへのアクセス数が日々増加  
    •  Webサービスの低価格化と安定性向上が課題  
    –  セキュリティやリソースの管理の効率化  
    –  サービスの運用・管理コストの低減  
    –  サービス形態によってWebサーバの機能を最適化  
    4

    View full-size slide

  5. Webサーバの機能拡張
    •  Webコンテンツでは難しい処理を実現可能  
    –  Webコンテンツ処理前後に処理を差し込む  
    –  効率の良いアクセス制御やリソース制御を実現  
    –  Webサービスの運用・管理を効率化  
    •  従来のWebサーバの機能拡張手法  
    –  C言語による実装が定番  
    •  高速かつ省メモリ ⇔  保守性や生産性が低い  
    –  スクリプト言語による実装  
    •  保守性や生産性が高い ⇔ 低性能・安全性の問題  
    5

    View full-size slide

  6. 本研究
    •  スクリプトで高速・省メモリにWebサーバを拡張  
    –  従来手法の目的やアーキテクチャを整理して考察  
    –  Webサーバプロセスへのインタプリタ組込みを最適化  
    –  性能面と安全性を両立したアーキテクチャの設計  
    –  サーバプロセスを再起動する事なく機能拡張の変更が可能  
    –  複数の異なるWebサーバの振る舞いを共通のDSLで記述  
    6

    View full-size slide

  7. 従来のWebサーバの機能拡張
    7

    View full-size slide

  8. Webサーバの機能拡張の目的(1)
    1.動的コンテンツの高速処理を主な目的  
    •  レスポンス生成をいかに効率よくするか  
    •  CGIはforkのコストが大きい  
    •  手法の分類  
    •  インタプリタを直接サーバプロセスに組込む  
    •  mod_php、mod_perl、mod_ruby  …  
    •  インタプリタやCGIプロセスを事前に起動  
    •  FastCGI、Java  Servlet、Ruby  On  Rails  …  
    8

    View full-size slide

  9. Webサーバの機能拡張の目的(2)
    2.レスポンス生成以外の内部処理が主な目的  
    •  本研究のスコープ  
    •  アクセス制御やリソース管理等  
    •  Webサーバそのものの振る舞いを定義  
    •  高速・省メモリを重視してC言語による実装が主流  
    •  Apacheモジュール、nginxモジュール …  
    •  生産性・保守性を重視してスクリプトによる実装  
    •  mod_lua、mod_perl、mod_ruby  …  
    •  サーバプロセスへのインタプリタ組込み方式の違い  
    •  インタプリタ共有方式(mod_perl・mod_ruby等)  
    •  複数インタプリタ方式(mod_lua)  
      9

    View full-size slide

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

    View full-size slide

  11. 従来のスクリプトによる機能拡張
    従来の機能
    拡張  
    mod_perl   mod_ruby mod_lua  
    言語 C Perl   Ruby   Lua
    インタプリタ  
    初期化処理
    ** 事前 都度
    ライブラリ  
    読み込み
    ** 事前 都度
    コンパイル 事前 都度 都度
    コードの変更 不可 可 可
    グローバル状態 共有 共有 非共有
    11

    View full-size slide

  12. 提案するアーキテクチャ
    12

    View full-size slide

  13. 従来のアーキテクチャの課題
    •  インタプリタ共有方式は安全性に課題  
    –  性能面では効率の良い組込み方式  
    –  グローバル状態が複数スクリプトで干渉  
    –  インタプリタの確保するメモリの増加  
    •  複数インタプリタ方式はオーバーヘッドが大きい  
    –  組込みスクリプト言語自体の軽量・高速処理の恩恵  
    –  インタプリタ確保・開放のコストが高い  
    –  依然としてC言語による実装より性能が低い  
    •  これらの利点を両立できないか?  
    13

    View full-size slide

  14. 複数インタプリタ方式のオーバーヘッド
    状態遷移保存領域の確保  
    ライブラリ読み込み  
    構文木解析  
    バイトコード生成  
    VM上で実行  
    リクエスト処理時にサーバプロセスからスクリプトがフック  
    スクリプト読み込み  
    •  速度面でボトルネック  
    •  省メモリが可能  
    •  グローバル状態が独立
    状態遷移保存領域を開放  
    •  状態遷移保存領域  
    インタプリタがスクリプト
    を実行するために必要な
    情報を保存しておく領域
    14

    View full-size slide

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

    View full-size slide

  16. 提案するアーキテクチャ概要
    16




    親サーバプロセス  
    子サーバプロセスA   リクエスト処理用インタプリタ
    起動時処理用インタプリタ
    リクエスト以外の処理用インタプリタ
    子サーバプロセスB   リクエスト処理用インタプリタ
    起動時処理用インタプリタ
    リクエスト以外の処理用インタプリタ
    スクリプト
    スクリプト
    スクリプト
    スクリプト
    スクリプト

    View full-size slide

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

    View full-size slide

  18. 提案するアーキテクチャの処理(キャッシュ)
    構文木解析  
    バイトコード生成  
    VM上で実行  
    リクエスト処理時にサーバプロセスからスクリプトがフック  
    スクリプト読み込み  
    状態遷移保存領域  
    とライブラリを共有
    グローバル変数・クラス、例外フラグを開放  
    •  バイトコードをキャッシュ
    しておく事も可能  
    1.  サーバプロセス起動時
    にコンパイル  
    2.  バイトコードテーブルに
    保存  
    3.  バイトコードIDから取り
    出し
    18
    バイトコードテーブル  

    View full-size slide

  19. アーキテクチャの実装
    19

    View full-size slide

  20. アーキテクチャの実装
    •  インタプリタ  
    – mruby  
    – C言語と親和性の高い組込みスクリプト言語  
    •  Webサーバソフトウェア  
    – Apache  hSpd  
    – nginx  
    •  mod_mruby(+  ngx_mruby)と命名  
    – 今回はmod_mrubyを対象に実装を紹介  
    20

    View full-size slide

  21. mrubyの特徴
    •  組み込みスクリプト言語mruby  
    1.  組込み機器を考慮してリアルタイム性を向上  
    2.  Rubyの最小限の機能でメモリフットプリントが軽量  
    3.  モジュールやクラス、メソッドの細かい取り外しが可能  
    4.  RubyのISO規格を尊重して設計  
    5.  C言語と親和性の高い組み込みAPI  
    6.  C99に準拠した記述で実装されており高い移植性  
    Webコンテンツ技術者がRubyの延長で扱える  
    生産性・保守性と高速・軽量性の両立に最適  

    21

    View full-size slide

  22. mod_mrubyの実装
    •  特徴  
    –  インタプリタを共有する事で高速・省メモリに動作  
    –  スクリプト間でグローバル変数やクラスの干渉を防止  
    –  Webサーバの振る舞いをRuby  DSLで容易に記述可能  
    –  Apacheをリスタートする事なく変更可能(キャッシュも可能)  
    •  出来ることの例  
    –  オリジナルのリバースプロキシ(20行程度)  
    –  複雑な条件によるリダイレクト  
    –  サーバの負荷によって処理を変更  
    –  Apacheの内部情報を利用したアクセス制御  
    –  管理者が自由にリソース制御をDSLで記述可能  
    22

    View full-size slide

  23. Apache  hSpd  設定例
    LoadModule  mruby_module  modules/mod_mruby.so  
     
    #  handler  middleフェーズでtest.rbをコンパイルして実行  
     
           mrubyHandlerMiddle  /path/to/test.rb  
     
     
    # サーバプロセス起動時にtest.rbをバイトコードにコンパイル  
    # しておいてhandler  middleフェーズでバイトコードを実行  
     
           mrubyHandlerMiddle  /path/to/test.rb  cache  
    23

    View full-size slide

  24. VirtualHost
    24

    View full-size slide

  25. Reverse  Proxy
    25

    View full-size slide

  26. BasicAuth  with  Redis
    26

    View full-size slide

  27. Access  Control  like  suEXEC
    27

    View full-size slide

  28. リソース制御の応用例[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月.

    View full-size slide

  29. 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

    View full-size slide

  30. 同一の実装例
    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

    View full-size slide

  31. パフォーマンス評価
    31

    View full-size slide

  32. 実験
    クライアント
    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

    View full-size slide

  33. 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増加

    View full-size slide

  34. 実験結果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
    ※ バイトコードをキャッシュした場合(コードの変更は不可)

    View full-size slide

  35. まとめ
    35

    View full-size slide

  36. まとめ
    •  まとめ  
    –  スクリプト言語による高速かつ省メモリなWebサーバ機能拡張
    アーキテクチャを提案  
    –  従来手法の目的やアーキテクチャを整理して考察  
    –  Webサーバプロセスへのインタプリタ組込みを最適化  
    –  性能面と安全性を両立したアーキテクチャの設計  
    –  Webサーバにおける単純なHelloWorld出力の機能拡張処理で
    あればC言語と遜色ない性能  
    –  C言語による拡張実装とも両立が可能  
    •  今後の課題  
    –  実用的な機能拡張(リバースプロキシ等)による性能比較  
    36

    View full-size slide