8月 16

go 操作redis ,对比python 操作redis

  之前做过python入库到redis的测试 http://www.simonzhang.net/?p=430
  今天才发现由于页面生成问题,有部分代码被转译了。借这个机会在同一台机器上再测试一下这两种语言。

  测试服务器为一个Xeon(TM)双核3.20GHz 的cpu,内存4G。操作系统为Centos5.4 64位。go1.0.2,python2.6

  go环境和redis之前已经有记录,go语言的redis开发包安装也比较简单,但是官方文档中目录有写错。
  我的go放在/usr/local/go,我的安装记录如下:
cd /usr/local/go/src/pkg
git clone git://github.com/alphazero/Go-Redis.git redis
cd redis
go install

仍旧用大密码表实验,go语言代码如下:

//www.simonzhang.net
package main 

import (
	"os";
	"log";
	"fmt";
	"redis";
        "encoding/hex"
        "crypto/md5"
)

func main () {
	spec := redis.DefaultSpec().Db(1).Password("");
        //如要操作远程redis服务器连接如下
	//spec := redis.DefaultSpec().Host("192.168.1.200").Db(1).Password("123");
	client, e := redis.NewSynchClientWithSpec (spec);
	if e != nil { log.Println ("failed to create the client", e); return }
        var str string
        userFile := "big_pass.txt"
        fin,err := os.Open(userFile)
        defer fin.Close()
        if err != nil {
                fmt.Println(userFile,err)
                return
        }
        buf := make([]byte, 1)
        for{
                n,_:= fin.Read(buf)
                if 0==n {break}
                if string(buf)=="\n"{
	            h:= md5.New()
   	            h.Write([]byte(str))
                    key:=hex.EncodeToString(h.Sum(nil));
                    value:=[]byte(str)
                    client.Set(key, value);
                    str=""
                 }else{
                    str+=string(buf)
                 }
                  
        }
}

开始测试

go使用build编译运行,cpu使用率在55%左右,load average: 1.98, 1.22, 0.91
real 1m33.310s
user 0m42.586s
sys 0m34.567s

python cpu使用在在80%,load average: 2.19, 1.36, 0.86。
real 1m26.873s
user 0m56.316s
sys 0m19.595s

  总结python写redis的东西比较简单。go对字符串做了MD5,入redis时用MD5值做key。
a)都运行完毕python和go录入redis行数与文本行数相同。
b)从大小来看python不到1K,go编译完成2.3M。如果要一处编译,移到其他服务器运行,go编译完的可以直接运行,python还要再装环境。但是有easy_install,所以装环境对我来说比较简单。
c) cpu使用量来看go要比python好一些,在增加md5计算的情况下所用系统资源也比pyhton少,但是应该快不了一倍。
d) 从代码编写的逻辑和难易程度来看,还是python简单一点。
如果要考虑速度可以试试Cpython,我没有试过。

6月 23

MongoDB的初步-安装、简单操作

网上的介绍很多所以就不废话了,先记录几个概念,直接记录关键操作。
mongodb 的官方网站http://www.mongodb.org/

MongoDB是由(database)、集合(collection)、文档对象(document)三个层次组成。与传统的
数据库对应关系如下
关系型数据库 MongoDB数据库
database database
table collection
row document
存储的数据格式是key-value对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档对象。

测试环境:CentOS 5.6 64位操作系统
将mongodb软件安装在/usr/local/mongodb
将mongodb数据放在/data/db
应该创建一个专有的操作账户。此次不麻烦了直接使用root。

A)部署
先下载mongodb到
# wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-1.8.1.tgz

进行解压缩
# tar xzvf mongodb-linux-x86_64-1.8.1.tgz

将文件移动到相应目录
# mv mongodb-linux-x86_64-1.8.1 /usr/local/mongodb

建立相应数据目录,也可以在启动时用–dbpath参数来指定数据库的路径
# mkdir -p /data/db

