[文章作者:张宴 本文版本:v1.4 最后修改:2010.06.11 转载请注明原文链接:http://blog.zyan.cc/read.php/362/]

  Tokyo Cabinet 是日本人 平林幹雄 开发的一款 DBM 数据库,该数据库读写非常快,哈希模式写入100万条数据只需0.643秒,读取100万条数据只需0.773秒,是 Berkeley DB 等 DBM 的几倍。

  点击在新窗口中浏览此图片



  Tokyo Tyrant 是由同一作者开发的 Tokyo Cabinet 数据库网络接口。它拥有Memcached兼容协议,也可以通过HTTP协议进行数据交换。

  Tokyo Tyrant 加上 Tokyo Cabinet,构成了一款支持高并发的分布式持久存储系统,对任何原有Memcached客户端来讲,可以将Tokyo Tyrant看成是一个Memcached,但是,它的数据是可以持久存储的。这一点,跟新浪的Memcachedb性质一样。

  相比Memcachedb而言,Tokyo Tyrant具有以下优势:

  1、故障转移:Tokyo Tyrant支持双机互为主辅模式,主辅库均可读写,而Memcachedb目前支持类似MySQL主辅库同步的方式实现读写分离,支持“主服务器可读写、辅助服务器只读”模式。

  点击在新窗口中浏览此图片

  这里使用 $memcache->addServer 而不是 $memcache->connect 去连接 Tokyo Tyrant 服务器,是因为当 Memcache 客户端使用 addServer 服务器池时,是根据“crc32(key) % current_server_num”哈希算法将 key 哈希到不同的服务器的,PHP、C 和 python 的客户端都是如此的算法。Memcache 客户端的 addserver 具有故障转移机制,当 addserver 了2台 Memcached 服务器,而其中1台宕机了,那么 current_server_num 会由原先的2变成1。

  引用 memcached 官方网站和 PHP 手册中的两段话:
引用
http://www.danga.com/memcached/
If a host goes down, the API re-maps that dead host's requests onto the servers that are available.

http://cn.php.net/manual/zh/function.Memcache-addServer.php
Failover may occur at any stage in any of the methods, as long as other servers are available the request the user won't notice. Any kind of socket or Memcached server level errors (except out-of-memory) may trigger the failover. Normal client errors such as adding an existing key will not trigger a failover.




  2、日志文件体积小:Tokyo Tyrant用于主辅同步的日志文件比较小,大约是数据库文件的1.3倍,而Memcachedb的同步日志文件非常大,如果不定期清理,很容易将磁盘写满。



  3、超大数据量下表现出色:

  点击在新窗口中浏览此图片

  但是,Tokyo Tyrant 也有缺点:在32位操作系统下,作为 Tokyo Tyrant 后端存储的 Tokyo Cabinet 数据库单个文件不能超过2G,而64位操作系统则不受这一限制。所以,如果使用 Tokyo Tyrant,推荐在64位CPU、操作系统上安装运行。



  一、安装
  1、首先编译安装tokyocabinet数据库
wget http://www.1978th.net/tokyocabinet/tokyocabinet-1.4.45.tar.gz
tar zxvf tokyocabinet-1.4.45.tar.gz
cd tokyocabinet-1.4.45/
./configure
#注:在32位Linux操作系统上编译Tokyo cabinet,请使用./configure --enable-off64代替./configure,可以使数据库文件突破2GB的限制。
#./configure --enable-off64
make
make install
cd ../


  2、然后编译安装tokyotyrant
wget http://www.1978th.net/tokyotyrant/tokyotyrant-1.1.40.tar.gz
tar zxvf tokyotyrant-1.1.40.tar.gz
cd tokyotyrant-1.1.40/
./configure
make
make install
cd ../




  二、配置
  1、创建tokyotyrant数据文件存放目录
mkdir -p /ttserver/


  2、启动tokyotyrant的主进程(ttserver)
  (1)、单机模式
ulimit -SHn 51200
ttserver -host 127.0.0.1 -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.tcb#lmemb=1024#nmemb=2048#bnum=10000000


  (2)、双机互为主辅模式
  服务器192.168.1.91:
ulimit -SHn 51200
ttserver -host 192.168.1.91 -port 11211 -thnum 8 -dmn -pid /ttserver/ttserver.pid -log /ttserver/ttserver.log -le -ulog /ttserver/ -ulim 128m -sid 91 -mhost 192.168.1.92 -mport 11211 -rts /ttserver/ttserver.rts /ttserver/database.tcb#lmemb=1024#nmemb=2048#bnum=10000000


  服务器192.168.1.92:
ulimit -SHn 51200
ttserver -host 192.168.1.92 -port 11211 -thnum 8 -dmn -pid /ttserver/ttserver.pid -log /ttserver/ttserver.log -le -ulog /ttserver/ -ulim 128m -sid 92 -mhost 192.168.1.91 -mport 11211 -rts /ttserver/ttserver.rts /ttserver/database.tcb#lmemb=1024#nmemb=2048#bnum=10000000


  (3)、参数说明
  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=1000000”,就可以将最新最热的100万条记录缓存在内存中:
ttserver -host 127.0.0.1 -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


  如果大量的客户端访问ttserver,请确保文件描述符够用。许多服务器的默认文件描述符为1024,可以在启动ttserver前使用ulimit命令提高这项值。例如:
ulimit -SHn 51200


  3、停止tokyotyrant(ttserver)
ps -ef | grep ttserver

  找到ttserver的进程号并kill,例如:
kill -TERM 2159




  三、调用
  1、任何Memcached客户端均可直接调用tokyotyrant。

  2、还可以通过HTTP方式调用,下面以Linux的curl命令为例,介绍如何操作tokyotyrant:
  (1)、写数据,将数据“value”写入到“key”中:
curl -X PUT http://127.0.0.1:11211/key -d "value"


  (2)、读数据,读取“key”中数据:


  (3)、删数据,删除“key”:




  附:文章修改历史

  ● [2008年08月07日] [Version 1.0] 撰写本文

  ● [2008年10月16日] [Version 1.1] Tokyo Cabinet 版本升级到 1.3.12;Tokyo Tyrant 版本升级到 1.1.5

  ● [2008年12月04日] [Version 1.2] Tokyo Cabinet 版本升级到 1.3.22;Tokyo Tyrant 版本升级到 1.1.8

  ● [2008年07月06日] [Version 1.3] Tokyo Cabinet 版本升级到 1.4.28;Tokyo Tyrant 版本升级到 1.1.29

  ● [2010年06月11日] [Version 1.4] Tokyo Cabinet 版本升级到 1.4.45;Tokyo Tyrant 版本升级到 1.1.40;默认示例改为B+Tree数据库;增加32位Linux操作系统上编译Tokyo cabinet的configue配置。





技术大类 » Cache与存储 | 评论(124) | 引用(7) | 阅读(173268)
vv
2009-9-10 10:33
超级便宜的机票网站.
paddy
2009-9-20 21:34
dbcached 什么时候可以支持memcached1.4系列 nmdb支持2.22系列啊?

1.2系列的memcached在性能和效能上不如1.4系列

nmdb2.22支持了tc(tokyo)协议.
startup
2009-10-15 21:03
您说的Tokyo Tyrant支持java吗?如果支持的话,如果将session存储?您那里有比较成功的实例和方案吗?
看了您的文章,也动手搭建了,只是不知道对于没有使用memcache的也能Tokyo Tyrant吗?
postbb
2009-10-27 14:40
直接用php5的memcache类:
$this->memcache = new Memcache;

如果是连接memcache 数据库的话,在php中可以直接
set/get对象class,如果set 的是对象,get出来的时候就自动完成了序列化了。

但是用ttserver的时候,需要自己序列化和反序列化一下,否则set进去的是对象,get出来的是对象的序列化后的字符串。
function get($key)
    {
      return unserialize($this->memcache->get($key));
    }
    function set($key,$value,$flag=0,$expire=3600)
    {
      return $this->memcache->set($key,serialize($value),$flag,$expire);
    }

感觉效率上不如memcached,没做具体的数据测试,但是我的页面明显感觉慢了一点点。
postbb
2009-10-27 14:41
直接用php5的memcache类:
$this->memcache = new Memcache;

如果是连接memcache 数据库的话,在php中可以直接
set/get对象class,如果set 的是对象,get出来的时候就自动完成了序列化了。

但是用ttserver的时候,需要自己序列化和反序列化一下,否则set进去的是对象,get出来的是对象的序列化后的字符串。
function get($key)
    {
      return unserialize($this->memcache->get($key));
    }
    function set($key,$value,$flag=0,$expire=3600)
    {
      return $this->memcache->set($key,serialize($value),$flag,$expire);
    }

感觉效率上不如memcached,没做具体的数据测试,但是我的页面明显感觉慢了一点点。
bluesky
2009-10-30 09:12
我最近在测试tt,用java的spy客户端,我写入小数据量的数据,tt的并发非常的的好,可是我向tt里面写入2M左右的数据,感觉tt的并发就不太好了,我开多个client向里面写数据时,经常有超时的现象,请问如何解决啊?有什么方案吗?
张宴 回复于 2009-11-2 06:11
数据库类型换成b+tree表tcb
tc
2009-11-9 07:55
众所周知,hash算法的时间复杂度为 O(1),而btree的时间复杂度是O(log n)

所以从算法上说,当数据量越大时,采用tc中的hash方式的性能应该越好,为什么现在的结果却是相反?

会不会是下面这几个参数使用了默认值导致的?

setxmsiz()
setcache()
optimize()
2009-11-25 09:15
我在gentoo下面装了tt,使用正常.
但当机器poweroff或reboot后再启动tt就会报Error the process 4411 may be already running之类的.
求解
ccw
2009-12-17 12:02
[root@localhost tokyotyrant-1.1.39]# make
LD_RUN_PATH=/lib:/usr/lib:/usr/local/lib:/root/lib:/usr/local/lib:/usr/local/lib:. gcc -g -O2 -std=c99 -Wall -fPIC -fsigned-char -O2 -o ttserver ttserver.o scrext.o -L. -L/usr/local/lib -L/root/lib -L/usr/local/lib  -ltokyotyrant -ltokyocabinet -lbz2 -lz -lresolv -lnsl -ldl -lrt -lpthread -lm -lc
ttserver.o(.text+0x12ed): In function `main':
/home/ccw/tokyotyrant-1.1.39/ttserver.c:610: undefined reference to `tcadbsetskelmulti'
ttserver.o(.text+0xbd41): In function `do_http_post':
/home/ccw/tokyotyrant-1.1.39/ttserver.c:3318: undefined reference to `tcwwwformdecode2'
collect2: ld returned 1 exit status

编译 1.0.1 的不会有错。
sjbrising Email
2010-2-5 17:21
大哥,你85年出生的啊,比我大一岁就这么厉害了!!!佩服啊!!!

您有没有memcache或是Tokyo Tyrant的实例代码分享一下学习学习。
如果有发到我邮箱sjbup@live.cn。谢谢!
王小呆
2010-2-28 15:31
请教下大虾,我用tchmttest进行测试,插入了1千万条记录,查看了下数据文件是306MB,
然后我再用tchmttest把插入的数据删除,但数据文件大小却还是306MB,
是不是tc的数据文件size只增不减啊,如果删除,它所占用的文件空间不会减少?

拜谢!
cer24 Email Homepage
2010-3-25 00:20
很疑惑为什么使用hash之后效率会出现瓶颈?
有没有哪位能够告知啊?谢谢!

cer24
wugenlin0815 Email
2010-4-7 18:30
在使用TT时发现不稳定,导致服务死掉场景:3200万条记录使用硬盘Hash数据库,数据文件大小在5G左右.......database.tch#bnum=100000000#xmsiz=5g每隔十天半个月的就死一次日志里会出现一些如下信息:ERROR   do_mc_set: operation failed版本信息:tokyocabinet-1.4.32.tar.gz     tokyotyrant-1.1.33.tar.gz一直被这问题困扰很久,不知各位大老是否遇到过这种情况?有什么办法解决?无忧买卖网
爱好者
2010-4-26 21:20
tokyotyrant 目前只提供tokyotyrant-1.1.31.tar.gz   1.32 1.33  1.40编译通不过,大家看看,我遇到了。。。
1987
2010-5-18 16:06
能不能介绍一下tt的底层原理呢?

我想知道的是: 当我插入数据以后是立马写入数据库中,还是放在内存中,然后有个机制统一入库.

如果是及时入库,怎么做到的这么高效率?
abc
2010-6-24 11:14
tch数据格式如何转化成tcb?
白开水
2010-6-25 16:36
张宴你好,为什么我用双机互为主辅模式,主辅不能同步数据呢?
日志错误信息:
2010-06-25T16:22:04+08:00       ERROR   do_slave: tcreplopen failed
白开水
2010-6-25 17:42
已经好了,可以同步了,两面如果同时写的话两边的键不能相同
dreaminto Email
2010-8-4 16:22
我启动TT后,用Php写入数据就没有问题。但用java写入数据时,总不成功。但只要停止TT的服务后,就可以正常写入,请教我需要如何修改配置呢?

我用的是
tokyocabinet-1.4.32
tokyotyrant-1.1.33
tokyocabinet-java-1.22

JAVA的代码如下:
    HDB hdb = new HDB();
    System.out.println("0");
    // open the database
    if(!hdb.open("casket.tch", HDB.OWRITER | HDB.OCREAT)){
      int ecode = hdb.ecode();
      System.err.println("open error: " + hdb.errmsg(ecode));
    }
    System.out.println("1");

    // store records
    if(!hdb.put("foo", "hop") ){
      int ecode = hdb.ecode();
      System.err.println("put error: " + hdb.errmsg(ecode));
    }
跟踪代码执行时:可以打印“0”,但“1”就打印不出来了,不知道open函数还有别的使用方法吗?
dreamit
2010-9-8 12:43
请问一下TTSERVER 单机模式, 因为断电,数据库的大小等等依然不变,但里面的数据为空(用stats查看),有什么解决办法吗?跪求中。。。
分页: 3/7 第一页 上页 1 2 3 4 5 6 7 下页 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]