作者:傲气战歌网 来源:www.27zg.com 发表时间:2012-07-02 01:05
Tokyo Cabinet是日本人平林幹雄开发的一款DBM数据库,该数据库读写非常快。但是单单的TC数据库,用处不大,宿主程序需要进行很多开发。TC的作者开发了Tokyo Tyrant(TT)这个网络服务程序,除了自己的二进制协议,还提供了现在被广泛应用的HTTP协议,memcached协议来访问TC数据库,这样一来,一下子就扩展了TC的使用范围,让TC从一个单纯的开发库变成了易用,高效的数据库系统。战歌网
Tokyo Tyrant是由同一作者开发的 Tokyo Cabinet 数据库网络接口。它拥有Memcached兼容协议,也可以通过HTTP协议进行数据交换。
Tokyo Tyrant 加上 Tokyo Cabinet,构成了一款支持高并发的分布式持久存储系统,对任何原有Memcached客户端来讲,可以将Tokyo Tyrant看成是一个Memcached,但是,它的数据是可以持久存储的。
#建立Tokyo Tyrant日志及数据存放目录mkdir /ttserver
复制代码#下载安装tokyocabinetwget
tar zxvf tokyocabinet-1.3.17.tar.gz
cd tokyocabinet-1.3.17/
./configure
make
make install
cd ../
复制代码#下载安装tokyotyrantwget ... tyrant-1.1.7.tar.gz
tar -xzvf tokyotyrant-1.1.7.tar.gz
cd tokyotyrant-1.1.7
./configure --prefix=/usr/local/tokyotyrant
make
make install
复制代码#启动Tokyo Tyrant服务器端
如果大量的客户端访问ttserver,请确保文件描述符够用。许多服务器的默认文件描述符为1024,可以在启动ttserver前使用ulimit命令提高这项值。例如:ulimit -SHn 51200
复制代码启动的时候,根据参数dbname名来确定使用的TC数据库类型。如果为"*",则使用内存hash表,如果为"+",则使用内存B+库,如果后缀为".tch",则使用hash表,如果后缀为".tcb",则使用B+树数据库,如果后缀为".tcf",则使用定长数组。如果dbname参数被省略,则采用内存hash数据库。
在ttserver众多的启动参数中,有两个参数在正式使用时非常有用,-mask expr, -unmask expr,分别是禁止的命令,允许的命令。在正式使用时,最好能把vanish(删除所有数据)屏蔽掉,就像linux系统中把rm -rf * 屏蔽了一样。
参数解释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] [-ext path] [-mask expr] [-unmask expr] [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 : 指定用来存放同步时间戳的文件名。
-ext path : 扩展的脚本文件
-mask expr : 需要禁止的命令,多个命名用","隔开
-unmaks expr : 允许的命令
复制代码不同数据库类型的详细配置参数解析
下面我们再来看下数据库类型的详细配置。
* 数据库名的命名方式被Tokyo Cabinet的抽象API指定。
* 如果数据库名为"*",表示内存hash数据库。
* 如果数据库名为"+"表示内存tree数据库。
* 如果数据库名为".tch",则数据库为hash数据库。
* 如果数据库名的后缀为".tcb",数据库将为B+ tree数据库。
* 如果数据库名的后缀为".tcf"。则数据库将为fixed-length数据库。
* 如果数据库名的后缀为".tct",则数据将为一个table数据库(有表的概念)。
数据库的调整参数通过数据库名的延伸来指定,通过"#"分开,每个参数通过一个参数名和值来指定,用"="隔开。
内存hash数据库支持"bnum", "capnum", 和 "capsiz"
内存tree数据库支持"capnum" 和 "capsiz"
capnum指定记录的最大容量,capsiz指定最大的内存使用量(在内存数据库中),记录通过存储的顺序移除。
hash数据库支持"mode", "bnum", "apow", "fpow", "opts", "rcnum", 和 "xmsiz".
`rcnum'指定最大的缓存记录数。如果它不大于零,那么缓存记录不可用。默认不可用。
xmsiz 指定外部内存的大小。如果不大于0,内存不可用。默认是67108864,即64M。
`bnum' 指定bucket存储桶的数量。如果指定的数目不大于0,将会使用默认的数值131071.推荐数量应该在所有需要存储的记录总数的0.4-4倍
`apow' 跟一个key关联的记录数,2的N次方表示. 如果不指定,默认2^4=16.
`fpow' specifies the maximum number of elements of the free block pool by power of 2. 默认2^10=1024.
`opts' 指定选项,位或:`HDBTLARGE' 指定数据库的大小通过使用64位数组桶能够超过2G。
`HDBTDEFLATE' 指定每个记录被Deflate encoding压缩。
`HDBTBZIP' 指定每个记录被BZIP2 encoding压缩
`HDBTTCBS'指定每个记录被 TCBS encoding压缩.
B+ tree数据库支持"mode", "lmemb", "nmemb", "bnum", "apow", "fpow", "opts", "lcnum", "ncnum", 和 "xmsiz".
Fixed-length 数据库 支持 "mode", "width", and "limsiz".
Table 数据库支持 "mode", "bnum", "apow", "fpow", "opts", "rcnum", "lcnum", "ncnum", "xmsiz", 和 "idx"
"idx"指定表的索引。
"mode"可以包含 "w" 写, "r" 读, "c" 创建, "t" 截断,"e" 无锁,和"f" 非阻塞锁。默认的的mod为"wc"。
复制代码优化性能
如果使用hash数据库我们可以指定#bnum=**来提高性能。**大于或等我我们的记录总数。
如果使用B+ tree数据库我们可以通过指定"#lcnum=**#bnum=yyy" 来提高性能.第一个参数指定被缓存的最大叶子节点数,受内存容量限制,第二个参数指定桶的数量,它应该大于总记录数的1/128.
如果有大量的客户端连接,确保我们的文件描述符够用。系统默认是1024,我们可以用使用“ulimit”来重新设定
启动命令/usr/local/tokyotyrant/bin/ttserver -host 192.168.137.64 -port 11211 -thnum 8 -dmn -pid /ttserver/ttserver.pid -log /ttserver/ttserver.log -le -ulog /ttserver/ -ulim 128m -sid 1 -rts /ttserver/ttserver.rts /ttserver/database.tch#bnum=1000000
复制代码如果不想这么麻烦的启动,可以使用ttservctl简单的命令来控制。ttservctl start,stop,restart,hup。使用这个命令,数据库文件位于/var/ttserver/casker.tch,log等相关文件位于/var/ttserver。
# 关闭服务cat /ttserver/ttserver.pid | xargs kill -TERM
复制代码#
配置主从的一个例子
TT服务端(主)/usr/local/tokyotyrant/bin/ttserver -port 11211 -thnum 16 -dmn -le -ulog /data/ttcache/ -ulim 128m -sid 1 -rts /data/ttcache/ttserver.rts /data/ttcache/database.tch#bnum=100000
复制代码TT客户端(从)/usr/local/tokyotyrant/bin/ttserver -port 11211 -sid 1 -mhost 192.168.0.1 -mport 11211 -thnum 16 -dmn -le -ulog /data/ttcache/ -ulim 128m -rts /data/ttcache/ttserver.rts /data/ttcache/database.tch#bnum=100000
复制代码调用
1、任何Memcached客户端均可直接调用tokyotyrant。
2、还可以通过HTTP方式调用,下面以Linux的curl命令为例,介绍如何操作tokyotyrant:
(1)、写数据,将数据“value”写入到“key”中:curl -X PUT :11211/key -d "value"
复制代码(2)、读数据,读取“key”中数据:curl :11211/key
复制代码(3)、删数据,删除“key”:curl -X DELETE :11211/key
复制代码# 利用memcache协议存取Tokyo Tyrant
add ($key, $val, $exp = 0)
往 TT 中写入对象,$key 是对象的唯一标识符,$val 是写入的对象数据,$exp 为过期时间,单位为秒,默认为不限时间;
get ($key)
从 TT 中获取对象数据,通过对象的唯一标识符 $key 获取;
replace ($key, $value, $exp=0)
使用 $value 替换 TT 中标识符为 $key 的对象内容,参数与 add() 方法一样,只有 $key 对象存在的情况下才会起作用;
delete ($key, $time = 0)
删除 TT 中标识符为 $key 的对象,$time 为可选参数,表示删除之前需要等待多长时间。
下面是一段简单的测试代码,代码中对标识符为 ‘mykey’ 的对象数据进行存取操作:
PHP代码://需要安装php的memcahce扩展 就不用包含外部memcache类文件了
// 选项设置
// 创建 memcache 对象实例
$mc=new Memcache();
$mc->addServer('127.0.0.1',11211); //添加tt服务器端ip和端口 可以多个
$mc->addServer('127.0.0.2',11211);
// 设置此脚本使用的唯一标识符
$key = "mykey";
// 往 TT 中写入对象
$mc->add($key, "some random strings");
$val = $mc->get($key);
echo "n".str_pad("$mc->add() ", 60, "_")."n";
var_dump($val);
// 替换已写入的对象数据值
$mc->replace($key, array("some"=>"haha", "array"=>"**"));
$val = $mc->get($key);
echo "n".str_pad("$mc->replace() ", 60, "_")."n";
var_dump($val);
// 删除 TT 中的对象
$mc->delete($key);
$val = $mc->get($key);
echo "n".str_pad("$mc->delete() ", 60, "_")."n";
var_dump($val);
?>
复制代码#实时查看监控数据命令watch "echo stats | nc 192.168.12.6 11211"
Every 2.0s: echo stats | nc 192.168.12.6 11211 Thu Feb 12 18:32:57 2009
STAT pid 18860
STAT uptime 7973
STAT time 1234434777
STAT version 1.1.7
STAT rusage_user 7.550852
STAT rusage_system 17.756300
STAT curr_items 100000
STAT bytes 7398720
END
# 效率测试
我们用tokyotyrant自带的工具tcrmttest,用来测试(多线程)对Tokyo Tyrant网络接口的写入、读取移动做效率测试。
# 查看tcrmttest工具的帮助及参数
cd /usr/local/tokyotyrant/bin/
./tcrmttest
./tcrmttest: test cases of the remote database API of Tokyo Tyrant
usage:
./tcrmttest write [-port num] [-tnum num] [-nr] [-ext name] [-rnd] host rnum
./tcrmttest read [-port num] [-tnum num] [-mul num] host
./tcrmttest remove [-port num] [-tnum num] host
./tcrmttest write -port 11211 192.168.137.64 100000
<Writing Test>
host=192.168.137.64 port=11211 tnum=1 rnum=100000 nr=0 ext= rnd=0
......................... (00010000)
......................... (00020000)
......................... (00030000)
......................... (00040000)
......................... (00050000)
......................... (00060000)
......................... (00070000)
......................... (00080000)
......................... (00090000)
......................... (00100000)
record number: 2103120
size: 1245941232
time: 636.535
ok
复制代码在已经有2百万数据的基础上追加10万数据,2百万数据占用数据库文件大小约为1.2G,平均每条数据用0.00637秒,平均每秒158条记录(该服务器为一台1u服务器做服务器端 2G物理内存 cpu为双核In【系统屏蔽非法词汇】(R) Xeon(TM) CPU 2.80GHz 32位平台)。
重新配置Tokyo Tyrant一台服务器,试试从0条数据写入的效率(该服务器为一台1u服务器做服务器端 2G物理内存 cpu为双核In【系统屏蔽非法词汇】(R) Xeon(TM) CPU 2.40GHz 32位平台)。# ./tcrmttest write -port 11211 192.168.12.6 100000
<Writing Test>
host=192.168.12.6 port=11211 tnum=1 rnum=100000 nr=0 ext= rnd=0
......................... (00010000)
......................... (00020000)
......................... (00030000)
......................... (00040000)
......................... (00050000)
......................... (00060000)
......................... (00070000)
......................... (00080000)
......................... (00090000)
......................... (00100000)
record number: 100000
size: 7398720
time: 6.845
ok
复制代码平均每条插入时间为0.006845秒,每秒插入14609条记录。
两台服务器硬件及负载相当,看来原有的数据库文件大小的插入效率有很大影响,那么读取数据的效率呢?
继续测试。./tcrmttest read -port 11211 192.168.12.6
<Reading Test>
host=192.168.12.6 port=11211 tnum=1 mul=0 rnd=0
......................... (00010000)
......................... (00020000)
......................... (00030000)
......................... (00040000)
......................... (00050000)
......................... (00060000)
......................... (00070000)
......................... (00080000)
......................... (00090000)
......................... (00100000)
record number: 100000
size: 7398720
time: 5.559
ok
复制代码每秒约读取17989条记录。
前段时间做过一个压力测试
名词解释
最大:缓存命中率约为0时的响应时间
最小:缓存命中率约为100%时的响应时间
平均:缓存命中率从0~100%的平均响应时间
平稳:系统平稳时的响应时间(约等于最小)
数据访问时间:从数据发起请求到数据下载完毕的时间间隔。
命中率:系统已有内存缓存的数据与总测试数据相比的百分比。
实验环境硬件:
一台pc机做TT客户端 2G物理内存 cpu为In【系统屏蔽非法词汇】(R) Pentium(R) 双核核 CPU 2.40GHz
一台1u服务器做TT服务器端 4G物理内存 cpu为双核In【系统屏蔽非法词汇】(R) Xeon(TM) CPU 2.80GHz
软件环境:tc的数据库大约是1.2G ,保存单元300多万
测试方法
使用1-1000000写入的key的对应value值,通过Tokyo Tyrant的http网络接口,组合URL,通过LoadRunner模拟大并发访问该URL。
结论
不同并发对数据访问时间的长短影响比较明显,并发数越高数据访问时间越长。根据测试中的平均时间数据与平稳时间数据之比,预计用户查词未命中内存缓存访问时间是未命中内存缓存数据访问时间的3倍左右。该架构性能良好,在测试中为发现有效服务器错误。
测试数据,在内存缓存命中率100%下平稳数据访问时间:
2000并发平稳数据访问时间为0.31秒,1000并发时为0.19秒。
tt的接口没有显示并发数的功能
我用的方法 watch "netstat -ant |grep 192.168.xx.xx:11211 |wc -l"