B)启、停数据库
进入mongodb的bin目录中
# cd /usr/local/mongodb/bin
可以看到以下命令
bsondump
mongo mongodb的客户端
mongod mongodb的服务端
mongodump mongodb的导出工具,导出为bson格式,也可用于备份、快照等。
mongoexport 把collection导出成json格式或csv格式的文件
mongofiles GridFS管理工具
mongoimport mongodb恢复工具速度快,但不保证数据完整导入
mongorestore mongodb恢复工具速度慢,但是根据mongodump导出的数据完整恢复
mongos mongodb的集群路程序
mongosniff mongodb操作捕获,类似于tcpdump,可以截获到要执行的命令
mongostat mongodb的运行信息。

启动数据库命令
# ./mongod
数据库正常启动,默认情况下客户端访问端口为27017,web访问端口为28017.
也可以使用–port参数直接设定,如果直接指定端口为4444,web访问端口将为5444,具体
信息会打出到启动信息中。常用参数还有
–fork 创建子进程
–logpath 指定日志目录,日志级别从多到少参数为从-v 到 -vvvvv
–directoryperdb 系统为每个 DB 创建一个独立子目录
–config 启动时调用配置文件,可有手动编辑配置文件
配置文件具体参数可以查询http://www.mongodb.org/display/DOCS/File+Based+Configuration
以 Daemon 方式运行# ./mongod –fork –logpath /dev/null

验证数据库是否启动正常。使用web比较方便,使用http://IP:port方式看到mongodb的
状态信息,表示启动成功。也可以使用客户端登陆,保存和查询数据,简单测试一下。这有点像
python中的字典。
# ./mongo
> db.foo.save({‘hi’:’hello word’})
> db.foo.find()
可以查到刚才保存的结果,表示数据库运行正常。客户端默认是连接本地的27017端口,如果
连接远程系统可以用 ./mongo ip:port的形式来指定IP和端口号。
到/data/db目录下,可以看到test.0、test.1、test.ns。因为mongodb采用预分配表空间机制,每个
分配文件都用0填充,第一个文件test.0为64MB,第二个文件为128MB ,依此类推,所以在32位模式运行时支持
的最大文件为2GB。每个库和索引也有对应的命名空间,命名空间的元数据都集中存在test.ns文件中。在数据插
入时每条数据都有”_id”,如果没有提供系统将自动生成Objectld作为该文档的主键。Objectid有4字节的时间戳,
3字节的机器号,2字节的进程id和3字节的自动计数组成。还有一个问题需要注意,文件删除后数据所占用的空
间不会被释放,所以不要存放经常要删除替换的文件。

关闭数据库
> use admin
> db.shutdownServer()

C)简单管理、操作命令

操作均为使用mongo连接后的操作提示符为>
命令列表 http://www.mongodb.org/display/DOCS/dbshell+Reference

切换库使用use,这个和mysql一样。切换后可以做的常用操作。
> use admin
查看帮助
> db.help()
查看当前表collection支持哪些方法
> db.dbname.help()
查看数据库运行统计信息
> db.serverStatus()
查看数据库的状态信息
> db.stats()
列出所有数据库
> show dbs
显示当前数据库
> db
打印最后出现的错误
> db.getLastError()
清除错误记录
> db.resetError()
添加用户,账户、密码、是否只读
> db.addUser(user,pwd,true)
列出用户
> show users
删除用户
> db.removeUser(“userName”)
清除错误记录
> db.resetError()
删除库
> db.dropDatabase()
将某个ip上的库同步到当前库
> db.cloneDatabase(“x.x.x.x”)
将某个ip上的数据复制到当前库
> db.copyDatabase(“test”,”x.x.x.x”)
查看数据空间大小
> db.userInfo.dataSize()

操作部分可以参照sql与mongo的对比
http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart
添加
> db.foo.save({‘hi’:’hello word’})
> db.foo.save({‘hi’:’nihao’})

查找
> db.foo.find({“hi”:”hello word”})

修改将”nihao”修改为”ni hao “
> db.foo.update({“hi”:”nihao”},{$set:{“hi”:”ni hao”}},false,true)

删除
> db.foo.remove({“hi”:”ni hao”})

5月 01

tokyo cabinet和tokyo tyrant安装 调试

Tokyo Cabinet和Tokyo Tyrant 是日本人 平林幹雄 开发的分布式缓存工具。

