关于使用key/value数据库redis和TTSERVER的心得体会


Posted in PHP onJune 28, 2013

先说redis
redis是一个类似memcached的key/value存储系统,它支持存储的value类型相对较多,包括string(字符串)、 list(链表)、set(集合)和zset(有序集合)。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件(这点儿个人觉得redis比memcache 在数据保存上要安全一些),并且在此基础上实现了master- slave(主从)同步。

redis的存取性能很高,SET操作每秒钟 110000 次,GET操作每秒钟 81000 次(速度很爽!)。
Redis针对不同的存储类型对象提供了不同的命令。
redis目前提供四种数据类型:string,list,set及zset(sorted set)。
string是最简单的类型,你可以理解成与Memcached一模一个的类型,一个key对应一个value,其上支持的操作与Memcached的操 作类似。但它的功能更丰富。

list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。

zset是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的 值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。

下面提供redis命令:
适合全体类型的命令
EXISTS key 判断一个键是否存在;存在返回 1;否则返回0;
DEL key 删除某个key,或是一系列key;DEL key1 key2 key3 key4
TYPE key 返回某个key元素的数据类型 ( none:不存在,string:字符,list,set,zset,hash)
KEYS pattern 返回匹配的key列表 (KEYS foo*:查找foo开头的keys)
RANDOMKEY 随机获得一个已经存在的key,如果当前数据库为空,则返回空字符串
RENAME oldname newname更改key的名字,新键如果存在将被覆盖
RENAMENX oldname newname 更改key的名字,如果名字存在则更改失败
DBSIZE返回当前数据库的key的总数
EXPIRE设置某个key的过期时间(秒),(EXPIRE bruce 1000:设置bruce这个key1000秒后系统自动删除)注意:如果在还没有过期的时候,对值进行了改变,那么那个值会被清除。
TTL查找某个key还有多长时间过期,返回时间秒
SELECT index 选择数据库
MOVE key dbindex 将指定键从当前数据库移到目标数据库 dbindex。成功返回 1;否则返回0(源数据库不存在key或目标数据库已存在同名key);
FLUSHDB 清空当前数据库中的所有键
FLUSHALL 清空所有数据库中的所有键

处理字符串的命令
SET key value 给一个键设置字符串值。SET keyname datalength data (SET bruce 10 paitoubing:保存key为burce,字符串长度为10的一个字符串paitoubing到数据库),data最大不可超过1G。
GET key获取某个key 的value值。如key不存在,则返回字符串“nil”;如key的值不为字符串类型,则返回一个错误。

GETSET key value可以理解成获得的key的值然后SET这个值,更加方便的操作 (SET bruce 10 paitoubing,这个时候需要修改bruce变成1234567890并获取这个以前的数据paitoubing,GETSET bruce 10 1234567890)
MGET key1 key2 … keyN 一次性返回多个键的值

SETNX key value SETNX与SET的区别是SET可以创建与更新key的value,而SETNX是如果key不存在,则创建key与value数据
MSET key1 value1 key2 value2 … keyN valueN 在一次原子操作下一次性设置多个键和值
MSETNX key1 value1 key2 value2 … keyN valueN 在一次原子操作下一次性设置多个键和值(目标键不存在情况下,如果有一个以上的key已存在,则失败)
INCR key 自增键值
INCRBY key integer 令键值自增指定数值
DECR key 自减键值
DECRBY key integer 令键值自减指定数值

处理 lists 的命令
RPUSH key value 从 List 尾部添加一个元素(如序列不存在,则先创建,如已存在同名Key而非序列,则返回错误)
LPUSH key value 从 List 头部添加一个元素
LLEN key 返回一个 List 的长度
LRANGE key start end从自定的范围内返回序列的元素 (LRANGE testlist 0 2;返回序列testlist前0 1 2元素)
LTRIM key start end修剪某个范围之外的数据 (LTRIM testlist 0 2;保留0 1 2元素,其余的删除)
LINDEX key index返回某个位置的序列值(LINDEX testlist 0;返回序列testlist位置为0的元素)
LSET key index value更新某个位置元素的值
LREM key count value 从 List 的头部(count正数)或尾部(count负数)删除一定数量(count)匹配value的元素,返回删除的元素数量。
LPOP key 弹出 List 的第一个元素
RPOP key 弹出 List 的最后一个元素
RPOPLPUSH srckey dstkey 弹出 _srckey_ 中最后一个元素并将其压入 _dstkey_头部,key不存在或序列为空则返回“nil”

