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

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

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

MATSUMOTO Ryosuke
PRO

December 20, 2013
Tweet

More Decks by MATSUMOTO Ryosuke

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

  3. 本研究の概要
    3

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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




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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    21

    View Slide

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

    View 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 Slide

  24. VirtualHost
    24

    View Slide

  25. Reverse  Proxy
    25

    View Slide

  26. BasicAuth  with  Redis
    26

    View Slide

  27. Access  Control  like  suEXEC
    27

    View 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 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 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 Slide

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

    View 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 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 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 Slide

  35. まとめ
    35

    View Slide

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

    View Slide