Tokyo Cabinet是 DBM 数据库,读写快速,哈希模式写入100万条数据只需0.643秒,读取100万条数据只需0.773秒。数据文件只有一个,里面存放多个的数据记录,key和valuevalue都是连续不定长的,即可以是二进制,也可是是字符串。数据文件记录组织有三种模式,hash表、B+树、定长数组。

Tokyo Tyrant 是Tokyo Cabinet 数据库网络接口。它拥有Memcached兼容协议,也可以通过HTTP协议进行数据交换。

Tokyo Tyrant和Tokyo Cabinet合并即成为高并发的分布式持久性存储系统。此系统支持双机热备,主辅库均可读写。用于主辅同步的数据日志也很小,大约是数据文件的1.3倍。为了保证性能建议在64位操作系统安装。

作者个人主页:http://1978th.net/

1.tokyocabinet安装

下载地址http://1978th.net/tokyocabinet/pastpkg/tokyocabinet-1.3.27.tar.gz

# tar zxvf tokyocabinet-1.3.27.tar.gz

# cd tokyocabinet-1.3.27

# ./configure && make && make install

直接编译不指定路径,如果是32为操作系统,需要添加–enable-off64参数,且数据文件不能超过2G。

2.Tokyotyrant安装

下载地址http://1978th.net/tokyotyrant/pastpkg/tokyotyrant-1.0.1.tar.gz

# tar zxvf tokyotyrant-1.0.1.tar.gz

# cd tokyotyrant-1.0.1

# ./configure && make && make install

3.优化系统,指定日志等文件存放位置

# ulimit -SHn 51200

# mkdir -p /usr/local/ttserver

4. 启动参数

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|-le : 日志文件中记录DEBUG调试信息|在日志文件中仅记录错误信息。此项为二选一,推荐使用-le。

-ulog path : 指定同步日志文件存放路径,此处路径为存放目录。

-ulim num : 指定每个同步日志文件的大小(例如128m)。

-uas : 使用异步IO记录更新日志(使用此项会减少磁盘IO消耗,但是数据会先放在内存中,不会立即写入磁盘,如果重启服务器或ttserver进程被kill掉,将导致部分数据丢失。一般情况下不建议使用)。

-sid num : 指定服务器ID号(当使用主辅模式时,每台ttserver需要不同的ID号)

-mhost name : 指定主辅同步模式下,对方服务器域名或IP地址。

-mport num : 指定主辅同步模式下,对方服务器的端口号。

-rts path : 指定用来存放同步时间戳的文件名。

dbname:制定数据库名,如果省略,则被视作内存hash数据库。

5.单机启动服务

服务器IP地址为192.168.1.100

# ttserver -host 192.168.1.100 -port 1111 -thnum 9 -dmn -pid /usr/local/ttserver/ttserver.pid -log /usr/local/ttserver/ttserver.log -le -ulog /usr/local/ttserver/ -ulim 64m -sid 1 –rts /usr/local/ttserver/ttserver.rts /usr/local/ttserver/database.tch

6.双机模式

主机IP地址192.168.1.100。 备机IP地址192.168.1.101

主机启动:

# ttserver -host 192.168.1.100 -port 1111 -thnum 9 -dmn -pid /usr/local/ttserver/ttserver.pid -log /usr/local/ttserver/ttserver.log -le -ulog /usr/local/ttserver/ -ulim 64m -sid 100 -mhost 192.168.101 -mport 1111 -rts /usr/local/ttserver/ttserver.rts /usr/local/ttserver/database.tch

备机启动:

# ttserver -host 192.168.1.101 -port 1111 -thnum 9 -dmn -pid /usr/local/ttserver/ttserver.pid -log /usr/local/ttserver/ttserver.log -le -ulog /usr/local/ttserver/ -ulim 64m -sid 101 -mhost 192.168.1.100 -mport 1111 -rts /ttserver/ttserver.rts /ttserver/database.tch

注:

如果使用的是哈希数据库,可以指定参数“#bnum=xxx”来提高性能。程序可以指定bucket存储桶的数量。例如指定“#bnum=10000”,就可以将最新最热的1万条记录缓存在内存中。

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

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

