Tokyo Tyrant をC言語で使う

# Tokyo Tyrantとは

Key-Value Store(KVS)の一種で、DBMSよりも高速にデータを読み書きすることができるため、
キャッシュ情報などの頻繁に更新されるデータの保存に使用される

Tokyo TyrantはTokyo Cabinetと組み合わせて使い、Tokyo Cabinetは実際にデータを読み書きするファイルコンテナで、
Tokyo Tyrantはそれを操作するためのインタフェースを提供する

ここでは便宜上、Tokyo TyrantとTokyo Cabinetを組み合わせて構成したものをTokyo Tyrantと表記する

## URL

Tokyo Tyrant: network interface of Tokyo Cabinet
http://fallabs.com/tokyotyrant/

DBMによるテーブルデータベース その参 (Mixi::Engineers::Blog)
http://alpha.mixi.co.jp/entry/2009/10705/

## インストール

### バージョン

* Tokyo Cabinet: 1.4.48
* Tokyo Tyrant: 1.1.41

### configure

インストール先を${PREFIX_DIR}で指定しています。ここでは以下の設定をしていますが、環境に合わせて適宜変更(/usrや/usr/localなど)してください
<pre>
PREFIX_DIR=/opt/tokyotyrant
</pre>

* Tokyo Cabinet
<pre>
        ./configure \
                --prefix=${PREFIX_DIR} \
                --libdir=${TARGETLIB_DIR} \
                --sysconfdir=${PREFIX_DIR}/conf \
                --localstatedir=${PREFIX_DIR}/var \
                --enable-shared \
                --disable-debug \
                --disable-devel
</pre>
* Tokyo Tyrant
<pre>
       ./configure \
                --prefix=${PREFIX_DIR} \
                --libdir=${TARGETLIB_DIR} \
                --sysconfdir=${PREFIX_DIR}/conf \
                --localstatedir=${PREFIX_DIR}/var \
                --with-tc=${PREFIX_DIR} \
                --enable-shared \
                --disable-debug \
                --disable-devel
</pre>

### make
<pre>
$ make
# make install
</pre>

## コマンドによるデータベース操作

* 値を取得
<pre>
$ tcrmgr get localhost ${key}
</pre>

* 値をセット
<pre>
$ tcrmgr put localhost ${key} ${value}
</pre>
 
* 値を削除
<pre>
$ tcrmgr out localhost ${key}
</pre>

* 登録されている全てのキーを取得
<pre>
$ tcrmgr list localhost
</pre>

* 登録されている全てのデータのキーと値を取得
<pre>
$ tcrmgr list -pv -sep '|' localhost
</pre>

* データを全て削除する
<pre>
$ tcrmgr vanish localhost
</pre>

* データベースを最適化する
<pre>
$ tcrmgr optimize localhost
</pre>

## データ構造

ファイルのサフィックスで変わる。ttserver起動時に指定する

例) tctを指定してtable database型で動作
<pre>
$ ttserver /tmp/ttserver.tct
</pre>

サフィックス|形式
-----------|-----
指定なし|hash database
+|tree database
.tch|hash database
.tcb|tree database
.tcf|fixed length database
.tct|table database

データ構造については以下のページを参考 (slide shareの17ページ目)
http://www.akirakoyasu.net/2011/12/11/tokyo-cabinet-and-tokyo-tyrant/

## C言語API

fallabsの [サンプルコード](http://fallabs.com/tokyotyrant/spex.html) を見れば基本的な使い方が分かる
APIの仕様については、Tokyo Tyrantの tcrdb.h を確認すればよい

* レコードを格納する（上書きモード）
<pre><code class="C">
bool tcrdbtblput(TCRDB *rdb, const void *pkbuf, int pksiz, TCMAP *cols);
</code></pre>

* レコードを格納する（既存値優先モード）
<pre><code class="C">
bool tcrdbtblputkeep(TCRDB *rdb, const void *pkbuf, int pksiz, TCMAP *cols);
</code></pre>

* レコードを格納する（カラム追加モード）
<pre><code class="C">
bool tcrdbtblputcat(TCRDB *rdb, const void *pkbuf, int pksiz, TCMAP *cols);
</code></pre>

* レコードを削除する
<pre><code class="C">
bool tcrdbtblout(TCRDB *rdb, const void *pkbuf, int pksiz);
</code></pre>

* レコードを取得する
<pre><code class="C">
TCMAP *tcrdbtblget(TCRDB *rdb, const void *pkbuf, int pksiz);
</code></pre>

* コラムインデックスを設定する
<pre><code class="C">
bool tcrdbtblsetindex(TCRDB *rdb, const char *name, int type);
</code></pre>

* ユニークなID番号を採番する
<pre><code class="C">
int64_t tcrdbtblgenuid(TCRDB *rdb);
</code></pre>

* クエリオブジェクトを生成する
<pre><code class="C">
RDBQRY *tcrdbqrynew(TCRDB *rdb);
</code></pre>

* クエリオブジェクトを破棄する
<pre><code class="C">
void tcrdbqrydel(RDBQRY *qry);
</code></pre>

* クエリオブジェクトに絞り込み条件を追加する
<pre><code class="C">
void tcrdbqryaddcond(RDBQRY *qry, const char *name, int op, const char *expr);
</code></pre>

* クエリオブジェクトに結果の順序を設定する
<pre><code class="C">
void tcrdbqrysetorder(RDBQRY *qry, const char *name, int type);
</code></pre>

* クエリオブジェクトに結果の最大取得件数を設定する
<pre><code class="C">
void tcrdbqrysetmax(RDBQRY *qry, int max);
</code></pre>

* 検索を行って主キーのリストを取得する
<pre><code class="C">
TCLIST *tcrdbqrysearch(RDBQRY *qry);
</code></pre>

* 検索を行って該当のレコードを削除する
<pre><code class="C">
bool tcrdbqrysearchout(RDBQRY *qry);
</code></pre>

## レプリケーション構築

### 準備

1. マスタの更新ログ置き場を用意する
<pre>
マスタ側
$ mkdir /tmp/ulog-master
</pre>

2. スレーブの更新ログ置き場を用意する
<pre>
スレーブ側
$ mkdir /tmp/ulog-slave
</pre>

### 起動
* マスタの起動
<pre>
$ ttserver -port 1978 -sid 1 -ulog /tmp/ulog-master /tmp/casket-master.tch
</pre>

* スレーブの起動
<pre>
$ ttserver -port 1979 -sid 2 -ulog /tmp/ulog-slave -mhost %%master_host%% -mport 1978 -rts /tmp/slave.rts /tmp/casket-slave.tch
</pre>
※ %%master_host%% はマスタのホスト名(またはIPアドレス)に置き換えてください
※ 複数のスレーブを立てる場合は"-sid"の値が被らないように、任意の値を割り当ててください

### 確認

1. マスタにデータを登録
<pre>
$ tcrmgr put -port 1978 %%master_host%% tako ika
</pre>
※ %%master_host%% はマスタのホスト名(またはIPアドレス)に置き換えてください

2. マスタのデータを検索
<pre>
$ tcrmgr get -port 1978 %%master_host%% tako
</pre>
※ %%master_host%% はマスタのホスト名(またはIPアドレス)に置き換えてください

3. スレーブのデータを検索
<pre>
$ tcrmgr get -port 1979 %%slave_host%% tako
</pre>
※ %%slave_host%% はスレーブのホスト名(またはIPアドレス)に置き換えてください

### 参考

Tokyo TyrantによるHAハッシュDBサーバの構築
http://alpha.mixi.co.jp/entry/2008/10692/