[文章作者:张宴 本文版本: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) | 阅读(172848)
lonelyteers Email Homepage
2009-2-20 16:55
MIXI很强大 他们衍生的东西也不错 学习了。
CHEN Email
2009-2-24 20:12
你好
请问Tokyo Cabinet 能撑得住7000cps(写,读,删各一次)的访问吗?
最大的总数据量回维持在900GB的规模。

谢谢。
张宴 回复于 2009-2-24 23:55
总数据量900GB存在一个Tokyo Cabinet文件内太大,建议按照50GB分成多个Tokyo Cabinet文件存放。速度能支撑7000cps。
CHEN Email
2009-2-25 10:25
memcached 的客户端你建议使用哪一个?
按照50GB分成多个Tokyo Cabinet文件存放,这个还是存在一个机器里的吧。
分成多个Tokyo Cabinet文件对外透明吧?

谢谢
chen4059 Email
2009-2-25 12:06
如何分成多个Tokyo Cabinet文件存放呢?
xiaov
2009-3-10 10:14
tokyo tyrant 已经支持  table database 了,php该怎么用,memcache没有对应的api,还只能用数组?
tony
2009-4-23 17:56
请教个问题,为什么我在架设这个TT数据库的时候,指定了-ulog 参数,在这个目录下产生了巨大数量的日志文件,怎么能解决这个问题呢?shock
tony
2009-4-23 19:06
我先自己解释一下吧,我设置的-ulim 128m,但是这个参数没有起作用,实际产生的日志文件都只有一百多字节,因此产生了大量的碎文件,这个问题该如何解决呢?谢了!~~
tony
2009-4-23 20:23
sleepy
不好啥意思又来留言。。。。上面的问题是版本的原因,都换到最新版就OK了~~~~~
xyan
2009-4-27 10:21
php的memcache api不会自动把从tt取出来的数组反序列化, 要先判断如果不是数组unserializer一下
张宴 回复于 2009-4-27 10:43
自行unserializer就行了。
m
2009-5-11 09:47
您好,我最近对TC和TT性能做了一些测试,发现在大数据量时PHP的客户端出现大量插入失败的情况。还有就是数据量越大插入越慢,而且用的是HASH表,但是在读取上明显是先存入的读得更快,这个事情很不理解。以上不知道大哥遇到过没有。还请指教。
张宴 回复于 2009-5-11 11:47
我最近正在看TC的源代码,准备在其基础上开发一款SQL数据库。你说的情况主要跟tctdb.h文件中的以下这项参数有关,TC会在建一份与磁盘内容对应的内存镜像,这份内存对应表默认的大小为为64M,先存入数据在内存、磁盘都有内容,后存入的(超过64M)只在磁盘有内容,所以读写速度先存入的要快。可以设置tctdbsetxmsiz(tdb, 536870912); 512M或更大来解决这个问题,TT没有设置tctdbsetxmsiz,所以应该是使用默认的64M。我在TC基础上开发的SQL数据库会解决这个问题。

/* Set the size of the extra mapped memory of a hash database object.
   `hdb' specifies the hash database object which is not opened.
   `xmsiz' specifies the size of the extra mapped memory.  If it is not more than 0, the extra
   mapped memory is disabled.  The default size is 67108864.
   If successful, the return value is true, else, it is false.
   Note that the mapping parameters should be set before the database is opened. */
bool tchdbsetxmsiz(TCHDB *hdb, int64_t xmsiz);
m
2009-5-11 14:03
非常感谢您上面的解释。也期待您的新作。不过还有一个问题,就是我在采用长数据(1000字节的数据)进行存储时。在数据条数过多的情况下会出现大量的写入失败情况,此种情况在php和python的客户端的测试中都有出现。具体情况:1000字节长度的数据,我插入100W条,基本都会在30w-50w左右出现写入失败的情况。
tc
2009-5-26 17:02
我也发现类似的问题,我用java native api操作tokyo cabinet hdb(后简称tc),明明已经分别设置了setxmsiz和setcahce,这两个值设置为1073741824(也就是1024M)和1000000(100万),
但对tc根本没起作用,当插入数据时,只要数据达到70万以上,速度就非常之慢,而此时tc只使用了150M左右内存。看着tc空着大量内存不用,而拼命地进行硬盘IO,真让人不得其解。
sad
2009-6-24 13:08
kong Email
2009-7-8 19:04
我用gbk编码格式写入中文到ttserver。用php的memcache自带的类读取出来全是乱码 如何解决?
小皮 Email
2009-7-9 12:29
用php-memcache插入,连续相同字符串就会是乱码,怪了
time2k
2009-7-9 17:47
--------在32位操作系统下,作为 Tokyo Tyrant 后端存储的 Tokyo Cabinet 数据库单个文件不能超过2G,而64位操作系统则不受这一限制。所以,如果使用 Tokyo Tyrant,推荐在64位CPU、操作系统上安装运行。---------------

