您的位置:首页 > 其它

Tokyo Tyrant(TTServer)系列-介绍和安装

2013-01-07 10:57 387 查看
Tokyo Tyrant(TTServer)系列-介绍和安装

Tokyo Cabinet 是日本人 Mikio Hirabayashi(平林幹雄)のページ 开发的一款DBM数据库(注:大名鼎鼎的DBM数据库qdbm就是他开发的),该数据库读写非常快。insert:0.4sec/1000000 recordes(2500000qps),写入100万数据只需要0.4秒。search:0.33sec/1000000 recordes (3000000 qps),读取100万数据只需要0.33秒。下图为各种key-value数据库读写数据的性能测试,可以看出Tokyo Cabinet的速度是非常快的。



Tokyo Tyrant 提 供dbm数据库Tokyo Cabinet的网络接口。它使用简单的基于TCP/IP的简单二进制协议进行通信。同时它拥有Memcached兼容协议并且可以用HTTP/1.1协 议进行数据交换。所以实现了跨平台,跨语言使用Tokyo Tyrant。采用热备份,更新日志记录,复制(replication)来实现高可用性和高可靠性。到目前为止,Tokyo Tyrant只能运行在inux, FreeBSD, Mac OS X, Solaris。

下面我们介绍如何安装Tokyo Tyrant。

首先我们安装Tokyo Cabinet.

#wget http://tokyocabinet.sourceforge.net/tokyocabinet-1.4.9.tar.gz
#tar -xzvf tokyocabinet-1.4.9.tar.gz

# cd tokyocabinet-1.4.9

# ./configure

# make

# make install

OK,我们装好了Tokyo Cabinet,再继续安装Tokyo Tyrant。

# wget http://tokyocabinet.sourceforge.net/tyrantpkg/tokyotyrant-1.1.16.tar.gz
# tar -xzvf tokyotyrant-1.1.16.tar.gz

#cd tokyotyrant-1.1.16

# ./configure

# make

#make install

OK,我们目前就完成了Tokyo Tyrant的安装。安装非常的简单。安装好的Tokyo Tyrant的启动程序文件叫ttserver,所以我们也简称ttserver.下面我们简单启动一个数据库,测试我们是否安装成功。

# ./ttservctl start

启动完成。这是自带的一个启动脚本,你可以拷贝到到任意目录,修改里面的参数。

# telnet 127.0.0.1 1978

然后我们telnet到1978端口,因为刚才的脚本默认启动的数据库使用了1978端口。

如果顺利,你可以看到可以连通,键入stats然后回车,可以看到一些类似如下的状态信息

stats

STAT pid 24755

STAT uptime 37

STAT time 1236396011

STAT version 1.1.16

STAT rusage_user 0.000000

STAT rusage_system 0.008998

STAT curr_items 0

STAT bytes 4198720

END

  请注意:在32位操作系统下,Tokyo Cabinet的单个数据库文件不能超过2G,而在64位操作系统下则没有这一限制。所以推荐使用64位操作系统和CPU。

Tokyo Tyrant(TTServer)系列-启动参数和配置

启动参数介绍

ttserver命令可以启动一个数据库实例。因为数据库已经实现了Tokyo Cabinet的抽象API,所以可以在启动的时候指定数据库的配置类型。

支持的数据库类型有:

1、内存hash数据库

2、内存tree数据库

3、hash数据库

4、B+ tree数据库

命令通过下面的格式来使用,‘dbname’制定数据库名,如果省略,则被视作内存hash数据库。

ttserver [-host name] [-port num] [-thnum num] [-tout num] [-dmn] [-pid path] [-log path] [-ld|-le] [-ulog path] [-ulim num] [-uas] [-sidnum] [-mhost name] [-mport num] [-rts path] [-ext path] [-extpc name period] [-mask expr] [dbname]

下面来说这些参数的功能:

• -host name :指明服务器的hostname或者ip地址。默认服务器的所有地址都会被绑定。比如:指定127.0.0.1这样的ip,就只是本地可以访问了。

• -port num : 指定服务启动的端口. 默认1978.如果要启动多个数据库实例,端口需要不一样。

• -thnum num : 指定服务工作的线程数。默认8.

• -tout num : 指定每个会话的超时时间。默认永不超时。

• -dmn : 以守护进程方式运行。

• -pid path : 输出进程IP到指定的文件。

• -log path : 输出日志信息到指定文件。

• -ld : 日志中记录debug信息。

• -le :日志中只记录错误信息。

• -ulog path : 指定存放更新日志(update log)的目录.可以用来备份恢复数据库,主从库之间的同步。

• -ulim num : 指定每个更新日志文件的大小限制.

