menu

秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

安装Tokyo Cabinet & Tokyo Tyrant的过程记录

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