1 redis的数据结构
Redis的数据结构共5种,如下:
- String:字符串类型,常用操作:get 、 set 、 del 、 incr、 decr
- List:列表类型
是双向链表,元素是有序的,value可以重复,可以通过下标取出对应的value值,左右两边都能进行插入和删除数据
使用列表的技巧,命令用法参见官网- lpush+lpop=Stack(栈)
- lpush+rpop=Queue(队列)
- lpush+ltrim=Capped Collection(有限集合)
- lpush+brpop=Message Queue(消息队列)
- Set:无序集合类型,常用操作:sadd 、srem、scard、smembers、sismember
特点如下:- 不允许有重复的元素,
- 集合中的元素是无序的,不能通过索引下标获取元素,
- 支持集合间的操作,可以取多个集合取交集、并集、差集
- ZSet:有序集合类型,常用操作: zadd 、 zrange、 zscore
与set的区别如下:- 有序集合中的元素是可以排序的
- 每个元素设置一个分数,作为排序的依据,分数值可以相同。
- Hash:哈希表类型,数据结构相当于Map<String,Map<String,Object>>,常用操作:hget 、hset 、 hdel 、hgetall

2 使用场景
2.1 常用使用场景
针对Redis的典型使用场景总结如下:
| 数据结构 | 使用场景 | 命令 | 备注 |
|---|---|---|---|
| String | 数据缓存 | set get del | 热点数据缓存 对象缓存 全页缓存 |
| String | 数据共享 | set get ttl | 分布式Session,如spring-session-data-redis |
| String | 分布式锁 | setnx、expire delete、watch | |
| String | 全局ID | incrby | 分库分表的场景,一次性拿一段记录ID |
| String | 计数器 | incr | 阅读量、点赞数等 |
| String | 限流 | incr | 以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false |
| String | 位统计 | setbit、getbit bitop、bitcount | 在线用户统计,留存用户统计 |
| list | 最新列表 | lpush、ltrim | 用户消息时间线timeline,保证插入有序 例如微博的时间轴,有人发布微博,用lpush加入时间轴,LTRIM可用来限制列表的数量,这样取到的永远是最新的N条消息 |
| list | 消息队列 | blpop、brpop | blpop key1 timeout 移除并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 blpop key1 timeout 移除并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 |
| list | 队列 | rpush blpop | 先进先出,左头右尾,右边进入队列,左边出队列 |
| list | 栈 | rpush brpop | 先进后出,左头右尾,右边进入队列,右边出队列 |
| set | 抽奖 | spop key [count] | spop 从集合中删除并返回一个或多个随机元素 |
| set | 社交网络 | sadd、srem sismember、smembers scard、sinter、sdiff | 点赞、踩、关注/被关注、共同好友、用户标签等是社交网站的基本功能,基于哈希、集合等数据结构能很方便的的实现这些功能 |
| zset | 排行榜 | zincrby、zrevrange | 小说视频等网站的小说视频排行榜 热点新闻排行榜 |
2.2 其它使用场景
2.2.1 事务处理
Fast transaction with Lua
基于Redis 的Lua的功能扩展实现事务处理。
可以编写若干command组合作为一个小型的非阻塞事务或者更新逻辑,如:在收到message推送时,进行如下操作:
- 给自己的增加一个未读的对话
- 给自己的私信增加一个未读消息
- 最后给发送人回执一个完成推送消息
这一层逻辑完全可以在Redis Server端实现。
注意:Redis会将lua script的全部内容记录在aof和传送给slave,这也将对磁盘、网络造成一个不小的开销。
Multi-Exec-Discard
用Multi(Start Transaction)、Exec(Commit)、Discard(Rollback)实现。
- 在事务提交前,不会执行任何指令,只会把它们存到一个队列里,不影响其他客户端的操作。在事务提交时,批量执行所有指令。
- 一般情况下redis在接受到一个client发来的命令后会立即处理并返回处理结果,但是当一个client在一个连接中发出multi命令后,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一个队列中。
- 当从此连接收到exec命令后,redis会顺序的执行队列中的所有命令,并将所有命令的运行结果打包到一起返回给client.然后此连接就结束事务上下文。
- 使用discard命令来取消一个事务。
Redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。
注意: redis只能保证事务的每个命令连续执行,但是如果事务中的一个命令失败了,并不回滚其他命令。另外一个十分罕见的问题是当事务的执行过程中,如果redis意外的挂了。只有部分命令执行了,后面的也就被丢弃了。
2.2.2 Pub/Sub
Redis的Pub/Sub非常非常简单,运行稳定并且快速。支持模式匹配,能够实时订阅与取消频道。
参考
https://www.runoob.com/redis/redis-strings.html
https://redis.io/commands/spop
Redis开发运维实践指南
版权声明:本文为penriver原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。