• -uas :使用异步IO记录更新日志。(使用此项可以减少写入日志的IO开销,但是在服务器意外关机,进程被kill时可能会丢失数据。根据经验,一般可以不使用)。

• -sid num : 指定服务的ID号。主从复制的时候通过不同的ID号来识别。

• -mhost name : 指定主从复制模式下的主服务器的IP或域名。

• -mport num : 指定主从模式下主服务器的端口号.

• -rts path : 指定用于主从复制的时间戳存放文件.

• -ext path : 指定扩展脚本语言文件。

• -extpc name period : 指定被周期调用的函数名和间隔时间.

• -mask expr : 指定被禁止的命令名(比如可以禁止使用清空vanish).

• -unmask expr : 指定被允许的命令名.

数据库类型

下面我们再来看下数据库类型的详细配置。

1、 数据库名的命名方式被Tokyo Cabinet的抽象API指定。

2、 如果数据库名为"*",表示内存hash数据库。

3、 如果数据库名为"+"表示内存tree数据库。

4、 如果数据库名为".tch",则数据库为hash数据库。

5、 如果数据库名的后缀为".tcb",数据库将为B+ tree数据库。

6、 如果数据库名的后缀为".tcf"。则数据库将为fixed-length数据库。

7、 如果数据库名的后缀为".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=xxx来提高性能。xxx大于或等我我们的记录总数。

如果使用B+ tree数据库我们可以通过指定"#lcnum=xxx#bnum=yyy" 来提高性能.第一个参数指定被缓存的最大叶子节点数,受内存容量限制,第二个参数指定桶的数量,它应该大于总记录数的1/128.

如果有大量的客户端连接,确保我们的文件描述符够用。系统默认是1024,我们可以用使用“ulimit”来重新设定

比如下面的单机实例启动脚本(一个正在线上运行的脚本):

#!/bin/sh

ulimit -SHn 51200

ttserver -host 192.168.0.136 -port 11212 -thnum 8 -dmn -pid /data/ttserver/ttserver.pid -log /data/ttserver/ttserver.log -le -ulog /data/ttserver/ -ulim 128m -sid 1 -rts /data/ttserver/ttserver.rts /data/ttserver/database.tch#bnum=10000000#xmsiz=434217728#rcnum=20000

使用hash数据库,最大会缓存20000个记录,最大使用内存434217728bytes(414M),bucket存储桶的数量10000000。

目前的库大小:

-rw-r--r-- 1 root root 28G Mar 8 12:19 bbsdatabase.tch

因为使用了64位操作系统,所以文件大小不受2G的限制。

我们再看下读取数据的速度:

当前获取memcache Threads_cdb_threads_tid3565732_displayorder_0 使用时间 0.00054812431335449

以上是程序打印出来的通过memcache协议读取key为memcache Threads_cdb_threads_tid3565732_displayorder_0的数据所花的时间0.00054812431335449(s),可以看到速度还是非常快的。

启动实例

个人推荐通过修改ttservctl来实现启动。下面我们举几个简单的启动例子。

单机启动例子,下面是ttservctl文件的部分:

#! /bin/sh

#----------------------------------------------------------------

# Startup script for the server of Tokyo Tyrant

#----------------------------------------------------------------

# configuration variables

prog="ttservctl"

cmd="ttserver"

basedir="/var/ttserver" #数据库存放的路径,比如改为"/data/mydata"

port="1978" #启动的端口

pidfile="$basedir/pid"

logfile="$basedir/log"

ulogdir="$basedir/ulog"

ulimsiz="256m"

sid=1

dbname="$basedir/casket.tch#bnum=1000000" #上面讲的数据库类型配置

maxcon="65536"

retval=0

双机互为主辅模式,比如两台机器的Ip分别为192.168.1.176和192.168.1.1.177,以下为ttservctl文件的一部分。

176的配置:

#! /bin/sh

#----------------------------------------------------------------

# Startup script for the server of Tokyo Tyrant

#----------------------------------------------------------------

# configuration variables

prog="ttservctl"

cmd="ttserver"

basedir="/data/data/data1"

port="11211"

pidfile="$basedir/pid"

logfile="$basedir/log"

ulogdir="$basedir/"

mhost="192.168.1.177" #主ip即另外机器的ip

ulimsiz="256m"

sid=6#注意要每台机器不一样

dbname="$basedir/casket.tch#bnum=100000000#xmsiz=104857600#rcnum=1000000"

rts="$basedir/ttserver.rts" #在ttservctl基础上增加

maxcon="65536"

retval=0

# locale clear

LANG=C

LC_ALL=C

export LANG LC_ALL

# start the server

