Redis 的 3 种用法
- 内存缓存
- 定量数据指标
- 发布/订阅模型
作为内存环境
数据结构
1. 字符串 string
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| // 设置字符串类型 set mystr "hello world!" // 读取字符串类型 get mystr
// 通过字符串类型进行数值操作 在遇到数值操作时,redis 会将字符串类型转换成数值。 127.0.0.1:6379> set mynum "2" OK 127.0.0.1:6379> get mynum "2" 127.0.0.1:6379> incr mynum (integer) 3 127.0.0.1:6379> get mynum "3"
|
INCR 等指令本身就具有原子操作的特性,所以我们完全可以利用 redis 的 INCR、INCRBY、DECR、DECRBY 等指令来实现原子计数的效果,假如,在某种场景下有 3 个客户端同时读取了 mynum 的值(值为 2),然后对其同时进行了加 1 的操作,那么,最后 mynum 的值一定是 5。不少网站都利用 redis 的这个特性来实现业务上的统计计数需求。
2. 列表 list
Redis list 使用链表实现, 所以插入速度快, 查询速度慢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // 新建一个 list 叫做 mylist,并在列表头部插入元素 "1" 127.0.0.1:6379> lpush mylist "1" // 返回当前 mylist 中的元素个数 (integer) 1 // 在 mylist 右侧插入元素 "2" 127.0.0.1:6379> rpush mylist "2" (integer) 2 // 在 mylist 左侧插入元素 "0" 127.0.0.1:6379> lpush mylist "0" (integer) 3 // 列出 mylist 中从编号 0 到编号 1 的元素 127.0.0.1:6379> lrange mylist 0 1 1) "0" 2) "1" // 列出 mylist 中从编号 0 到倒数第一个元素 127.0.0.1:6379> lrange mylist 0 -1 1) "0" 2) "1" 3) "2"
|
lists 的应用相当广泛,随便举几个例子:
- 我们可以利用 lists 来实现一个消息队列,而且可以确保先后顺序,不必像 MySQL 那样还需要通过 ORDER BY 来进行排序。
- 利用 LRANGE 还可以很方便的实现分页的功能。
- 在博客系统中,每片博文的评论也可以存入一个单独的 list 中。
3. 无序集合 set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| // 向集合 myset 中加入一个新元素 "one" 127.0.0.1:6379> sadd myset "one" (integer) 1 127.0.0.1:6379> sadd myset "two" (integer) 1 // 列出集合 myset 中的所有元素 127.0.0.1:6379> smembers myset 1) "one" 2) "two" // 判断元素 1 是否在集合 myset 中,返回 1 表示存在 127.0.0.1:6379> sismember myset "one" (integer) 1 // 判断元素 3 是否在集合 myset 中,返回 0 表示不存在 127.0.0.1:6379> sismember myset "three" (integer) 0 // 新建一个新的集合 yourset 127.0.0.1:6379> sadd yourset "1" (integer) 1 127.0.0.1:6379> sadd yourset "2" (integer) 1 127.0.0.1:6379> smembers yourset 1) "1" 2) "2" // 对两个集合求并集 127.0.0.1:6379> sunion myset yourset 1) "1" 2) "one" 3) "2" 4) "two"
|
对于集合的使用,也有一些常见的方式,比如,QQ 有一个社交功能叫做 “好友标签”,大家可以给你的好友贴标签,比如 “大美女”、“土豪”、“欧巴” 等等,这时就可以使用 redis 的集合来实现,把每一个用户的标签都存储在一个集合之中。
4. 有序集合 zset
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 127.0.0.1:6379> zadd myzset 1 baidu.com (integer) 1 // 向 myzset 中新增一个元素 360.com,赋予它的序号是 3 127.0.0.1:6379> zadd myzset 3 360.com (integer) 1 // 向 myzset 中新增一个元素 google.com,赋予它的序号是 2 127.0.0.1:6379> zadd myzset 2 google.com (integer) 1 // 列出 myzset 的所有元素,同时列出其序号,可以看出 myzset 已经是有序的了。 127.0.0.1:6379> zrange myzset 0 -1 with scores 1) "baidu.com" 2) "1" 3) "google.com" 4) "2" 5) "360.com" 6) "3" // 只列出 myzset 的元素 127.0.0.1:6379> zrange myzset 0 -1 1) "baidu.com" 2) "google.com" 3) "360.com"
|
5. 哈希 hashes
哈希是从 redis-2.0.0 版本之后才有的数据结构。
hashes 存的是字符串和字符串值之间的映射,比如一个用户要存储其全名、姓氏、年龄等等,就很适合使用哈希。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| // 建立哈希,并赋值 127.0.0.1:6379> HMSET user:001 username dong4j password 1234 age 29 OK // 列出哈希的内容 127.0.0.1:6379> HGETALL user:001 1) "username" 2) "dong4j" 3) "password" 4) "1234" 5) "age" 6) "29" // 更改哈希中的某一个值 127.0.0.1:6379> HSET user:001 password 12345 (integer) 0 // 再次列出哈希的内容 127.0.0.1:6379> HGETALL user:001 1) "username" 2) "dong4j" 3) "password" 4) "12345" 5) "age" 6) "29"
|
6. HyperLogLog
Redis 的 HyperLogLog 使用随机化,以提供唯一的元素数目近似的集合只使用一个常数,并且体积小,少量内存的算法。
HyperLogLog 提供,即使每个使用了非常少量的内存(12 千字节),标准误差为集合的基数非常近似,没有限制的条目数,可以指定,除非接近 264 个条目。
1 2 3 4 5 6 7 8
| redis 127.0.0.1:6379> PFADD tutorials "redis" 1) (integer) 1 redis 127.0.0.1:6379> PFADD tutorials "mongodb" 1) (integer) 1 redis 127.0.0.1:6379> PFADD tutorials "mysql" 1) (integer) 1 redis 127.0.0.1:6379> PFCOUNT tutorials (integer) 3
|
作为定量数据指标
发布/订阅模型
Redis 的订阅实现了邮件系统,发送者(在 Redis 的术语中被称为发布者)发送的邮件,而接收器(用户)接收它们。由该消息传送的链路被称为通道。
在 Redis 客户端可以订阅任何数目的通道。
1 2 3 4 5 6
| redis 127.0.0.1:6379> SUBSCRIBE redisChat
Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "redisChat" 3) (integer) 1
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"
(integer) 1
redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by tutorials point"
(integer) 1
1) "message" 2) "redisChat" 3) "Redis is a great caching technique" 1) "message" 2) "redisChat" 3) "Learn redis by tutorials point"
|
Redis 事务
Redis 事务让一组命令在单个步骤执行。事务中有两个属性,说明如下:
- 在一个事务中的所有命令按顺序执行作为单个隔离操作。通过另一个客户端发出的请求在 Redis 的事务的过程中执行,这是不可能的。
- Redis 的事务具有原子性。原子意味着要么所有的命令都执行或都不执行。
Redis 的事务由指令多重发起,然后需要传递在事务,而且整个事务是通过执行命令 EXEC 执行命令列表。
1 2 3 4
| redis 127.0.0.1:6379> MULTI OK List of commands here redis 127.0.0.1:6379> EXEC
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET tutorial redis QUEUED redis 127.0.0.1:6379> GET tutorial QUEUED redis 127.0.0.1:6379> INCR visitors QUEUED redis 127.0.0.1:6379> EXEC
1) OK 2) "redis" 3) (integer) 1
|