Tokyo Tyrant + Lua Extensionで作るクエリキャッシュサーバ

6,750 views

Published on

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

Tokyo Tyrant + Lua Extensionで作るクエリキャッシュサーバ

  1. 1. Tokyo Tyrant+Lua で作る クエリキャッシュサーバ KLab 株式会社 研究開発部 鈴木 信太郎 <suzuki-s@klab.jp>
  2. 2. 自己紹介 <ul><li>名前:鈴木 信太郎 </li></ul><ul><li>入社3ヶ月目 </li></ul><ul><li>ソーシャルアプリを作っています </li></ul><ul><ul><li>高負荷対策 </li></ul></ul><ul><ul><li>  ->ストレージを変えよう(?) </li></ul></ul><ul><li>言語 </li></ul><ul><ul><li>Perl, PHP, Ruby </li></ul></ul><ul><li>最近の興味 </li></ul><ul><ul><li>テレビ(BRAVIA)を買った ->アプリキャスト使ってみたい </li></ul></ul>
  3. 3. agenda <ul><li>Tokyo Cabinet, Tokyo Tyrant って何? </li></ul><ul><li>Tokyo Tyrant で Lua extension を使う </li></ul><ul><ul><li>TT から MySQL に接続してみる </li></ul></ul><ul><ul><li>試作:クエリキャッシュサーバ </li></ul></ul>
  4. 4. システム構成例 クライアント Tokyo Tyrant Lua Tokyo Cabinet Tokyo Tyrant Lua Tokyo Cabinet レプリケーション
  5. 5. <ul><li>mixi の平林さんが開発した DBM </li></ul><ul><li>色んなデータ構造があります </li></ul><ul><ul><li>ハッシュ DB </li></ul></ul><ul><ul><li>B+ 木 DB </li></ul></ul><ul><ul><li>固定長 DB </li></ul></ul><ul><ul><li>テーブル DB </li></ul></ul><ul><li>速い </li></ul><ul><ul><li>Tokyo Cabinet 公式サイトのベンチマーク </li></ul></ul><ul><ul><li>http://1978th.net/tokyocabinet/benchmark.pdf </li></ul></ul>Tokyo Cabinet
  6. 6. Tokyo CabinetのテーブルDB mixi Engineers’ Blog >> DBM によるテーブルデータベース http:// alpha.mixi.co.jp/blog/?p =290
  7. 7. Tokyo Tyrant <ul><li>Network interface of Tokyo Cabinet </li></ul><ul><li>Memcached プロトコル互換 </li></ul><ul><li>レプリケーションも組めます </li></ul><ul><li>Lua extension で機能拡張できる </li></ul><ul><ul><li>ビルドオプション – enable-lua を付ける </li></ul></ul><ul><ul><li>起動オプション – ext=script.lua </li></ul></ul>
  8. 8. Lua <ul><li>高速で動作する組み込み用スクリプト言語 </li></ul><ul><li>Lua 5.1 リファレンスマニュアル </li></ul><ul><ul><li>http://sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html </li></ul></ul>function hoge(arg1, arg2) -- 文字列連結 local str = arg1 .. Arg2 --- テーブル ( 連想配列 ) local tbl = {“aaa”, “bbb”, “ccc”} --- ループ for i, v = ipairs(tbl) do echo v end return str end
  9. 9. クエリキャッシュサーバ <ul><li>動機 </li></ul><ul><ul><li>Tokyo Tyrant + Lua で何か作れないだろうか </li></ul></ul><ul><ul><li>Lua から他の DB に接続できる? </li></ul></ul><ul><ul><li>アプリケーションからキャッシュを意識せずにデータアクセスできたら便利そう </li></ul></ul><ul><ul><li>しかも速そう </li></ul></ul>
  10. 10. クエリキャッシュの仕組み Memcached Web Server MySQL Server Tokyo Tyrant Web Server Lua Tokyo Cabinet MySQL Server MySQL + Memcached TT+Lua
  11. 11. getById() <ul><li>getById(table_name, id) </li></ul>$data = $mc->get(‘item_1’); If(!$data){ $stmt = $mysql->query(‘select * from item where id=1’); $data = $stmt->fetch(); } MySQL + Memcached $data = $tt->ext(‘getById’, TokyoTyrant::RDBXOLCK_REC, “item”, 1); TT + Lua
  12. 12. getById() の実装 function getById(table, id) key = table .. &quot;_&quot; .. id val = _get(key) -- cache hit if val ~= nil then     return val end query = string.format([[select * from %s where id='%s']], table, string.gsub(id,&quot;'&quot;,&quot;''&quot;)) ret = con:execute(query) if not ret then _log(&quot;query error&quot;) return &quot;&quot; end val = serialize_for_php(ret:fetch({}, &quot;a&quot;)) _put(key, val) return val end
  13. 13. 性能比較 100 万レコードをランダムに指定して 10 万回抽出 ※ キャッシュヒット率 Memcached: 60% Tokyo Tyrant: 60% [QPS]
  14. 14. 関係テーブルをTTに <ul><li>応用 </li></ul><ul><ul><li>関係テーブルを TT に置く </li></ul></ul><ul><ul><ul><li>例えば User-Item テーブルを TT に格納する </li></ul></ul></ul><ul><ul><ul><ul><li>dbname=user_item.tct#idx=user_id:dec#idx=item_id:dec </li></ul></ul></ul></ul><ul><ul><li>MySQL 上の Item マスタに TT からアクセスする </li></ul></ul><ul><ul><li>クエリキャッシュは Stash (オンメモリのハッシュ DB, テーブル DB とは別)に格納する </li></ul></ul>user user_item item 1 * * 1 Item のキャッシュ stash テーブル DB
  15. 15. getItems() <ul><li>getItems(user_id) </li></ul>$stmt = $mysql->query(‘select * from user_item where user_id=1’); while($user_item = $stmt->fetch()){ $key = ‘item_’.$user_item[‘item_id’]; if(!$data = $mc->get($key)){ $stmt2 = $mysql->query(‘select * from item where id=‘.$user_item[‘item_id’]); $data = $stmt2->fetch(); $mc->set($key, $data); } } MySQL + Memcached $data = $tt->ext(‘getItems’, TokyoTyrant::RDBXOLCK_REC, 1); TT + Lua
  16. 16. getItems() の実装 function getItems(id) local args = {} table.insert(args, &quot;addconduser_idNUMEQ&quot;..id) local keys = _misc(&quot;search&quot;, args) local ret = {} for i, key in pairs(keys) do local val = unserialize( _get(key) ) ret[key] = getById('item', val['item_id'])   end return serialize_for_php(ret) end
  17. 17. 性能比較 [QPS] ※ キャッシュヒット率 Memcached: 67% Tokyo Tyrant: 67%
  18. 18. 参考:更新性能 [QPS] User_item テーブルに 100 万レコード insert
  19. 19. 性能について補足 <ul><li>Lua の処理によってはパフォーマンスが結構落ちる </li></ul><ul><ul><li>特に文字列処理とテーブル ( 連想配列 ) の処理が重い? </li></ul></ul><ul><ul><li>リクエスト毎に処理せずに、 extpc オプションを使う方法も </li></ul></ul>ttserver –ext function.lua –extpc function 1
  20. 20. まとめ <ul><li>TC, TT について </li></ul><ul><ul><li>テーブル DB がすごい </li></ul></ul><ul><ul><li>Lua で extension できる </li></ul></ul><ul><li>TT の Lua から MySQL に接続できた </li></ul><ul><ul><li>Lua でできる事なら何でもできそう </li></ul></ul><ul><ul><li>例: TC のデータ操作、メール送信、死活監視 </li></ul></ul><ul><li>クエリキャッシュサーバ </li></ul><ul><ul><li>パフォーマンスは期待ほどでは無いものの、一応使えそう </li></ul></ul><ul><ul><li>TODO : Lua の処理を見直して性能向上させる </li></ul></ul>
  21. 21. 参考文献 <ul><li>mixi Engineers’ Blog </li></ul><ul><ul><li>Lua on Tyrant: DB サーバに LL を組み込む </li></ul></ul><ul><ul><ul><li>http:// alpha.mixi.co.jp/blog/?p =236 </li></ul></ul></ul><ul><ul><li>DBM によるテーブルデータベース </li></ul></ul><ul><ul><ul><li>http://alpha.mixi.co.jp/blog/?p=290 </li></ul></ul></ul><ul><li>平林幹雄のホームページ </li></ul><ul><ul><li>http://1978th.net/ </li></ul></ul><ul><li>Lua 5.1 リファレンスマニュアル </li></ul><ul><ul><li>http://sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html </li></ul></ul>ご清聴ありがとうございました!

×