FreeBSDでKyotoTycoonを使ってみた
KyotoTycoon とは?
KyotoTycoonはプロセス組み込み軽量データベースライブラリであるKyoto Cabinetをネットワーク越しに利用出来るようにするKVSのサーバです。同じKVSで有名なmemcachedの場合データベースを全てオンメモリで処理しているため電源を落としたりプロセスを再起動させると保存していたデータが全部初期化されてしまう特徴があります。 KyotoTycoonはファイルにデータを書き込み永続的なデータ保存ができる「memcachedのデータ永続化版」の特徴を持っています。
またサーバの起動オプションでmemcachedと同じようにオンメモリに高速にデータストアーできるように設定することも可能な特徴も合わせ持っているようです。また付属するプラグインを利用する事によりmemcachedのプロトコルを解釈する事ができるためプログラムシステムを全く変更することなくmemcachedと置き換えることも可能です。データベースのホットバックアップやレプリケーションも出来るため耐障害性能のあるKVSとして利用価値があります。
KyotoCabinet をインストール
FreeBSDには便利なportsシステムがあり簡単にアプリケーションのインストールができるのですがKyotoCabinetのportsが古いためtarballからinstallします。
http://fallabs.com/kyotocabinet/
$ wget http://fallabs.com/kyotocabinet/pkg/kyotocabinet-1.2.58.tar.gz $ export CPPFLAGS="-march=i686" $ ./configure $ gmake $ su # make install
lua のインストール
portsから
$ sudo portinstall lang/lua
KyotoTycoonをmakeする際にライブラリが見つけられないのでシンボリックリンクを作成
$ ln -s /usr/local/include/lua51 /usr/local/include/lua $ ln -s /usr/local/lib/liblua-5.1.so /usr/local/lib/liblua.so
KyotoTycoon のインストール
portsに存在しませんのでtarballからinstallします。 http://fallabs.com/kyototycoon/
$ wget http://fallabs.com/kyototycoon/pkg/kyototycoon-0.9.42.tar.gz $ ./configure --enable-lua $gmake $su #make install
KyotoTycoon の起動
$ktserver 2011-06-05T02:28:48.710949+09:00: [SYSTEM]: ================ [START]: pid=64582 2011-06-05T02:28:48.712529+09:00: [SYSTEM]: opening a database: path=: 2011-06-05T02:28:48.713851+09:00: [SYSTEM]: starting the server: expr=:1978 2011-06-05T02:28:48.714925+09:00: [SYSTEM]: server socket opened: expr=:1978 timeout=30.0 2011-06-05T02:28:48.715320+09:00: [SYSTEM]: listening server socket started: fd=3
オプションを何も指定しないで起動させるとオンメモリなKVSとして動作します。 起動させた状態で別コンソールなどからKVSを操作してみます。
$ktremotemgr set key1 hoge $ktremotemgr get key1 hoge $ktremotemgr set key2 moe $ktremotemgr get key2 moe #expire 5sec $ktremotemgr set -xt 5 foo bar1
サーバをstopするには[ctl-C]
ktserverオプション一覧
-host str : specifies the host name of the server. -port num : specifies the port number of the server. -tout num : specifies the timeout in seconds. -th num : specifies the number of worker threads. By default, it is 8. -log file : specifies the path of the log file. By default, logs are written into the standard output. -li : sets the logging level "INFO". -ls : sets the logging level "SYSTEM". -le : sets the logging level "ERROR". -lz : sets the logging level "NONE". -ulog dir : specifies the path of the update log directory. By default, it is disabled. -ulim num : specifies the limit size of each update log file. -uasi num : specifies the interval of synchronization of update log files. By default, it is disabled. -sid num : specifies the server ID number. -ord : opens the database as a reader. -oat : opens the database with the auto transaction option. -oas : opens the database with the auto synchronization option. -onl : opens the database with the no locking option. -otl : opens the database with the try locking option. -onr : opens the database with the no auto repair option. -asi num : specifies the interval of auto synchronization. By default, it is disabled. -ash : does physical synchronization while auto synchronization. -bgs dir : specifies the path of the background snapshot directory. By default, it is disabled. -bgsi num : specifies the interval of background snapshotting. By default, it is 180. -bgsc str : specifies the compression algorithm of the snapshot. "zlib", "lzo", are "lzma" are supported. -dmn : switches to a daemon process. -pid file : specifies the file to contain the process ID to send signals by. -cmd dir : specifies the command search path for outer commands. By default, it is the current directroy. -scr file : specifies the script file for the scripting extention. -mhost str : specifies the host name of the master server of replication. -mport num : specifies the port number of the master server of replication. -rts file : specifies the file to contain the replication time stamp. -riv num : specifies the interval of each replication operation in milliseconds. By default, it is 0.04. -plsv file : specifies the shared library file of a pluggable server. -plex str : specifies the configuration expression of a pluggable server. -pldb file : specifies the shared library file of a pluggable database.
DBの命名規則
内部で利用しているKyotoCabinetのDBの種類がいくつかありDBファイルの拡張子等で指定する事が可能です。
- ":" :スタッシュDB(デフォルト、省メモリDB)
- "*" :オンメモリハッシュDB
- "%" :オンメモリツリーDB
- ".kch" :ファイルハッシュDB
- ".kct" :ファイルツリーDB
- ".kcd" :ディレクトリハッシュDB
- ".kcf" :ディレクトリツリーDB
FreeBSD用KyotoTycoonスタートアップスクリプト
設定内容がハードコートしてあります。適宜自分の設定に書き換えてお使い下さい。現在の設定はmemcachedプラグインを利用してファイルハッシュDBを64MBのメモリマップで使う設定になっております。 スタートアップスクリプト ktservctl
設置場所は /usr/local/etc/rc.d/ktservctl
起動: /usr/local/etc/rc.d/ktservctl start
停止: /usr/local/etc/rc.d/ktservctl stop
再起動: /usr/local/etc/rc.d/ktservctl restart
#!/bin/sh
#----------------------------------------------------------------
# Startup script for the server of KyotoTycoon
#----------------------------------------------------------------
# configuration variables
prog="ktservctl"
cmd="ktserver"
basedir="/var/ktserver"
port="1978"
pidfile="$basedir/pid"
logfile="$basedir/log"
#ulogdir="$basedir/ulog"
#ulimsiz="256m"
#sid=1
#mhost="remotehost1"
#mport="1978"
#rtsfile="$basedir/rts"
dbname="$basedir/casket.kch#opts=l#bnum=100000#msiz=64m#dfunit=8"
timeout=10
plsv="/usr/local/libexec/ktplugservmemc.so"
plex="opts=f"
retval=0
# setting environment variables
LANG=C
LC_ALL=C
PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
export LANG LC_ALL PATH
# start the server
start(){
printf 'Starting the server of Tokyo Tyrant\n'
mkdir -p "$basedir"
if [ -z "$basedir" ] || [ -z "$port" ] || [ -z "$pidfile" ] || [ -z "$dbname" ] ; then
printf 'Invalid configuration\n'
retval=1
elif ! [ -d "$basedir" ] ; then
printf 'No such directory: %s\n' "$basedir"
retval=1
elif [ -f "$pidfile" ] ; then
pid=`cat "$pidfile"`
printf 'Existing process: %d\n' "$pid"
retval=1
else
cmd="$cmd -port $port -le -dmn -pid $pidfile"
if [ -n "$timeout" ] ; then
cmd="$cmd -tout $timeout"
fi
if [ -n "$plsv" ] ; then
cmd="$cmd -plsv $plsv"
fi
if [ -n "$plex" ] ; then
cmd="$cmd -plex $plex"
fi
if [ -n "$logfile" ] ; then
cmd="$cmd -log $logfile"
fi
if [ -n "$ulogdir" ] ; then
mkdir -p "$ulogdir"
cmd="$cmd -ulog $ulogdir"
fi
if [ -n "$ulimsiz" ] ; then
cmd="$cmd -ulim $ulimsiz"
fi
if [ -n "$sid" ] ; then
cmd="$cmd -sid $sid"
fi
if [ -n "$mhost" ] ; then
cmd="$cmd -mhost $mhost"
fi
if [ -n "$mport" ] ; then
cmd="$cmd -mport $mport"
fi
if [ -n "$rtsfile" ] ; then
cmd="$cmd -rts $rtsfile"
fi
printf "Executing: %s\n" "$cmd"
cmd="$cmd $dbname"
$cmd
if [ "$?" -eq 0 ] ; then
printf 'Done\n'
else
printf 'The server could not started\n'
retval=1
fi
fi
}
# stop the server
stop(){
printf 'Stopping the server of Tokyo Tyrant\n'
if [ -f "$pidfile" ] ; then
pid=`cat "$pidfile"`
printf "Sending the terminal signal to the process: %s\n" "$pid"
kill -TERM "$pid"
c=0
while true ; do
sleep 0.1
if [ -f "$pidfile" ] ; then
c=`expr $c + 1`
if [ "$c" -ge 100 ] ; then
printf 'Hanging process: %d\n' "$pid"
retval=1
break
fi
else
printf 'Done\n'
break
fi
done
else
printf 'No process found\n'
retval=1
fi
}
# send HUP to the server for log rotation
hup(){
printf 'Sending HUP signal to the server of Tokyo Tyrant\n'
if [ -f "$pidfile" ] ; then
pid=`cat "$pidfile"`
printf "Sending the hangup signal to the process: %s\n" "$pid"
kill -HUP "$pid"
printf 'Done\n'
else
printf 'No process found\n'
retval=1
fi
}
# check permission
if [ -d "$basedir" ] && ! touch "$basedir/$$" >/dev/null 2>&1
then
printf 'Permission denied\n'
exit 1
fi
rm -f "$basedir/$$"
# dispatch the command
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
hup)
hup
;;
*)
printf 'Usage: %s {start|stop|restart|hup}\n' "$prog"
exit 1
;;
esac
# exit
exit "$retval"
# END OF FILE
memcachedクライアントから操作するには
ktserver 起動時にktplugservmemc.soプラグインを指定することでmemcachedプロトコルを扱えるようになります。 起動オプション例
$ ktserver -plsv /usr/local/libexec/ktplugservmemc.so -plex 'opts=f' 'casket.kch#opts=l#bnum=100000#msiz=64m#dfunit=8'
memcachedクライアント
Masahiro Naganoさん謹製の perlモジュール Cache::Memcached::IronPlate からアクセスしてみます。
Cache::Memcached::IronPlate は Cache::Memcached::Fast のオブジェクトを渡して使うperlモジュールで memcached injectionを防ぐための機能が備わったmemcachedクライアントライブラリです。
iron.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Cache::Memcached::IronPlate;
use Cache::Memcached::Fast;
use Data::MessagePack;
use Data::Dumper;
use utf8;
my $memd = Cache::Memcached::IronPlate->new(
cache => Cache::Memcached::Fast->new({
servers => [ { address => 'localhost:11211' }],
serialize_methods =>
[
sub { Data::MessagePack->pack(+shift)},
sub { Data::MessagePack->unpack(+shift)}
]
})
);
$memd->set(key1 => +{ foo => 1, bar => 1});
warn Dumper $memd->get("key1");
$memd->set(key2 => +{foo => "日本語"});
warn Dumper $memd->get("key2");
$memd->set("key 3 キー\n" => "bar");
warn Dumper $memd->get("key 3 キー\n");
実行結果
$perl iron.pl
$VAR1 = {
'bar' => 1,
'foo' => 1
};
$VAR1 = {
'foo' => '日本語'
};
$VAR1 = 'bar';
参考)
[http://www.slideshare.net/estraier/kyoto-tycoon-guide-in-japanese](http://www.slideshare.net/estraier/kyoto-tycoon-guide-in-japanese)
追記2011-06-17
FreeBSD用の自動起動用のスクリプト
rc.conf追加
ktserver_enable="YES" ktserver_args="-port 1978 -le -dmn -pid /var/ktserver/pid -tout 10 -plsv /usr/local/libexec/ktplugservmemc.so -plex opts=f -log /var/ktserver/log /var/ktserver/casket.kch#opts=l#bnum=100000#msiz=64m#dfunit=8"
自動起動スクリプト
#!/bin/sh
#
# $FreeBSD: ports/databases/kyototycoon/files/ktserver,v 1.3 2011/06/17 00:12:51 dougb Exp $
#
#
# PROVIDE: ktserver
# REQUIRE: DAEMON
# KEYWORD: shutdown
. /etc/rc.subr
name="ktserver"
rcvar=`set_rcvar`
load_rc_config $name
: ${ktserver_enable:="NO"}
: ${ktserver_args=""}
command="/usr/local/bin/${name}"
command_args="${ktserver_args}"
run_rc_command "$1"