整理一波Redis
简介,与memcached比较
官网:http://redis.io
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。
这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
在此基础上,redis支持各种不同方式的排序。
与memcached一样,为了保证效率,数据都是缓存在内存中。
区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制(观察者模式),使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
可以充当缓存、队列等作用。
源码脱管: https://github.com/antirez/redis
历史和发展
2008年,意大利的一家创业公司Merzia推出一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人Salvatore Sanfilippo便对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。
不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
短短几年,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如京东、淘宝、新浪微博、街旁网(已关闭服务器)、知乎网、国外如GitHub、Stack Overflow、Flickr(雅虎旗下图片分享网站)等都是Redis的用户。
VMware公司从2010年开始赞助Redis的开发,Salvatore Sanfilippo和Pieter Noordhuis也分别在3月5月加入VMware,全职开发Redis。
特性
1)多种数据类型存储
字符串类型 string 512M
散列类型 hash 2^32-1
列表类型 list 2^32-1
集合类型 set 2^32-1
有序集合类型 zset
2)内存存储与持久化
内存的读写速度远快于硬盘
自身提供了持久化功能(RDB、AOF两种方式)
3)功能丰富
可以用作缓存、队列、消息订阅/发布
支持键的生存时间
按照一定规则删除相应的键
4)简单稳定
相比SQL而言更加简洁
不同语言的客户端丰富
基于C语言开发,代码量只有3万多行
5)所有操作是原子性的
Redis 使用单个 Lua 解释器去运行所有脚本,并且, Redis 也保证脚本会以原子性(atomic)的方式执行: 当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。 这和使用 MULTI / EXEC 包围的事务很类似。 在其他别的客户端看来,脚本的效果(effect)要么是不可见的(not visible),要么就是已完成的(already completed)
1.1 Redis持久化的两种方式
1.1.1 rdb和aof比较
rdb |
aof |
fork一个进程,遍历hash table,利用copy on write,把整个db dump保存下来。 save, shutdown, slave 命令会触发这个操作。粒度比较大,如果save, shutdown, slave 之前crash了,则中间的操作没办法恢复。 |
把写操作指令,持续的写到一个类似日志文件里。(类似于从postgresql等数据库导出sql一样,只记录写操作) 粒度较小,crash之后,只有crash之前没有来得及做日志的操作没办法恢复。 |
注:fork一个进程--
UNIX关于进程管理的一个术语,本质是新开一个进程,但是不从磁盘加载代码,而是从内存现有进程复制一份。
两种区别就是,
一个是持续的用日志记录写操作,crash(崩溃)后利用日志恢复;
一个是平时写操作的时候不触发写,只有手动提交save命令,或者是shutdown关闭命令时,才触发备份操作。
选择的标准,
就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),
还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 最终一致性(eventually consistent)的意思了。
1.1.2 性能比较
测试方法是用java写的脚本对redis数据库进行写入,看写入速度。
100000/300000/1000000是数据量,插入的都是string。第一个数据是最小时间,第二个是平均,第三个是数据大小。
100000:
dbmode: 4.8, 5.1, 1477792
aofmode: 9.1, 9.3, 3677803
300000:
dbmode: 16.5, 17.6, 4877792
aofmode: 21.1, 21.4, 11477803
1000000:
dbmode: 61, 65, 16777792
aofmode: 77, 85, 38777849
从简单分析来看,aof比rdb慢25-80%,但是大规模数据都比较支持慢25%这端。
估计在低数据量下,rdb模式更加占优势。
数据规模增长时,速率比接近于4:5。aof的数据比rdb数据大150%(2.5倍上下),这点随着数据增长基本不变。
从读性能分析来看,两者差异不大。同样,数据分别是最小时间和平均时间。
dbmode: 55, 60
aofmode: 62, 63
差异在10%以内,甚至比最小-平均差异还弱。基本可以视为一致。