深入浅出Redis(一)简介(二)

2015-07-24 07:27:11 · 作者: · 浏览: 2
teger) 4 127.0.0.1:6379> lindex mylist 1 "b" 127.0.0.1:6379> lrange mylist 2 3 1) "c" 2) "d" 127.0.0.1:6379> lpop mylist "a" 127.0.0.1:6379> rpop mylist "d" 127.0.0.1:6379> lrange mylist 0 -1 1) "b" 2) "c"
通过List,我们可以非常容易的实现各个链表、栈等数据结构,得益于Redis的优点,使用这些实现在性能上都非常的快。

Sets

Sets是一个集合,比起List,它不允许重复的值,而且也不是有序的,所以不能通过下标索引来获取元素。可以使用sadd命令向集合中加入新的元素,smember命令返回集合中的所有元素,sismember命令判断一个元素是否属于某个集合(值得一提的是sismember命令的复杂度是O(1),不管集合中有多少个元素,它总是花费固定的时间完成执行)。
127.0.0.1:6379> sadd myset java
(integer) 1
127.0.0.1:6379> sadd myset c++
(integer) 1
127.0.0.1:6379> sadd myset objective-c
(integer) 1
127.0.0.1:6379> sadd myset java
(integer) 0
127.0.0.1:6379> smembers myset
1) "objective-c"
2) "c++"
3) "java"
127.0.0.1:6379> sismember myset java
(integer) 1
127.0.0.1:6379> sismember myset c
(integer) 0

对于具体超大数据量的系统来说,使用Sets做来唯一性判断未尝不是一个好的方案。

Sorted Sets

Sorted Sets是一个非常强大的数据结构,它在Sets的基础上,为集合中每个元素绑定了一个数值,这样一来就可以对集合做一些排序相关的操作了。zadd命令向集合中新增一个元素,同时指定该元素对应的数值;zank返回元素在集合中根据数值排序后的下标索引,zrevrank与zank类似,只是排序方式由大到小;zrange与zrevrange命令可以根据下标获取排序后的元素,非常有用的命令。 比如我们使用Sorted Sets来存放一个成绩表,可以非常容易处理诸如:多少人在90分以上,多少人不及格,80分以上的人是哪些,排名第一的是谁,多少分等等查询:
127.0.0.1:6379> zadd math:score 58 person1 63 person2 78 person3 85 person4 90 person5 100 person6
(integer) 6
127.0.0.1:6379> zrevrangebyscore math:score 100 60 //及格的人是哪些
1) "person6"
2) "person5"
3) "person4"
4) "person3"
5) "person2"
127.0.0.1:6379> zrevrangebyscore math:score 100 90 //90分以上(包括90)的人是哪些
1) "person6"
2) "person5"
127.0.0.1:6379> zrevrangebyscore math:score 100 (90 //90分以上(不包括90)的人是哪些
1) "person6"
127.0.0.1:6379> zcount math:score 90 +inf //90分以上有多少人
(integer) 2
127.0.0.1:6379> zcount math:score -inf 59 //多少人不及格
(integer) 1
127.0.0.1:6379> zrevrange math:score 0 0 withscores //排名第一的是谁,多少分
1) "person6"
2) "100"

现实生活中有很多类似的场景、业务都可以使用Sorted Sets来解决。电商系统可以使用Sorted Sets来维护每个用户的月消费额度,对用户分级并进行不同的促销措施;门户网站可以记录用户每周或每月的登录次数,并对活跃用户加以积分奖励等手段;博额系统可以对每篇博客的阅读量、好评率进行统计,从进评选精品文章等等,应用的场景实在是太多了,只有你想不到,没有做不到,而且别忘了,Redis很快。

Redis命令

前面我们已经看到,Redis的每种数据类型都提供了一组相关的命令,掌握并灵活地使用这些命令是用好Redis最基本的要求,官方文档里面有每个命令的详细说明,这里我们就不再重重了。值得注意的是每个命令的时间复杂度,一般有O(1)、O(logN)和O(N)等等几种,在生产环境一定要检查每个命令的复杂度,如果重杂复是类似O(logN)这种与数据量相关的命令,在数据量巨大的时候就可能成为性能瓶颈,这里需要查阅文档看看其它命令或者若干其它命令的组合是否可以完成相同的功能,以此来提升性能。
Redis所有命令都是原子性的,这是因为Redis内部是使用单线程实现的,就算不同的客户端同一时刻发送多条命令到Redis Server,这些命令也是串行执行的,因为在Redis Server中只有一个线程依次地处理它们。Redis能否像数据库事务一样,支持多条命令的原子性呢?答案是肯定的,Redis支持事务,相关的内容我们后续再介绍。
除了与数据类型相关的命令,还有一些一类型无关的命令,这里我们简单介绍一些。
Redis中也有数据库的概念,就像在数据库系统中我们可以建立多个数据库一样。在Redis中数据库是通过一个数字来标识的,默认情况下是连接到0这个库,可以使用select选择当前的数据库。
127.0.0.1:6379> select 1 //改变当前库为1
OK
127.0.0.1:6379[1]> select 0 //改变当前库为0,默认库
OK
127.0.0.1:6379> 

exists命令可以检查某个key是否存在;del命令删除key;keys命令可以根据正则查询有哪些key,但这个命令最好不要在生产环境使用;rename可以修改key的名字。
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> set key2 2
OK
127.0.0.1:6379> exists key1
(integer) 1
127.0.0.1:6379> exists key0
(integer) 0
127.0.0.1:6379> del key1
(integer) 1
127.0.0.1:6379> keys *
1) "key2"
127.0.0.1:6379> rename key2 key2-new
OK
127.0.0.1:6379> keys *
1) "key2-new"
127.0.0.1:6379> 

Redis还支持为key指定一个过期时间,当某个key达到过期时间后,Redis将会删除这个key。这个特性使得Redis非常适合用来做缓存。expire命令可以设置某个key多长时间后过期(单位:秒),ttl命令可以查询key多久后过期,persist命令删除key的过期时间(永不过期)。
12