start(){

printf 'Starting the server of Tokyo Tyrant\n'

ulimit -n "$maxcon"

mkdir -p "$basedir"

if [ -f "$pidfile" ] ; then

pid=`cat "$pidfile"`

printf 'Existing process: %d\n' "$pid"

retval=1

else

$cmd \

-port "$port" \

-dmn \

-pid "$pidfile" \

-log "$logfile" \

-ulog "$ulogdir" \

-ulim "$ulimsiz" \

-sid "$sid" \

-mhost "$mhost" \#在ttservctl基础上增加

-mport "$port" \#在ttservctl基础上增加

-rts "$rts" \#在ttservctl基础上增加

"$dbname"

if [ "$?" -eq 0 ] ; then

printf 'Done\n'

else

printf 'The server could not started\n'

retval=1

fi

fi

}

177的配置:

#! /bin/sh

#----------------------------------------------------------------

# Startup script for the server of Tokyo Tyrant

#----------------------------------------------------------------

# configuration variables

prog="ttservctl"

cmd="ttserver"

basedir="/data/data/data1"

port="11211"

pidfile="$basedir/pid"

logfile="$basedir/log"

ulogdir="$basedir/"

mhost="192.168.1.176" #主ip即另外机器的ip

ulimsiz="256m"

sid=7#注意要每台机器不一样

dbname="$basedir/casket.tch#bnum=100000000#xmsiz=104857600#rcnum=1000000"

rts="$basedir/ttserver.rts" #在ttservctl基础上增加

maxcon="65536"

retval=0

# locale clear

LANG=C

LC_ALL=C

export LANG LC_ALL

# start the server

start(){

printf 'Starting the server of Tokyo Tyrant\n'

ulimit -n "$maxcon"

mkdir -p "$basedir"

if [ -f "$pidfile" ] ; then

pid=`cat "$pidfile"`

printf 'Existing process: %d\n' "$pid"

retval=1

else

$cmd \

-port "$port" \

-dmn \

-pid "$pidfile" \

-log "$logfile" \

-ulog "$ulogdir" \

-ulim "$ulimsiz" \

-sid "$sid" \

-mhost "$mhost" \#在ttservctl基础上增加

-mport "$port" \#在ttservctl基础上增加

-rts "$rts" \#在ttservctl基础上增加

"$dbname"

if [ "$?" -eq 0 ] ; then

printf 'Done\n'

else

printf 'The server could not started\n'

retval=1

fi

fi

}

Tokyo Tyrant(TTServer)系列-memcache协议

通过memcache协议使用ttserver

通过telnet 127.0.0.1 1978 telnet连接到到我们第一节的启动实例。

以下我们通过add增加key为key1和value为value1的数据。

通过get key1获取数据,如果你看不明白,可以搜索下memcache协议的东西看下。

add key1 1 0 6

value1

STORED

get key1

VALUE key1 0 6

value1

END

通过php使用

$mem=new Memcache();

$mem->connect("192.168.15.178",1978);

$mem->add("key2","value2");

print_r( $mem->get("key2"));

echo "<hr>";

$mem->add("key3",array("value3"=>"this is value3"));

print_r($mem->get("key3"));

?>

运行后输出:

value2

________________________________________

a:1:{s:6:"value3";s:14:"this is value3";}

需要注意的问题

序列化问题

如果你熟悉memcache协议,或者你曾经用php的memcache来使用ttserver,你可能马上就发现了上面的问题。

比如我们key3是一个数组,但是我们取回来的是一个序列化的字符串,没有自动反序列化,在memcached服务器上是会自动反序列化的。

通过上面的telnet示例我们可以看到,我们add key1的时候设置flag参数为1,但是我们get回来的时候,返回的flag参数是0,实际上,ttserver是没有存储flag参数的,统一的都 使用0,这就造成了php使用时不会自动反序列化,当然,如果你使用压缩参数,一样会有这样的问题。

  怎么样解决这个问题,如果要修改ttserver的代码实为不方便。我们完全可以在php,或者我们的客户端来控制。

比如value我们统一的都序列化后存储,取出来的时候我们再反序列化。

自增问题

//使用ttserver自增

$mem=new Memcache();

$mem->connect("192.168.15.178",1978);

var_dump($mem->increment("incr"));

//结果为int(1)

?>

//使用memcache自增

$mem=new Memcache();

$mem->connect("192.168.15.178",11211);

var_dump($mem->increment("incr"));

//结果为bool(false)

?>

我们看到同样的代码用在memcache返回了失败(false).我们可以在php手册上看到这样一句话“Memcache::increment() does not create an item if it didn't exist.”但是同样的,用在ttserver上就是成功的。这一点要特别注意。