数据库类型

数据库名的命名方式被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”。

7.测试

ttserver对外有三种协议,可以用curl程序调用http协议访问,可用tt自带的客户端程序,使用私有二进制协议访问。

tcrtest :测试程序, tc remote test

tcrmttest :多线程测试程序 tc multi-thread test

两个测试程序写入的数据key,value均是8字节的,按照00000001,00000002格式

tcrtest write host rnum : 写入 rnum条记录(是重新写,不是追加)

tcrtest read host : 读出所有记录

tcrtest remote host : 删除所有记录

tcrmgr : 测试和调试

usage:

tcrmgr inform [-port num] [-st] host

tcrmgr put [-port num] [-sx] [-dk|-dc] host key value

tcrmgr out [-port num] [-sx] host key

tcrmgr get [-port num] [-sx] [-px] [-pz] host key

tcrmgr mget [-port num] [-sx] [-px] host [key…]

tcrmgr list [-port num] [-m num] [-pv] [-px] [-fm str] host

tcrmgr sync [-port num] host

tcrmgr vanish [-port num] host

tcrmgr copy [-port num] host dpath

tcrmgr restore [-port num] [-ts num] host upath

tcrmgr setmst [-port num] [-mport num] host [mhost]

tcrmgr repl [-port num] [-ts num] [-sid num] [-ph] host

tcrmgr http [-ah name value] [-ih] url

tcrmgr version

tcrmgr inform host: 获取服务器的信息

tcrmgr put host key value : 添加记录

tcrmgr get host key : 获取记录

tcrmgr out host key : 删除记录

tcrmgr list host : 列出数据库中所有的key(这个在memcached中是需要patch才能实现的)

tcrmgr vanish host : 删除所有数据

举例

1)查看服务器统计信息

tcrmgr inform -port 1111 -st 192.168.1.100

2)写入数据

tcrmgr put -port 1111 192.168.1.100 test value

3)读取数据

tcrmgr get -port 1111 192.168.1.100 test

4)删除数据

tcrmgr out -port 1111 192.168.1.100 test

5)查看所有的key

tcrmgr list -port 1111 192.168.1.100

6)备份数据

tcrmgr copy -port 1111 192.168.1.100 /usr/local/ttserver/backup/backup.tch

一定要写绝对路径

7) 同步内存数据到磁盘(当使用异步io时将缓存的数据写入磁盘)

tcrmgr sync -port 1111 192.168.1.100

8)数据导入

注意:tsv格式的文件以TAB分隔,如:test2tvalue2n

注意:路径是本地路径,所以不必是绝对路径

tcrmgr importtsv -port 1111 192.168.1.100 temp/2.tsv

9)通过ulog日志恢复数据

注意:路径是服务器上的绝对路径

tcrmgr restore -port 1111 192.168.1.100 /data/ttserver/ulog/

10)打印更新日志(挂起,一直显示日志)

可能是用于实时查看ttserver有哪些操作,相当于tail –f

tcrmgr repl -port 1111 -ph 192.168.1.100

8.ttservctl

命令ttservctl是服务器的启动脚本。Shell编写可以被操作系统的引导过程rc脚本调用,此命令用于以下格式。

ttservctl start

启动服务器。

ttservctl st
op

停止服务器。

ttservctl restart

重新启动服务器。

ttservctl hup

HUP信号发送到服务器的日志轮换。

默认情况该数据库被放置为“/var/ttserver/casket.tch”。该日志和相关的文件,也放在“/var/ ttserver”目录。该命令返回0成功,其它为失败。

9.ttulmgr

命令ttulmgr是导出和导入的更新日志的实用工具,可以用` grep ‘和’ sed ‘等过滤工具更新日志。此命令用于以下格式,`upath’指定了更新日志目录。

ttulmgr export [-ts num ] [-sid num ] upath

作为TSV格式文本数据导出更新日志到标准输出。

ttulmgr import upath

从标准输入导入TSV格式文本数据到更新日志。

可选项功能如下。

-ts num :指定开始时间戳记。

-sid num :指定本机服务器ID。

该命令返回0成功,另一个失败。