Redis的数据结构及其使用场景

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全局IDincrby分库分表的场景,一次性拿一段记录ID
String计数器incr阅读量、点赞数等
String限流incr以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false
String位统计setbit、getbit
bitop、bitcount
在线用户统计,留存用户统计
list最新列表lpush、ltrim用户消息时间线timeline,保证插入有序
例如微博的时间轴,有人发布微博,用lpush加入时间轴,LTRIM可用来限制列表的数量,这样取到的永远是最新的N条消息
list消息队列blpop、brpopblpop key1 timeout 移除并获取列表的第一个元素,
如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
blpop key1 timeout 移除并获取列表的最后一个元素,
如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
list队列rpush blpop先进先出,左头右尾,右边进入队列,左边出队列
listrpush 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推送时,进行如下操作:

  1. 给自己的增加一个未读的对话
  2. 给自己的私信增加一个未读消息
  3. 最后给发送人回执一个完成推送消息

这一层逻辑完全可以在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版权协议,转载请附上原文出处链接和本声明。