一、 String
1. 缓存
简单的key-value存储
2. 分布式锁
setnx key value,当key不存在时,将key 的值设为 value ,返回1;
若给定的 key 已经存在,则setnx不做任何动作,返回0。
当setnx返回1时,表示获取锁,做完操作以后del key,表示释放锁;如果 setnx返回0表示获取锁失败,整体思路大概就是这样
3. 计数器
Redis中有一个字符串相关的命令incr key,incr命令将 key 中储存的数字值增一,返回结果分为以下三种情况:
- 值不是整数,返回错误
- 值是整数,返回自增后的结果
- key不存在, key 的值会先被初始化为 0 ,返回1
比如文章的阅读量,视频的播放量等等都会使用redis来计数,每播放一次,对应的播放量就会加1,同时将这些数据异步存储到数据库中达到持久化的目的。
set key 0
incr key // incr readcount::{帖子id} 每阅读一次
get key // get readcount::{帖子id} 获取阅读量
4. IP限制
为了安全考虑,会对IP进行限制,限制同一IP在一定的时间内访问次数不能超过N次
二、 List
Redis 里的 List 是一个链表,由于链表本身插入和删除比较块,但是查询的效率比较低,所以常常被用做异步队列。Redis 里的 List 设计非常牛,当数据量比较小的时候,数据结构是压缩链表,而当数据量比较多的时候就成为了快速链表。
列表类型用来存储多个有序的字符串,一个列表最多可以存储2^32-1个元素,列表的两端都可以插入和弹出元素。
1.消息队列
在业务中异步队列使用 rpush/lpush 操作队列,使用 lpop 和 rpop 出队列,具体结构如下图所示:
Redis虽然支持消息队列的实现,但是并不支持ack。所以redis实现的消息队列不能保证消息的可靠性,除非自己实现消息确认机制,不过这非常麻烦,所以如果是重要的消息还是推荐使用专门的消息队列去做。
2.文章列表
因为列表的元素不但是有序的,而且还支持按照索引范围获取元素。因此我们可以使用命令lrange key 0 9分页获取文章列表
三、 Hash
Redis的散列可以让用户将多个键值对存储到一个Redis的键里面,散列非常适用于将一些相关的数据存储在一起。类似map的一种结构,将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存到redis中,以后每次读写内存时,就可以操作hash里的某个字段。
1.Hash内部编码
哈希类型的内部编码有俩种
- zipList(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)同时所有值都小于hash-max-ziplist-value配置(默认64字节)时使用。ziplist使用更加紧凑的结构实现多个元素的连续存储,所以比hashtable更加节省内存。
- hashtable(哈希表):当ziplist不能满足要求时,会使用hashtable。
2.使用场景
由于hash类型存储的是多个键值对,比如数据库有以下一个用户表结构
ID | NAME | age |
---|---|---|
1 | 靓仔 | 28 |
hset user:1 name 靓仔 age 28
使用哈希存储会比字符串更加方便直观
四、 set
set集合类型也可以保存多个字符串元素,与列表不同的是,集合中不允许有重复元素并且集合中的元素是无序的。一个集合最多可以存储2^32-1个元素。
无序集合,自动去重,将数据放到set中就可去重,可以基于JVM的HashSet去重,如果系统部署在多台机器上,就可以用redis进行全局去重。可以基于set做交集,并集,差集的操作。如把2个人的粉丝列表弄一个交集,就能看到两个人的共同好友是谁。
1. 抽奖功能
集合有两个命令支持获取随机数,分别是:
- 随机获取count个元素,集合元素个数不变
srandmember key [count]
- 随机弹出count个元素,元素从集合中弹出,集合元素个数改变
spop key [count]
用户点击抽奖按钮,参数抽奖,将用户编号放入集合,然后抽奖,分别抽一等奖、二等奖,如果已经抽中一等奖的用户不能参数抽二等奖则使用spop,反之使用srandmember。
五、 Zset(sorted set )
zset是Redis中最具有特色的数据结构(跳跃列表),首先它有set不可重复的特性,在这个基础上,还可以给value赋予一个排序权重score,所谓的有序其实就是根据这个得分来排序。排序的set,可以去重还可以排序,写进去的时候给一个分数,自动根据根据分数排序,分数可以自定义排序规则。
Redis 有序集合zset和集合set一样也是String类型元素的集合,且不允许重复的成员。不同的是 zset 的每个元素都会关联一个分数(分数可以重复),redis 通过分数来为集合中的成员进行从小到大的排序。Redis的zset天生是用来做排行榜的,榜单,总榜,热榜。
1、zset内部编码
有序集合类型的内部编码有两种:
ziplist(压缩列表):当有序集合的元素个数小于list-max-ziplist-entries配置(默认128个)同时所有值都小于list-max-ziplist-value配置(默认64字节)时使用。ziplist使用更加紧凑的结构实现多个元素的连续存储,更加节省内存。
skiplist(跳跃表):当不满足ziplist的要求时,会使用skiplist。
2、排行榜
用户发布了n篇文章,其他人看到文章后给喜欢的文章点赞,使用score来记录点赞数,有序集合会根据score排行。流程如下
用户发布一篇文章a,初始点赞数为0,即score为0
zadd user:article 0 a
有人给文章a点赞,递增1
zincrby user:article 1 a
查询点赞前三篇文章
zrevrangebyscore user:article 0 2
查询点赞后三篇文章
zrangebyscore user:article 0 2