处理集合(sets)的命令(有索引无序序列)
SADD key member增加元素到SETS序列,如果元素(membe)不存在则添加成功 1,否则失败 0;(SADD testlist 3 /n one)
SREM key member 删除SETS序列的某个元素,如果元素不存在则失败0,否则成功 1(SREM testlist 3 /N one)
SPOP key 从集合中随机弹出一个成员
SMOVE srckey dstkey member 把一个SETS序列的某个元素 移动到 另外一个SETS序列 (SMOVE testlist test 3/n two;从序列testlist移动元素two到 test中,testlist中将不存在two元素)
SCARD key 统计某个SETS的序列的元素数量
SISMEMBER key member 获知指定成员是否存在于集合中
SINTER key1 key2 … keyN 返回 key1, key2, …, keyN 中的交集
SINTERSTORE dstkey key1 key2 … keyN 将 key1, key2, …, keyN 中的交集存入 dstkey
SUNION key1 key2 … keyN 返回 key1, key2, …, keyN 的并集
SUNIONSTORE dstkey key1 key2 … keyN 将 key1, key2, …, keyN 的并集存入 dstkey
SDIFF key1 key2 … keyN 依据 key2, …, keyN 求 key1 的差集。官方例子:
key1 = x,a,b,c
key2 = c
key3 = a,d
SDIFF key1,key2,key3 => x,b
SDIFFSTORE dstkey key1 key2 … keyN 依据 key2, …, keyN 求 key1 的差集并存入 dstkey
SMEMBERS key 返回某个序列的所有元素
SRANDMEMBER key 随机返回某个序列的元素

处理有序集合(sorted sets)的命令 (zsets)
ZADD key score member 添加指定成员到有序集合中,如果目标存在则更新score(分值,排序用)
ZREM key member 从有序集合删除指定成员
ZINCRBY key increment member 如果成员存在则将其增加_increment_,否则将设置一个score为_increment_的成员
ZRANGE key start end 返回升序排序后的指定范围的成员
ZREVRANGE key start end 返回降序排序后的指定范围的成员
ZRANGEBYSCORE key min max 返回所有符合score >= min和score <= max的成员 ZCARD key 返回有序集合的元素数量 ZSCORE key element 返回指定成员的SCORE值 ZREMRANGEBYSCORE key min max 删除符合 score >= min 和 score <= max 条件的所有成员。

使用体会:
个人在觉得redis速度是不用说了(很快的),但是很消耗物理内存,算是redis的一个弊端吧,redis适合数据量比较小速度更新快的类型的网站,比如社区,不适合数据比较庞大的网站,比如论坛。以前用redis应用的一个论坛帖子上,但是因为数据量太大,消耗物理内存惊人而放弃了用 redis!

再说说TTSERVER
Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符串。这里没有数据类型和数据表的概念。当做为Hash表数据库使用时,每个key必须是不同的,因此无法存储两个key相同的值。提供了以下访问方法:提供key,value参数来存储,按 key删除记录,按key来读取记录,另外,遍历key也被支持,虽然顺序是任意的不能被保证。这些方法跟Unix标准的DBM,例如GDBM,NDBM 等等是相同的,但是比它们的性能要好得多(因此可以替代它们) 当按B+树来存储时,拥用相同key的记录也能被存储。像hash表一样的读取,存储,删除函数也都有提供。记录按照用户提供的比较函数来存储。可以采用顺序或倒序的游标来读取每一条记录。依照这个原理,向前的字符串匹配搜索和整数区间搜索也实现了。另外,B+树的事务也是可用的。对于定长的数组,记录按自然数来标记存储。不能存储key相同的两条或更多记录。另外,每条记录的长度受到限 制。读取方法和hash表的一样。 Tokyo Cabinet是用C写的,同时提供c,perl,ruby,java的API。Tokyo Cabinet在提供了POSIX和C99的平台上都可用,它以GNU Lesser Public License协议发布。

tokyocabinet :一个key-value的DBM数据库,但是没有提供网络接口,以下称TC。
tokyotyrant :是为TC写的网络接口,他支持memcache协议,也可以通过HTTP操作,以下称TT。

性能:
Tokyo Cabinet 是日本人 平林?中 开发的一款 DBM 数据库,Tokyo Cabinet基于GNU Lesser General Public License协议发布,采用C语言开发,它可以运行在任何支持C99和POSIX平台上使用。相比一般的DBM数据库有以下几个特点:空间小,效率高,性能高,可靠性高,多种开发语言的支持(现已提供C,Perl,Ruby,Java,Lua的API),支持64位操作系统。该数据库读写非常快,哈希模式写入100万条数据只需0.643秒,读取100万条数据只需0.773秒,是 Berkeley DB 等 DBM 的几倍。

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