Tokyo Tyrant(TTServer)系列-高可用性和高可靠性+nginx

1.基于memcache协议的高可用性

1.1构建一个互为主辅的ttserver.

图中构建了在ip为177和178两台机器的互为主辅结构的ttserver.

1.2在php中实现高可用

非常幸运,php的memcache客户端直接就可以实现故障转移的功能。其中的addServer函数或者方法非常好。

bool Memcache::addServer ( string $host [, int $port [, bool $persistent [, int $weight [, int $timeout [, int $retry_interval [, bool $status [, callback$failure_callback [, int $timeoutms ]]]]]]]] )

$memcache = new Memcache;

$memcache->addServer('192.168.0.177', 11211);

$memcache->addServer('192.168.0.178', 11211);

$memcache->get("key");

?>

addServer 会把其中加入的ip放到一个池中,然后使用对键hash的方式(默认是crc32(key) % current_server_num)进行存取选择服务器,当其中一台服务器宕机不可用时,current_server_num就会减一,进行重新hash连接新的服务器,这样就实现了故障的自动转移。具体其中的原理可以查看php手册中关于memcache部分。

1.3其他语言
http://code.google.com/p/memcached/wiki/Clients这是一个memcached的client API的各种语言实现的列表,几乎所有的api都有提供php类似的addServer实现故障转移功能。

2.利用nginx实现http协议的高可用性

2.1为什么要把nginx扯进来?

ttserver提供了http接口

ttserver没有提供安全保证

nginx在处理http请求和反向代理的性能非常好

nginx的反向代理具有负载均衡和健康检查功能

2.2如何结合nginx实现高可用性

2.2.1配置

在nginx配置文件中增加:

upstream backend {

server 192.168.0.177:11211 weight=5 max_fails=3 fail_timeout=30s;

server 192.168.2.178:11211 weight=1 max_fails=3 fail_timeout=30s;

}

利用upstream指向后端的两台机器。

location ~* /count(.*) {

if ($request_method = PUT ) {

return 403;

}

if ($request_method = DELETE ) {

return 403;

}

if ($request_method = POST ) {

return 403;

}

proxy_method GET;

proxy_pass http://backend;
}

当路径包含/count的时候,则代理到ttserver后端进行请求数据。请注意,这里屏蔽了PUT,DELETE,POST方法,只是使用了GET,主要目的是为了安全性,因为DELETE,POST,PUT是可以修改数据的。

2.2.2使用

使用以上的配置文件,启动nginx就可以访问ttserver中的内容了。比如访问http://host/count_key1将会显示ttserver中key为”count_key1”的内容。当我们不同时停掉177和178时,前端通过nginx http://host/count_key1都是同样可以可用的。
Tokyo Tyrant(TTServer)系列-备份恢复和增加从库

前面我们说了TTServer 的使用,以及如何在开始的时候配置主从。在使用中它非常高效和可靠,那么如果我们的服务运行一段时间后,需要增加一个从库(ttserver)来分担压力 或者用于负载均衡和HA,因为是线上系统,那么就不应该停机,那么我们应该怎么对数据进行备份和拷贝,然后启动一个slave从库呢?

1.如何备份和恢复

登录到ttserver服务器,执行如下命令

# tcrmgr copy -port 11211 localhost /data/backup.tch

localhost :ttserver主机名

/data/backup.tch 备份文件保存的路径,请注意,这里指ttserver所在机器的路径。

同样,也可以备份远程机器,

# tcrmgr copy -port 11211 remotehost /data/backup.tch

备份文件将保存在remotehost的/data/backup.tch

接下来恢复数据就比较简单,直接替换掉原有ttserver的数据文件,启动就可以了。

这种方式适用于定期的数据备份,在出现灾难故障时可以恢复到某一个时间的数据。不适合用来增加从库时需要的数据库文件。

2.如何不停机增加从库

从库需要进行同步,那么就需要有个文件的时间版本,防止数据冲突。

首先我们建立一个一个如下的脚本文件,存为"backup.sh",并赋予执行权限(chmod 755 backup.sh)。比如存在:/data/backup/路径下。

#! /bin/sh

srcpath="$1"

destpath="$1.$2"

rm -f "$destpath"

cp -f "$srcpath" "$destpath"

接下执行如下命令,执行的时间会根据你的磁盘性能和数据大小而定。

tcrmgr copy -port 11211 masterhost '@/data/backup/backup.sh'

materthost:主库主机名,请注意:backup.sh存放的路径是在materthost机器上。

'@/data/backup/backup.sh' :如果tcrmgr copy命令中,参数以@开始,那么后面的字符串作为命令行执行。

