初识redis
redis是个存储服务,能够支持k-v等结构,数据能落地(memcache的数据是内存数据,无法落地)
下面进入redis的世界来一探究竟。
命令行进入redis:
用ps aux | grep redis看下redis-server是否开启,对应的端口号是多少。
/usr/local/redis26/redis-server /usr/local/redis26/6007.conf
redis命令行连6007端口进入redis
/usr/local/redis26/redis-cli -h localhost -p 6007
常用的几个命令:get(拿key获取value),set(设置key-value对),ttl(查看该key-value的过期时间),keys(查看符合查询条件的key list)
可能会用到的:mget(多个key获取value),hset-hget,incr,decr
某些场景:带排序的SortedSet(这些见参考文件1)
keys:通过查询条件查看key列表,支持*正则,其它正则表示不确定是否支持
redis localhost:6007> keys ST:client:*
1) "ST:client:soft:1"
2) "ST:client:edition:100092983"
3) "ST:client:soft:3"
4) "ST:client:edition:100093524"
keys-2:不存在
redis localhost:6007> keys test (empty list or set)
set-get:
redis localhost:6007> set test 'test' OK redis localhost:6007> get test "test"
del:删除某个key,特别注意如果某个key不存在,用命令行get时会返回nil
redis localhost:6007> del test (integer) 1 redis localhost:6007> get test (nil)
ttl:查看某个key的过期时间。可以看到如果key不存在,则ttl返回-1(与版本有关,2.8之前返回-1,2.8之后返回-2);如果key存在并且永不过期,则ttl返回-1;如果key存在并且设置了过期,则返回key的剩余存活时间
redis localhost:6007> get test (nil) redis localhost:6007> ttl test (integer) -1 redis localhost:6007> set test 'test' OK redis localhost:6007> ttl test (integer) -1 redis localhost:6007> get test "test"
expire:设置key的过期时间
redis localhost:6007> expire test 100 (integer) 1 redis localhost:6007> ttl test (integer) 98
mget:获取多个key对应的value
redis localhost:6007> mget test test1 1) "test" 2) "test1"
decr:自减1
redis localhost:6007> decr test (error) ERR value is not an integer or out of range redis localhost:6007> set test 3 OK redis localhost:6007> decr test (integer) 2
incr:自增1
redis localhost:6007> incr test (integer) 3 redis localhost:6007> get test "3"
append:字符串追加
redis localhost:6007> append test 'test' (integer) 5 redis localhost:6007> get test "3test"
上面所有的可归结于字符串操作,可以看到redis支持string类型,以及set,list,zset,hash类型
list操作:数组,下表为0,1,2,3....
redis localhost:6007> lset list 0 'list0' (error) ERR no such key redis localhost:6007> lpush list 'list0' (integer) 1 redis localhost:6007> lget list (error) ERR unknown command 'lget' redis localhost:6007> lrange list 0 1 1) "list0"
解释:
lset:直接用lset是错误的,因为list必须存在才能使用该命令
lpush:往list中添加元素,如果list不存在则创建list并添加元素
lget:没有这个命令
lrange:列出list的指定条目
用法:LRANGE key start stop,start表示起始下标从0开始,stop表示终止下标从0开始,stop不是条目数,而是结尾处的下标值
redis localhost:6007> lrange list 0 0 1) "list0" redis localhost:6007> lpush list 'list1' (integer) 2 redis localhost:6007> lrange list 0 1 1) "list1" 2) "list0"
redis localhost:6007> lset list 0 'list-new0'
OK
redis localhost:6007> lrange list 0 1
1) "list-new0"
2) "list0"
解释:
lrange之前解释过了。
lpush添加元素到list
lset:lset key index value,修改list的某个下标内的值。复杂度为O(1),可见数据结构不是链表
获取list的某个index的值,获取list的某一段的值
redis localhost:6007> lpush list 'list 2' (integer) 3 redis localhost:6007> lrange list 0 -1 1) "list 2" 2) "list-new0" 3) "list0" redis localhost:6007> lrange list 0 0 1) "list 2" redis localhost:6007> lrange list 0 1 1) "list 2" 2) "list-new0"
解释:
lrange:可以获取单个下标对应的值,也可以获取一段连续的index值。例如:lrange list 0 0(获取0号元素的值);lrange list 0 1(获取0号,1号元素的值)
lpush:在list的表头插入元素,返回值为列表的长度
lpop:弹出list的表头,返回表头的value
redis localhost:6007> lrange list 0 -1 1) "list 2" 2) "list-new0" 3) "list0" redis localhost:6007> lpop list "list 2" redis localhost:6007> lrange list 0 -1 1) "list-new0" 2) "list0"
rpush:表尾插入元素,返回list长度
redis localhost:6007> rpush list 'list-last' (integer) 3 redis localhost:6007> lrange list 0 -1 1) "list-new0" 2) "list0" 3) "list-last"
rpush:list允许插入相同的元素值
redis localhost:6007> rpush list 'list-last' (integer) 4 redis localhost:6007> lrange list 0 -1 1) "list-new0" 2) "list0" 3) "list-last" 4) "list-last"
rpop:弹出表尾的元素
redis localhost:6007> rpop list "list-last" redis localhost:6007> lrange list 0 -1 1) "list-new0" 2) "list0" 3) "list-last"
llen:查询表长度
总结:list是以0,1,2,3这样连续的下标方式存储和修改和查找元素的。对于新建list:list不支持直接lset创建list,支持lpush和rpush创建list并添加元素。增加元素:list支持插入到表头(lpush)和插入到尾部(rpush)。查询元素:lrange(单个或者多个)。删除元素:删除表头元素(lpop)和删除表尾(rpop)。修改元素:修改指定下标的元素(lset)。而且,对于list,可以插入相同值的元素。
----
hash
hash的结构是:有两级key,同时拿两级key才能获取到value。
类似于php的:array('data'=>array('one'=>'one','two'=>'two')),一级key对应data,二级key对应one,two等
hset-hget-hgetall:设置-获取-获取所有
redis localhost:6007> hset hash-lww index0 value0 (integer) 1 redis localhost:6007> hgetall hash-lww 1) "index0" 2) "value0" redis localhost:6007> hget hash-lww index0 "value0" redis localhost:6007> hlen hash-lww (integer) 1
批量操作:hMset,hMget
hash类型结束
----
set类型
set类型是集合类型,只保证存在,不保证有序。类似于课本中学的集合的概念{0,1,3,2}这样子的。对于集合而言最常见的操作有,集合的交(sInter)并(sUnion)差(sDiff)。
而且集合中的元素是唯一的,不能重复。{0,0,1}这个不是集合所允许的。
sadd-smembers-srandmember
redis localhost:6007> sadd website www.so.com (integer) 1 redis localhost:6007> slen website (error) ERR unknown command 'slen' redis localhost:6007> sget website (error) ERR unknown command 'sget' redis localhost:6007> smembers website 1) "www.so.com" redis localhost:6007> srandmember website "www.so.com" redis localhost:6007> sadd website www.baidu.com (integer) 1 redis localhost:6007> smembers website 1) "www.baidu.com" 2) "www.so.com" redis localhost:6007> sadd website www.baidu.com (integer) 0
集合的获取元素的操作:sMembers,sRandMember
集合之间的交并差操作:sUnion,sDiff,sInter
redis localhost:6007> smembers website 1) "www.baidu.com" 2) "www.so.com" redis localhost:6007> smembers website1 1) "www.hao123.com" 2) "www.baidu.com" redis localhost:6007> sinter website website1 1) "www.baidu.com" redis localhost:6007> sdiff website website1 1) "www.so.com" redis localhost:6007> sunion website website1 1) "www.hao123.com" 2) "www.baidu.com" 3) "www.so.com"
sUnion,sDiff,sInter的计算复杂度都比较高,其中sInter是最低的(N*M)N为最短的集合长度,M为集合个数,sUnion和sDiff为O(N),N为所有的集合长度之和。
set类型结束
----
zset类型
zadd-zrange:增加某个元素,查询
redis localhost:6007> zadd zs-lww 10 google.com (integer) 1 redis localhost:6007> zadd zs-lww 9 baidu.com (integer) 1 redis localhost:6007> zRange zs-lww 0 -1 1) "baidu.com" 2) "google.com" redis localhost:6007> zRange zs-lww 0 -1 WITHSCORES 1) "baidu.com" 2) "9" 3) "google.com" 4) "10"
zdd-zrange:修改某个value的排名
redis localhost:6007> zadd zs-lww 8 baidu.com (integer) 0 redis localhost:6007> zRange zs-lww 0 -1 WITHSCORES 1) "baidu.com" 2) "8" 3) "google.com" 4) "10"
移除某个set,查询某个score的元素列表
zRem:移除某个set
redis localhost:6007> zRange zs-lww 0 -1 WITHSCORES 1) "baidu.com" 2) "8" 3) "google.com" 4) "10" redis localhost:6007> zRem zs-lww baidu.com (integer) 1 redis localhost:6007> zRange zs-lww 0 -1 WITHSCORES 1) "google.com" 2) "10"
zRank:查看某个元素的排名(从0开始)
redis localhost:6007> zRange zs-lww 0 -1 WITHSCORES 1) "google.com" 2) "10" redis localhost:6007> zRank zs-lww baidu.com (nil) redis localhost:6007> zRank zs-lww google.com (integer) 0
zScore:查看某个元素的得分
redis localhost:6007> zScore zs-lww google.com "10"
zCard:查询z-set中有多少个元素
zCount:查询z-set的score在指定的[min,max]中有多少元素
zset类型结束
----
关于PHP的redis接口见参考5。
redis的PHP版接口,对于mget函数而言:1,如果key为0或者空字符串等,会忽略该key;2,如果keys=1,2,3,那么返回的value为v1,v2,v3,其中如果key存在则返回的value为redis存储的value,如果key在redis中不存在,则返回false。意味着redis的php版本的value与key能产生一一对应,这个是很重要的,在key不为空的的情况下(即情况1)。
reference:
1,http://redis.readthedocs.org/en/latest/
2,关于ttl:http://redis.readthedocs.org/en/latest/key/ttl.html