ttserver和memcache比较:
ttserver是数据库,memcached是缓存。两者都是保存<key,value>形式的数据,通过key进行任何操作。ttserver可以将数据持久化保存,memcached全部是保存在内存中,memcached会自动删除过期数据,最长不超过30天。memcached在和一些api配合时,能自动进行数据的出入序列化,读取反序列化。ttserver有主从复制的功能,操作日志等,这完全是数据库才有的东西。据说memcached正在对整体架构做调整,到时候支持plugin机制.会把网络,事件处理,内存存储剥离开来.以后要做基于磁盘的key-value存储就可以写一个存储引擎就成了。memcached的二次开发又步入一个小高潮。

PHP 相关文章推荐
php ob_flush,flush在ie中缓冲无效的解决方法
May 09 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
Oct 29 PHP
php中使用临时表查询数据的一个例子
Feb 03 PHP
解析PHP中ob_start()函数的用法
Jun 24 PHP
codeigniter框架批量插入数据
Jan 09 PHP
php通过排列组合实现1到9数字相加都等于20的方法
Aug 03 PHP
2款PHP无限级分类实例代码
Nov 11 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
Nov 16 PHP
浅谈PHP中的面向对象OOP中的魔术方法
Jun 12 PHP
php7安装mongoDB扩展的方法分析
Aug 02 PHP
PHP中PDO事务处理操作示例
May 02 PHP
php生成短网址/短链接原理和用法实例分析
May 29 PHP
解析php中如何直接执行SHELL
Jun 28 #PHP
zend Framework中的Layout(模块化得布局)详解
Jun 28 #PHP
解析在zend Farmework下如何创立一个FORM表单
Jun 28 #PHP
解析zend Framework如何自动加载类
Jun 28 #PHP
使用PHP接收POST数据,解析json数据
Jun 28 #PHP
PHP遍历某个目录下的所有文件和子文件夹的实现代码
Jun 28 #PHP
下拉列表多级联动dropDownList示例代码
Jun 27 #PHP
You might like
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
php定时删除文件夹下文件(清理缓存文件)
2013/01/23 PHP
关于初学PHP时的知识积累总结
2013/06/07 PHP
php/js获取客户端mac地址的实现代码
2013/07/08 PHP
PHP自动重命名文件实现方法
2014/11/04 PHP
Js的MessageBox
2006/12/03 Javascript
纯JAVASCRIPT图表动画插件Highcharts Examples
2011/04/16 Javascript
JS弹出层的显示与隐藏示例代码
2013/12/27 Javascript
浅析jquery的js图表组件highcharts
2014/03/06 Javascript
最简单的JavaScript验证整数、小数、实数、有效位小数正则表达式
2015/04/17 Javascript
详解JavaScript基于面向对象之创建对象(1)
2015/12/10 Javascript
Asp.Net之JS生成分页条的方法
2016/11/23 Javascript
JavaScript 网页中实现一个计算当年还剩多少时间的倒数计时程序
2017/01/25 Javascript
Angular实现预加载延迟模块的示例
2017/10/12 Javascript
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
vue路由对不同界面进行传参及跳转的总结
2019/04/20 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
vue+layui实现select动态加载后台数据的例子
2019/09/20 Javascript
微信小程序新闻网站详情页实例代码
2020/01/10 Javascript
Python GAE、Django导出Excel的方法
2008/11/24 Python
Python中map和列表推导效率比较实例分析
2015/06/17 Python
Python之父谈Python的未来形式
2016/07/01 Python
python 调用有道api接口的方法
2019/01/03 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
浅谈Python访问MySQL的正确姿势
2020/01/07 Python
HTML5 解决苹果手机不能自动播放音乐问题
2017/12/27 HTML / CSS
详解如何将 Canvas 绘制过程转为视频
2021/01/25 HTML / CSS
美国鞋类购物网站:Shiekh Shoes
2016/08/21 全球购物
购房公证委托书(2014版)
2014/09/12 职场文书
学习普通话的体会
2014/11/07 职场文书
文案策划岗位职责
2015/02/11 职场文书
警示教育观后感
2015/06/17 职场文书
详解缓存穿透击穿雪崩解决方案
2021/05/28 Redis
Mysql中mvcc各场景理解应用
2022/08/05 MySQL
MySQL数据管理操作示例讲解
2022/12/24 MySQL