执行完成后,我们进入ttserver的数据目录,执行ls -lh会发现类似下面的文件名,

-rw-r--r-- 1 root root 9.2G Aug 25 14:31 casket.tch.1251181588942889

请确认产生casket.tch.xxxxx类似的文件名,xxxxx代表时间戳。

接下来在从库salve上以我们备份的文件来运行ttserver,把时间错写入到一个时间戳文件ttserver.rts。

$ ls

$ cp casket.tch.xxxxx casket.tch

$ echo xxxxx >ttserver.rts

$ mkdir ulog

$ ttserver -mhost masterhost -mport mport -port 11211 -ulog ulog -sid 2 -rts ttserver.rts casket.tch

运行后,ttserver将会以此时间戳进行同步。

masterhost :主库主机名

mport : 主库端口号

到此我们就完成了一个salve从库ttserver的增加。

3.小结

推荐备份也使用2中用到的方式,上面带上了时间戳,可以精确的知道数据的版本时间。

另外请注意:在使用此方法进行备份的时候,ttserver会在备份过程中一直保持同步阻塞和不修改数据。所以可以保证备份出来的版本跟时间戳的一致性。

Tokyo Tyrant(TTServer)系列-数据压缩

由于忙于工作,好久继续写关于ttserver的东西了。最近由于服务器准备的原因,只能在32位上做ttserver的测试,很快数据就达到 2G,ttserver无法正常工作,于是想到了ttserver的压缩功能,发现压缩比例挺大。所以进行了一些测试并在项目中做了一些应用。本文将展示 在64下面进行压缩的压缩比以及进行压缩的好处。

压缩测试

数据:2720268条原始新闻数据,每条数据使用json格式进行存储。

A机器ttserver配置:casket.tch#bnum=100000000#xmsiz=524288000#rcnum=200000#opts=ld

B机器ttserver配置:casket.tch#bnum=100000000#xmsiz=524288000#rcnum=200000

分别把原始新闻数据存储A机器和B机器。其中A和B的ulog日志文件大小都为19G。接下来来看ttserver的数据库文件大小,

A机器(有压缩)6.1G,B机器 (无压缩)17G。压缩后大概只占原来文件的1/3。

配置中的#opts=ld的d表示使用压缩。关于opts可以参考官方的原话:

"opts" can contains "l" of large option, "d" of Deflate option, "b" of BZIP2 option, and "t" of TCBS option.

经过初步测试,d是速度比较快的一种了。

压缩的优点

存储空间,压缩首先给人带来的优点肯定就是节约存储空间,这点在服务器空间不足的情况下使用非常有用,当然,你在32位2G文件大小的限制下,使用压缩的话就可以存储更多的数据。

IO性能:经过压缩,数据本身变得小了,对磁盘的IO也会相应减小,如果你的磁盘IO对你的应用形成了瓶颈,那么压缩也是可以为你来带益处的。对于IO的性能提高在硬盘结构和工作方式上也能得到解释。

压缩的缺点

使用压缩肯定就会耗费CPU资源了,所以CPU和空间只是一个权衡,根据经验,一般来说使用压缩都是没有问题的。比如nginx的gzip压缩静态文件(js,css)。

ttserver的压缩跟memcached的压缩的比较

提交到了比较,肯定就有不一样的地方。ttserver使用了内部压缩,就是服务器端(ttserver)负责压缩。而memcached的压缩则是客户端进行的,memcached只是负责存储压缩后的数据。客户端client根据flag参数来确定是否解压。ttserver是服务器负责压缩,memcache是客户端负责压缩。

ttserver输出的是解压后的数据,memcached输出的就是输入的压缩数据(数据使用压缩的情况)。这样就形成一个区别,memcached使用压缩后,由于输出的是压缩数据,会降低网络传输,而ttserver则不会有任何改变。

关于memcached的使用请网上搜索相应的介绍。

请注意Tokyo Tyrant (ttserver)在大数据量下的不稳定

ttserver不稳定案例

1. CMS a系统的文章采用了ttserver存储。在数据达到30多G的时候,经常出现写入失败,还出现了几次意外崩溃,无法重启成功,只得从slave恢复数据。

2.CMS b系统的图片使用ttserver存储,在数据导到65G的时候出现无法写入的情况,重启后问题依旧,只得从slave重新恢复数据重启。

