安装Tokyo Cabinet & Tokyo Tyrant的过程记录 @ 5/28/2010

技术类
1、编译安装tokyo cabinet
wget http://1978th.net/tokyocabinet/tokyocabinet-1.4.45.tar.gz
tar zxvf tokyocabinet-1.4.45.tar.gz
cd tokyocabinet-1.4.45/
./configure --prefix=/usr/local/services --enable-static --enable-off64
make
make install

2、编译安装tokyo tyrant
wget http://1978th.net/tokyotyrant/tokyotyrant-1.1.40.tar.gz
tar zxvf tokyotyrant-1.1.40.tar.gz
cd tokyotyrant-1.1.40/
./configure --prefix=/usr/local/services --enable-static --with-tc=/usr/local/services
make
make install


3、启动tokyo tyrant
A、单机模式
ulimit -SHn 51200
ttserver -host 127.0.0.1 -port 8888 -thnum 8 -dmn -pid /data/tt.pid -log /data/tt.log -le -ulog /data/ -ulim 128m -sid 1 -rts /data/tt.rts /data/data.tch#bnum=10000#rcnum=100000#xmsiz=256m

如果希望提高查询的性能,可以把hash的桶设置得再大些,然后缓存的记录多一些。
同时,设置-uas参数异步写入日志,可提高写入的性能。不过这样可能导致日志丢失,降低了数据安全性。

B、双机互为主辅模式
服务器192.168.1.11:
ulimit -SHn 51200
ttserver -host 192.168.1.11 -port 8888 -thnum 8 -dmn -pid /data/tt.pid -log /data/tt.log -le -ulog /data/ -ulim 128m -sid 1 -mhost 192.168.1.12 -mport 11211 -rts /data/tt.rts /data/data.tch#bnum=10000#rcnum=100000#xmsiz=256m

服务器192.168.1.12:
ulimit -SHn 51200
ttserver -host 192.168.1.12 -port 8888 -thnum 8 -dmn -pid /data/tt.pid -log /data/tt.log -le -ulog /data/ -ulim 128m -sid 2 -mhost 192.168.1.11 -mport 11211 -rts /data/tt.rts /data/data.tch#bnum=10000#rcnum=100000#xmsiz=256m

应用程序可以访问任意一个服务器进行读写,且应用程序发现某服务器不能访问后,可立即转到另一台服务器。

注:
a、数据库类型由后缀决定
Hash Database: tch
B+ tree database: tcb
fixed-length database: tcf
table database: tct
内存Hash Database: *
内存B+ tree database: +

b、参数说明:
ttserver [-host name] [-port num] [-thnum num] [-tout num] [-dmn] [-pid path] [-log path] [-ld|-le] [-ulog path] [-ulim num] [-uas] [-sid num] [-mhost name] [-mport num] [-rts path] [dbname]
  -host name: 指定需要绑定的服务器域名或IP地址。默认绑定这台服务器上的所有IP地址。
  -port num: 指定需要绑定的端口号。默认端口号为1978
  -thnum num: 指定线程数。默认为8个线程。
  -tout num: 指定每个会话的超时时间(单位为秒)。默认永不超时。
  -dmn: 以守护进程方式运行。
  -pid path: 输出进程ID到指定文件(这里指定文件名)。
  -log path: 输出日志信息到指定文件(这里指定文件名)。
  -ld: 在日志文件中还记录DEBUG调试信息。
  -le: 在日志文件中仅记录错误信息。
  -ulog path: 指定同步日志文件存放路径(这里指定目录名)。
  -ulim num: 指定每个同步日志文件的大小(例如128m)。
  -uas: 使用异步IO记录更新日志(使用此项会减少磁盘IO消耗,但是数据会先放在内存中,不会立即写入磁盘,如果重启服务器或ttserver进程被kill掉,将导致部分数据丢失。一般情况下不建议使用)。
  -sid num: 指定服务器ID号(当使用主辅模式时,每台ttserver需要不同的ID号)
  -mhost name: 指定主辅同步模式下,主服务器的域名或IP地址。
  -mport num: 指定主辅同步模式下,主服务器的端口号。
  -rts path: 指定用来存放同步时间戳的文件名。
  #bnum=xxx: 指定bucket存储桶的数量。例如#bnum=10000,将最新最热的1万条记录缓存在内存中


C、读写分离
可以使用on-memory hash database引擎的ttserver作为写服务器,然后采用复制的方式将on-memory hash database上的数据复制到hash database的多个ttserver上去,然后将多个hash database ttserver作为读服务器。这实际上是通过降低一致性来提高性能。

写服务器192.168.1.11:
ulimit -SHn 51200
ttserver -host 192.168.1.11 -port 8888 -thnum 8 -dmn -pid /data/tt.pid -log /data/tt.log -le -ulog /data/ -ulim 128m -sid 0 -mhost 192.168.1.12 -mport 11211 -rts /data/tt.rts "*#bnum=10000000#capnum=100#capsiz=10m"

服务器192.168.1.12:
ulimit -SHn 51200
ttserver -host 192.168.1.12 -port 8888 -thnum 8 -dmn -pid /data/tt.pid -log /data/tt.log -le -ulog /data/ -ulim 128m -sid 1 -mhost 192.168.1.11 -mport 11211 -rcc -rts /data/tt.rts /data/data.tch#bnum=10000#rcnum=100000#xmsiz=256m

