Chris's Blog

Keep Walking......

The Redis Introduction

Redis是REmote DIctionary Server的缩写,它采用了单请求处理线程的架构,避免了管理并发的复杂问题,也简化了实现,但同时也带来CPU的瓶颈,当单线程被阻塞时整个Redis都会停止响应。

Redis Key

Key不能太长,推荐的格式为:<object type>:<id>:<field>,用“:”分隔域,用“.”作为单词间的连接。

KEYS命令可返回匹配指定模式的key,模式支持通配符,具体可参考:http://redis.readthedocs.org/en/latest/key/keys.html

SORT命令可对集合按数字或字母顺序排序后返回或另存为list,还可以关联到外部key等。可参考:http://redis.readthedocs.org/en/latest/key/sort.html

Key超时操作常用的命令:EXPIREEXPIREATPERSISTTTL

其它关于Key的常用命令:EXISTSDELRANDOMKEYRENAMERENAMENXTYPE

Redis Value的数据结构

String

可以是任何种类的字符串(包括二进制数据),长度不能超过1GB。

除了最基本的GET/SET,Redis还提供了一些简便的指令。

INCR/DECR/INCRBY/INCRBYFLOAT/DECRBY:针对数字类型的字符串。若key不存在时创建key并设值为0。INCRBYFLOAT专门针对float类型的值,使用负数即可实现DECR的效果。

SETEX:即Set + Expire。

SETNX:即SET if Not eXists。

GETSET:设置新值,并返回旧值。

MGET/MSET/MSETNX:GET/SET/SETNX的批量操作。

GETBIT/SETBIT/BITOP/BITCOUNT:Redis BitMap的用法,使用场景可参考:http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/

APPEND/SETRANGE/GETRANGE/STRLEN:对字符串进行扩展、替换、截取和取长度,只适用于特定数据格式的字符串。

Hash

Key-HashMap结构,可以一次set,get多个属性。相比JSON格式的字符串,可以只读取/更新对象的某些属性,不用取回所有的属性,改完再写回去。

可以通过该数据结构建立索引。比如User对象,通常都会使用id或name来查询,这样在插入User对象时:set user:101 {“id”:101,”name”:”admin”}, 同时再插入一条hash结构的索引:hset user:index:name admin 101。按name查询的时候,使用:hget user:index:name admin 就能取出对应的id。

List

List是一个双向链表,基于linked list,支持双向的Pop/Push,一般从左端Push,右端Pop。在左端或右端添加一个元素的复杂度是一样的。

List的下标从0开始,从左到右计算,下标为负数时则从右到左。

常用的命令:

LREM:按值删除元素。
LINSERT:插在某个值的前后。
LSET:按下标设置元素值。
LINDEX:按下标返回元素。
LRANGE:返回列表内一段下标的元素,可用于分页操作。
LTRIM:限制List的大小。
BLPOP/BRPOP:阻塞版的pop命令,可用于Message Queue,当多个Client并发阻塞等待,有Element入列时谁先被阻塞谁先被服务。

Set

用于存储不重复的值,无序。还提供一些交集,并集,差集的集合操作。

SADD/SREM/SISMEMBER/SCARD/SMOVE/SMEMBERS:基本操作。 SINTER/SINTERSTORE/SUNION/SUNIONSTORE/SDIFF/SDIFFSTORE:集合操作。

Sorted Set

有序集合,元素放入集合时要提供该元素的分数。

ZRANGE/ZREVRANGE:按排名的上下限返回元素,正数与倒数。
ZRANGEBYSCORE/ZREVRANGEBYSCORE:按分数的上下限返回元素,正数与倒数。
ZREMRANGEBYRANK/ZREMRANGEBYSCORE:按排名/分数的上下限删除元素。
ZCOUNT:统计分数上下限之间的元素个数。
ZRANK/ZREVRANK:显示某个元素的正倒序的排名。
ZSCORE/ZINCRBY:显示元素的分数/增加元素的分数。
ZADD/ZREM/ZCARD/ZINSERTSTORE/ZUNIONSTORE:集合操作,与Set相比,少了IsMember和差集运算。

事务

MULTI(Start Transaction)、EXEC(Commit)、DISCARD(Rollback)实现。 在事务提交前,不会执行任何指令,只会把它们存到一个队列里。此时其他客户端可以对当前数据进行任意的操作。在事务提交时,批量执行所有指令,因为是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的。

Redis不保证所有指令同时成功或失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力。

WATCH命令在事务提交时,如果Key的值已被别的客户端改变,则整个事务队列都不会被执行。

持久化

RDB与AOF完全独立运行。只有正确关闭服务器:redis-cli shutdown,才保证写RDB文件以及将AOF文件fsync到磁盘,不会丢失数据。 如果是Ctrl+C,或者 kill -9 就可能丢失。

RDB

整个内存的压缩过的Snapshot,可以配置复合的重写触发条件,默认是1分钟内改了1万次,或5分钟内改了10次,或15分钟内改了1次。

先写到临时文件再重命名,这样外部程序对RDB文件的备份和传输过程是安全的。而且即使写新快照的过程中Server被强制关掉了,旧的RDB文件还在。

可配置是否进行压缩,压缩方法是字符串的LZF算法,以及将string形式的数字变回int形式存储。

AOF

append only的操作日志,记录所有有效的写操作,格式就是Redis协议的纯文本文件。

如果使用了AOF,重启时只会从AOF文件载入数据,不会再管RDB文件。

RDB不会实时写入数据,而且如果同时使用两者,但服务器重启只会找AOF文件。不建议只使用AOF,因为RDB更适合用于备份数据库,快速重启。

Windows版本

Redis本身并未提供Windows版本,微软技术小组采用LibUV成功将Redis移植到了windows平台,这样就方便了应用的本地开发调试。

目前的稳定版是2.6版本,支持Lua脚本:https://github.com/MSOpenTech/redis

编译好的可执行文件:https://github.com/MSOpenTech/redis/tree/2.6/bin/release

Resources

Redis的设计与实现:http://www.redisbook.com/en/latest/
The Little Redis Book:http://openmymind.net/2012/1/23/The-Little-Redis-Book/
Redis 命令参考:http://redis.readthedocs.org/en/latest/
NoSQLFan - Redis资料汇总专题:http://blog.nosqlfan.com/html/3537.html
Redis响应延迟问题排查:http://www.oschina.net/translate/redis-latency-problems-troubleshooting

Comments