3.BBS系统采用ttserver做缓存,设计上采用如果没有更新,那么缓存永久存在的策略。在数据达到65GB,数据条数在700多万条的时 候,出现大量写入失败的情况,系统负载开始上升,日志出现大量do_mc_set: operation failed。当然这里作为缓存比较好处理,删掉,重新建个新的就OK。(注:启动参数 data.tch#bnum=10000000#xmsiz=434217728#rcnum=20000)

测试中ttserver写入表现不稳定

1.#bum=10000000

插入940多万数据(一条7.2k)时出现崩溃(测了两次都一样,看起来好像内部出现了死锁,连上后,无法进行任何响应,没有任何操作时,也占了大量CPU)。越到后面插入的qps(每秒响应数)越小。而且波动比较大。

#bum=100000000

可以顺利插入上千万的数据,但是越到后面qps越小。越到后面插入的qps(每秒响应数)越小。而且波动比较大。

2.跟其他的nosql(mongodb,bdb je,cassandra)对比测试,在写入上,ttserver是表现最不稳定的,其他的nosql都非常好。

总结和注意

1.经过对Tokyo Cabinet 的测试,同样跟ttserver一样,所以应该是Tokyo Cabinet 导致的不稳定。在选择btree方式存储时,随着数据量的增加一样不稳定。在优化参数上也做了各种尝试。

2.ttserver在性能的表现上非常不俗,特别是内存占用和cpu占用都很低,能同时响应上万的并发。但是你应该注意,他一般在数据导到20G以上就会出现不稳定情况。

所以用ttserver来存储单条比较小的数据非常好,存储大文本或者大的二进制文件,由于空间占用上升很快,很快就会变得不稳定。

3.注意备份,使用master-slave是个非常好的主意,在ttserver崩溃导致文件损坏或者其他什么原因无法启动时,你可以从slave 拷贝数据文件来进行恢复。

4.如果你一定要使用ttserver,建议对数据进行分片(sharding)存储,或者你自己使用一个网络接口,底层使用Tokyo Cabinet 来进行分片存储。

5.以上只是个人在使用中遇到的情况,本人正在尝试在存储大文本的ttserver进行替换掉。

Tokyo Tyrant (ttserver)的master-slave复制协议分析

The replication protocol of Tokyo Tyrant (ttserver)

[文章作者:孙立 链接:http://www.cnblogs.com/sunli/ 更新时间:2010-06-26]

目的

ttserver已经自带了主从复制功能,而且运行非常稳定,高效,使我们在使用ttserver实现高可靠性的不二选择。为什么我还要分析它的复制协议呢?

1.需要实时从ttserver同步数据到一个异构库。比如mysql,其他的nosql数据库。

2.数据的无缝迁移,如果需要从ttserver数据库无缝切换到其他数据库,可以使用这种复制协议

3.高性能的异步处理队列,你可以设置主库为mem类型,然后使用同步协议获取数据,这实际上就是一个队列,而且还是一个持久化的队列服务。

4.其他存储写一个服务,可以用ttserver做slave。

协议结构分析

咱们从数据流向的流程开始:

1. 客户端(slave)连接到服务器端(master)

2. slave连接成功后向master发送

+--------------------------------------+

|0xC8 |0xa0 | slave rts | slave sid |

|1byte |1 byte | 8 bytes | 4 bytes |

+--------------------------------------+

3. master收到后,想客户端发送:

+---------+

|mid |

|4 bytes |

+---------+

4. slave收到后可以得到服务器端的master sid.

5. 这里就开始复制了,master继续想客户端循环不断的发送复制的数据的object.

+------+

|0xca | 表示没有任何操作

|1 byte|

+------+

发送一个操作项:

+--------------------------------------------------+

|0xc9 |rts | rsid |rsize |data |

|1 byte |8 bytes |4 bytes |4 bytes |rsize bytes |

+--------------------------------------------------+

其中data的结构:

+-----------------------------------+

|magic |cmd |[data] |

|1 bytes |1 bytes | key-value data |

+-----------------------------------+

cmd表示各种操作类型,比如put putkeep 等

6. slave循环接受数据进行数据ok了。

协议实现

ttserver的复制协议非常简单,因为官方并没有把复制协议写到文档中,其他操作都有文档的。就需要去分析它的C代码,结构分析出来实现就非常简单了。 我会开放一些实现,到时会在www.cnblogs.com/sunli/公布

Tokyo(ttserver)使用手册摘要

1 概述

Tokyo是Tokyo Cabinet和Tokyo Tyrant的简称,合在一起用也称ttserver。

Tokyo Cabinet 是日本人 平林幹雄 开发的一款 NoSQL 数据库,数据库由一系列key-value对的记录构成,类似bdb。

Tokyo Tyrant 是由同一作者开发的 Tokyo Cabinet 数据库网络接口。它拥有Memcached兼容协议,也可以通过HTTP协议进行数据交换。Tokyo Tyrant 加上 Tokyo Cabinet,构成了一款支持高并发的分布式持久存储系统Tokyo。

对Tokyo内部机制感兴趣的请参考陈海涛 chenht@ucweb.com:《Tokyo代码剖析》;

针对使用tt时出现太多误用,参数误设或未设,提供使用手册的摘要。在此开一个讨论的头。

2 Tokyo的安装

测试了在32位机器和64位机器都运行正常,64位机器可以支持>2G的单个db文件;

32位机器加上编译选项” --enable-off64”后也能支持>2G的单个db文件,但是不能突破32位Linux 3G用户内存空间的限制,所以内存最大只能用3G的,除非安装64位操作系统。

可用普通用户安装和运行。

Tokyo Cabinet依赖下面的库,一般Linux会自带,编译出错的话则需先安装:

zlib : 用来压缩. 1.2.3版本或更新的.

bzip2 : 用来压缩. 1.0.5版本或更新的.

下面的例子都是基于$HOME/local目录,使用时可更改。

下载最新的包(注意别下载到旧包了),2010年8月推荐用的最新版本是:
http://1978th.net/tokyotyrant/Latest Source Package (version 1.1.41)
http://1978th.net/tokyocabinet/Latest Source Package (version 1.4.46)

注:新版本主要进行bugfix,请尽量下载最新版本,changelog在源代码包里面。

下载后传到Linux的目录解压:

tar zxvf ***.tar.gz

2.1 Tokyocabinet

cd tokyocabinet-***

32位操作系统:

./configure --prefix=$HOME/local/tokyocabinet/ --enable-off64

64位操作系统:

./configure --prefix=$HOME/local/tokyocabinet/

make

make install

2.1.1 32位操作系统支持大于2G的db文件

32位操作系统要支持大于2G的db文件请加上” --enable-off64”,否则会导致严重问题,db文件超过2G时表现为:

Tcrmgr inform显示记录数为0,实际数据并没有被清空;

连接暴多但都操作失败,ttserver.log内提示“ERROR ttacceptsock failed”和“ERROR do_mc_set: operation failed”等;

Ttserver检测到文件异常会悄悄退出。

2.2 Tokyotyrant

环境变量设置,cd $HOME 后vi .bash_profile,修改PATH和LD_LIBRARY_PATH加上Tokyo的相关安装路径:

PATH=$HOME/local/tokyocabinet/bin:$HOME/local/tokyotyrant/bin:$PATH

LD_LIBRARY_PATH=$HOME/local/tokyocabinet/lib:$HOME/local/tokyotyrant/lib:$LD_LIBRARY_PATH

export PATH

export LD_LIBRARY_PATH

然后安装:

./configure --prefix=$HOME/local/tokyotyrant \

--with-tc=$HOME/local/tokyocabinet

make

make install

安装后在$HOME/local目录下生成了安装目录:

cd $HOME/local/tokyotyran

mkdir log data

新建两个目录用来存放ulog和db文件等。

在两台主机都安装完后,于是可以执行下面的启动步骤了。

2.2.1 支持lua脚本

末尾加上–enable-lua表示支持lua脚本:

./configure --prefix=$HOME/local/tokyotyrant \

--with-tc=$HOME/local/tokyocabinet –enable-lua

2.3 版本查看

查看tc版本:

tcamgr --version

查看tt版本:

ttserver --version

3 Tokyo的启动

生产环境可用本例的目录结构,可将#后面的参数再调整。

3.1 Hash关键性能参数

Hash是B+tree的基础,数据put时直接写入文件或文件映射,并非写缓存,是比较安全的数据存储方式。数据量小时,全在缓存或内存映射内操作,读写很快。

而且写数据是单条写入,所以数据量超过内存映射xmsiz时后要直接写入db文件,性能下降明显,io升高明显。

"bnum", 用来保存计算完hash值后的每个key在db文件的位置,bnum太小时hash值冲突比例就大。冲突的key依次链接起来,查找时增加了搜寻次数;

该值持久化到db文件,全映射在内存,默认很小是131071,最大可以设几亿以上。,要减少hash冲突次数,则要设置bnum >= key个数,一般一年后key要达到5000万个,bnum则设置为5千万:50 000 000。

"opts", 指定压缩方式(hash的短数据压缩比不高)和bucket array对每条数据用4字节还是8字节保存文件偏移量,要支持db文件>2G请加“#opts=l”。要支持db文件>2G并且用效果较好的gzip用到的压缩算法请加“#opts=ld”。

hash方式单条数据很短(< 100字节)时压缩效果差,可以不用这个参数,否则请带上这个参数,但会占用更多cpu。

"rcnum", hash map缓存的记录数,get时放到这个缓存,set时从缓存清掉该key,默认0不缓存,设置则最小256,B+tree不用这个参数,缓存热点数据的,在get访问确定没明显热点时不要设置这个参数;在有明显热点时才需设置这个参数,在保证xmsiz足够大时这个参数推荐设小些,例如100万,因为会把rnum条key和value不加压缩地放内存,除非机器内存很充裕。

"xmsiz",指定文件映射尺寸,默认且最小为:256(放head等关键信息)+ bucket array的尺寸。注意这个最重要的参数必须>=db文件尺寸才能正常速度地响应,否则很慢,例如db文件最大会达到10G,则xmsiz设置为10G,单位字节。

上述参数中只有这个xmsiz参数在启动后还可通过重启调整。

3.2 B+tree关键性能参数

B+tree是基于hash机制实现的,复用上述的db文件格式和文件映射,不同的只是最上层缓存机制。

写入db数据时,是按叶节点或非页节点进行了打包分页,整页写入;压缩也是整页压缩,压缩比更高。写也进行了缓存。

但必须在备机上定期执行tcrmgr sync,否则异常重启丢掉数据。

"bnum", 同hash方式的,但bnum的数量大于或等于存储总记录数的1/128即可,因为b+tree是整页保存到hash db内。

"opts", 同hash方式的该选项,要支持db文件>2G请加“#opts=l”。要支持db文件>2G并且用效果较好的gzip压缩算法请加“#opts=ld”。

b+tree方式压缩是整页(128条记录)压缩,压缩效果很好,数据量大时用b+tree时带上压缩参数降低内存使用量效果明显,但会稍占用更多cpu。

"xmsiz",同hash方式的。

"lcnum", b+tree缓存叶节点数,每个叶节点上可放128条记录作为一页,减轻读写压力,缓存热点数据的,默认1024,设的话最小64,太大则stop和sync时耗时很多。在xmsiz足够大时这个参数别设置。

"ncnum", b+tree缓存非叶节点数,每个树节点上可放256条索引作为一页,索引指向叶节点,减轻读写压力, 缓存热点数据,默认512,设的话最小64,太大则stop和sync时耗时很多。通常为叶节点数的一半。

在xmsiz足够大时以上两个参数可不设置。

#define BDBDEFLCNUM 1024 // default number of leaf cache

#define BDBDEFNCNUM 512 // default number of node cache

3.3 Hash主-备启动命令

./ttserver -host 192.168.4.150 -port 11230 -thnum 8 -dmn -pid $HOME/local/tokyotyrant/bin/ttserver.pid -log $HOME/local/tokyotyrant/log/ttserver.log -le -ulog $HOME/local/tokyotyrant/data/ -ulim 128m -sid 91 $HOME/local/tokyotyrant/data/database.tch#bnum=10000000#xmsiz=1024000000 #rcnum=1000000#opts=ld

./ttserver -host 192.168.4.151 -port 11230 -thnum 8 -dmn -pid $HOME/local/tokyotyrant/bin/ttserver.pid -log $HOME/local/tokyotyrant/log/ttserver.log -le -ulog $HOME/local/tokyotyrant/data/ -ulim 128m -sid 92 -mhost 192.168.4.150 -mport 11230 -rts $HOME/local/tokyotyrant/data/ttserver.rts $HOME/local/tokyotyrant/data/database.tch#bnum=10000000#xmsiz=1024000000 #rcnum=1000000#opts=ld

3.4 B+tree主-主启动命令

./ttserver -host 192.168.4.150 -port 11230 -thnum 8 -dmn -pid $HOME/local/tokyotyrant/bin/ttserver.pid -log $HOME/local/tokyotyrant/log/ttserver.log -le -ulog $HOME/local/tokyotyrant/data/ -ulim 128m -sid 91 -mhost 192.168.4.151 -mport 11230 -rts $HOME/local/tokyotyrant/data/ttserver.rts $HOME/local/tokyotyrant/data/database.tcb#bnum=10000000#xmsiz=2000000000 #lcnum=1024#ncnum=512#opts=ld

./ttserver -host 192.168.4.151 -port 11230 -thnum 8 -dmn -pid $HOME/local/tokyotyrant/bin/ttserver.pid -log $HOME/local/tokyotyrant/log/ttserver.log -le -ulog $HOME/local/tokyotyrant/data/ -ulim 128m -sid 92 -mhost 192.168.4.150 -mport 11230 -rts $HOME/local/tokyotyrant/data/ttserver.rts $HOME/local/tokyotyrant/data/database.tcb#bnum=10000000#xmsiz=2000000000 #lcnum=1024#ncnum=512#opts=ld
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  安装 ttserver