はじめに
今回は、
今回も利用したコードやプログラムはgithubに置いてあるので適宜参照してください。
TokyoTyrantの特徴
key-valueストアという点ではmemcachedと同じですが、
また、
データ型 | TokyoTyrant | TokyoCabinet | ファイル名 |
---|---|---|---|
ハッシュデータベース | RDB | HDB | *.tch |
テーブルデータベース | RDBTBL | TDB | *.tct |
B+treeデータベース | RDB | BDB | *.tcb |
オンメモリデータベース | RDB | ADB | * |
どんなところに使える?
もっとも簡単な利用方法は、
また、
- 具体的な利用シーン
- memcachedの代替としての利用
- 複雑な検索条件を用いつつも高速なレスポンスが要求される
TokyoCabinetを試す
さて、
class TokyocabinetController < ApplicationController
require 'json'
require 'tokyocabinet'
include TokyoCabinet
before_filter :do_init
after_filter :do_finalize
def set
@hdb['key1'] = 100
@hdb['key2'] = ["foo", "bar"].to_json
@hdb['key3'] = {"a" => "ほげ", "b" => "ふが"}.to_json
end
def get
p @hdb['key1'] # "100"
p JSON.parse(@hdb['key2']) # ["foo", "bar"]
p JSON.parse(@hdb['key3']) # {"a" => "ほげ", "b" => "ふが"}
end
private
def do_init
@hdb = HDB.new # ハッシュデータベースを指定
@hdb.open('sample.tch', HDB::OWRITER | HDB::OCREAT)
end
def do_finalize
@hdb.close
end
end
TokyoTyrantを試す
TokyoCabinetでデータの保存や読み出しが出来ることが確認できました。しかし、
では、
sudo ttserver -port 1978 -pid /var/ttserver/pid_1978 -dmn /var/ttserver/ttcache_1978.tch sudo ttserver -port 1979 -pid /var/ttserver/pid_1979 -dmn /var/ttserver/ttcache_1979.tch sudo ttserver -port 1980 -pid /var/ttserver/pid_1980 -dmn /var/ttserver/ttcache_1980.tch
memcached互換プロトコル
もちろんTokyoTyrant独自プロトコルを使って利用することも可能ですが、
def do_init
@cache = MemCache.new(
- ['localhost:11211', 'localhost:11212', 'localhost:11213'], # memcached
+ ['localhost:1978', 'localhost:1979', 'localhost:1980'], # TokyoTyrant
:logger => Logger.new(STDOUT)
)
end
memcached互換プロトコルを利用する場合、
# key4は1978に、key2, key3は1979に、key1は1980に保存されている set key1 to <MemCache::Server: localhost:1980 [1] (CONNECTED)>: 5 set key2 to <MemCache::Server: localhost:1979 [1] (CONNECTED)>: 19 set key3 to <MemCache::Server: localhost:1979 [1] (CONNECTED)>: 16 set key4 to <MemCache::Server: localhost:1978 [1] (CONNECTED)>: 19
テーブルデータベース
次に、
まず、
sudo ttserver -port 1981 -ulog /var/ttserver/ulog_master -sid 1 -pid /var/ttserver/pid_1981 -dmn /var/ttserver/ttcache_1981.tct sudo ttserver -port 1982 -ulog /var/ttserver/ulog_slave_1982 -sid 2 -mhost localhost -mport 1981 -rts /var/ttserver/3.rts -pid /var/ttserver/pid_1982 -dmn /var/ttserver/ttcache_1982.tct sudo ttserver -port 1983 -ulog /var/ttserver/ulog_slave_1983 -sid 3 -mhost localhost -mport 1981 -rts /var/ttserver/3.rts -pid /var/ttserver/pid_1983 -dmn /var/ttserver/ttcache_1983.tct
TokyoTyrantはmemcachedと同じようにクライアント側の実装によって処理を分散させる必要があります。ただし、
テーブルデータベースを利用した具体的なコードは以下のようになります。簡単な実装ですが、
class TokyotyrantTdbController < ApplicationController
require 'tokyotyrant'
include TokyoTyrant
before_filter :set_connection, :do_init
after_filter :do_finalize
def set
@rdb['1'] = {"name" => "山田花子", "sex" => "female", "birthday" => "20050321"}
@rdb['2'] = {"name" => "鈴木太郎", "sex" => "male", "birthday" => "20060601"}
@rdb['3'] = {"name" => "佐藤洋子", "sex" => "female", "birthday" => "20070311"}
@rdb['4'] = {"name" => "山田健一", "sex" => "male", "birthday"=> "20070523"}
end
def get
qry = RDBQRY::new(@rdb)
qry.addcond("name", RDBQRY::QCSTRBW, "山田")
qry.setorder("birthday", RDBQRY::QONUMDESC)
res = qry.search()
p res # ["4", "1"] (keyが返ってくる)
p @rdb.get(res[0]) # {"name" => "山田健一", "sex" => "male", "birthday"=> "20070523"}
p @rdb.get(res[1]) # {"name" => "山田花子", "sex" => "female", "birthday" => "20050321"}
end
private
def set_connection
@connection = {
:master => ['localhost', 1981],
:slave => [
['localhost', 1982],
['localhost', 1983]
]
}
end
def do_init
@rdb = RDBTBL::new() # テーブルデータベース
case action_name
when 'set'
_con = @connection[:master]
@rdb.open(_con[0], _con[1])
logger.info "write to master: #{_con[0]}:#{_con[1]}"
when 'get'
_con = @connection[:slave].sort_by{rand}.first
@rdb.open(_con[0], _con[1])
logger.info "read from slave: #{_con[0]}:#{_con[1]}"
end
@rdb.setindex("name", RDBTBL::ITLEXICAL) # インデックス
end
def do_finalize
@rdb.close()
end
end
例では、
まとめ
今回はTokyoTyrantについて見てみました。memcachedは何といっても手軽なのですが、