服务器192.168.1.13:
ulimit -SHn 51200
ttserver -host 192.168.1.13 -port 8888 -thnum 8 -dmn -pid /data/tt.pid -log /data/tt.log -le -ulog /data/ -ulim 128m -sid 2 -mhost 192.168.1.11 -mport 11211 -rcc -rts /data/tt.rts /data/data.tch#bnum=10000#rcnum=100000#xmsiz=256m


4、停止数据库
ps aux | grep ttserver | grep -v 'grep' | awk -F ' ' '{print $2}' | xargs kill -TERM

5、http调用
写 curl -X PUT http://127.0.0.1:8888/1 -d "ifyr"
读 curl http://127.0.0.1:8888/1
删 curl -X DELETE http://127.0.0.1:8888/1

6、使用C调用
1)直接写文件
#include <tcutil.h>
#include <tchdb.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

int main(int argc, char **argv) {
    TCHDB *hdb;
    int ecode;
    char *key, *value;

    /* create the object */
    hdb = tchdbnew();

    /* open the database */
    if(!tchdbopen(hdb, "ifyr.tch", HDBOWRITER | HDBOCREAT)) {
        ecode = tchdbecode(hdb);
        fprintf(stderr, "open error: %s\n", tchdberrmsg(ecode));
    }

    /* store records */
    if(!tchdbput2(hdb, "foo", "hello") ||!tchdbput2(hdb, "bar", "tokyo") ||!tchdbput2(hdb, "baz", "cabinet")) {
        ecode = tchdbecode(hdb);
        fprintf(stderr, "put error: %s\n", tchdberrmsg(ecode));
    }

    /* retrieve records */
    value = tchdbget2(hdb, "foo");
    if(value) {
        printf("%s\n", value);
        free(value);
    } else {
        ecode = tchdbecode(hdb);
        fprintf(stderr, "get error: %s\n", tchdberrmsg(ecode));
    }

    /* traverse records */
    tchdbiterinit(hdb);
    while((key = tchdbiternext2(hdb)) != NULL) {
        value = tchdbget2(hdb, key);
        if(value) {
            printf("%s:%s\n", key, value);
            free(value);
        }
        free(key);
    }

    /* remove records */
    if(!tchdbout2(hdb, "foo") ||!tchdbout2(hdb, "bar") ||!tchdbout2(hdb, "baz")) {
        ecode = tchdbecode(hdb);
        fprintf(stderr, "out error: %s\n", tchdberrmsg(ecode));
    }

    /* close the database */
    if(!tchdbclose(hdb)) {
        ecode = tchdbecode(hdb);
        fprintf(stderr, "close error: %s\n", tchdberrmsg(ecode));
    }

    /* delete the object */
    tchdbdel(hdb);
    return 0;
}

gcc -I/usr/local/include -L/usr/local/lib -ltokyotyrant -lm -lc -o test1 test1.c

2)使用网络读写
#include <tcrdb.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

int main(int argc, char **argv) {
    TCRDB *rdb;
    int ecode;
    char *value;

    /* create the object */
    rdb = tcrdbnew();

    /* connect to the server */
    if(!tcrdbopen(rdb, "localhost", 8888)) {
        ecode = tcrdbecode(rdb);
        fprintf(stderr, "open error: %s\n", tcrdberrmsg(ecode));
    }

    /* store records */
    if(!tcrdbput2(rdb, "foo", "hello") || !tcrdbput2(rdb, "bar", "toyko") ||
            !tcrdbput2(rdb, "baz", "cabinet")) {
        ecode = tcrdbecode(rdb);
        fprintf(stderr, "put error: %s\n", tcrdberrmsg(ecode));
    }

    /* retrieve records */
    value = tcrdbget2(rdb, "foo");
    if(value) {
        printf("%s\n", value);
        free(value);
    } else {
        ecode = tcrdbecode(rdb);
        fprintf(stderr, "get error: %s\n", tcrdberrmsg(ecode));
    }

    /* remove records */
    if(!tcrdbout2(rdb, "foo")) {
        ecode = tcrdbecode(rdb);
        fprintf(stderr, "out error: %s\n", tcrdberrmsg(ecode));
    }

    /* close the connection */
    if(!tcrdbclose(rdb)) {
        ecode = tcrdbecode(rdb);
        fprintf(stderr, "close error: %s\n", tcrdberrmsg(ecode));
    }
    /* delete the object */
    tcrdbdel(rdb);
    return 0;
}

gcc -I/usr/local/include -L/usr/local/lib -ltokyotyrant -lm -lc -o test2 test2.c

7、测试一万行数据(无任何优化)
写:
real    0m0.611s
user    0m0.080s
sys    0m0.150s

改:
real    0m0.596s
user    0m0.065s
sys    0m0.169s

查:
real    0m0.554s
user    0m0.085s
sys    0m0.177s

删:
real    0m0.773s
user    0m0.048s
sys    0m0.217s
发布于 5/28/2010 1:01:54 | 评论:0

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1168
  • 评论数:2011