其实不用,在编译Tokyo cabinet的时候,使用如下编译选项就可以突破2G限制
--enable-off64  

另附Tokyo cabinet编译参数:
Options of Configure
The following options can be specified with `./configure'.

--enable-debug : build for debugging. Enable debugging symbols, do not perform optimization, and perform static linking.
--enable-devel : build for development. Enable debugging symbols, perform optimization, and perform dynamic linking.
--enable-profile : build for profiling. Enable profiling symbols, perform optimization, and perform dynamic linking.
--enable-static : build by static linking.
--enable-fastest : build for fastest run.
--enable-off64 : build with 64-bit file offset on 32-bit system.
--enable-swab : build for swapping byte-orders.
--enable-uyield : build for detecting race conditions.
--disable-zlib : build without ZLIB compression.
--disable-bzip : build without BZIP2 compression.
--disable-pthread : build without POSIX thread support.
--disable-shared : avoid to build shared libraries.
haitao
2009-8-4 20:27
hi,谢谢张宴的文章,详细测试了tokyo,遇到一个同步问题,不知大家遇到过不。使用的是master-master方式,使用版本:Tokyo Cabinet 版本 1.4.29和1.4.30,Tokyo Tyrant 版本 1.1.24(从这下的http://tokyocabinet.sourceforge.net/misc/,目前2009.8.4最新版本是不是这个呢?官方链接对下载包管理有些乱)。用的是B+Tree方式。

出现的问题,运行master-master过程中,有请求发到master1,这个时候停止master2,模拟现网一台down掉情况,然后重启,重启后导致可能出现:
A, 数据同步不一致;

B, 一个或两个master cpu空转,即使没有新请求过来时,cpu占用高,有时耗尽cpu。

以上两个问题有时出现一个,有时出现两个,有时都不出现,存在风险。请教下大家遇到过不?怎么解决。

另外看了以上留言,测试发现hash方式在数据量大于设置的内存cache后,iowait会极高,有时达到99%,直接用自带工具写入1000万条一测就能发现,写到600万时,再也难以写进去,所以觉得hash方式有很大问题。改用B+Tree方式没这个问题。

引用张宴的:。。。Tokyo Tyrant 版本升级到 1.1.29
xifan
2009-8-15 01:53
我使用了ttserver来做点击率统计.由于点击率非常大.导致服务器time_wait也很高..
[oopp@web-* ~]# netstat -n |grep TIME_WAIT |awk '/^tcp/ {print $5 }' |awk -F : ' {++S[$1]} END {for(a in S) print a, S[a]}' |sort -k 2rn |head -n 10
192.*.*.74 35779
127.0.0.1 3251
192.*.*.* 3140
192.*.*.* 584
192.*.*.* 450
192.*.*.* 322
192.*.*.* 294
主要是192.*.*.74 用于点击率统计的.
内核参数我已经修改过
但是效果还是不明显.不知道大虾有办法解决么
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 15
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 30
xifan Email
2009-8-15 01:55
请大师指点一下...
haitao Email
2009-9-7 16:11
为了感谢张宴的文章,我回复一个要注意用最新tokyo版本的B+Tree方式,而不是官方推荐或默认的hash方式,前面我提了tokyo版本问题,现在已经自己找到解决办法。

注:老版本有很多bug,新的使用者请注意不要取到比下面旧的版本,官方网页在下载包管理上目前较零乱,需要注意。

Tokyocabine目前最新版本1.4.30:
http://tokyocabinet.sourceforge.net/

tokyotyrant目前最新版本
tokyotyrant-1.1.33.tar.gz
21-Jul-2009 02:33   181K
http://tokyocabinet.sourceforge.net/tyrantpkg/

以前版本以及最新版本的Hash方式在数据量大于设置的内存cache时iowait急剧升高导致系统不可用,而B+Tree方式OK。注意这点后tokyo就是一个非常好的解决方案了。注意注意!
分页: 2/7 第一页 上页 1 2 3 4 5 6 7 下页 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]