Redis核心数据结构实战

文章目录


概述

Redis有五种核心数据结构:

  1. String:标准的 key-value 结构:key -> value
  2. Hash:key -> field1:value1, field2:value2,类似双层 Map
  3. List:key -> 有序列表 [v1, v2, v3, ...]
  4. Set:key -> 无序、不重复元素集合 {v1, v2, v3}
  5. Zset:也称为sorted_set,key -> (member, score) 的集合,自动按 score 排序

一、String运用场景

String通常是项目中运用最多的场景,通常可用于单值缓存,对象缓存,计数器,生成ID序列等场景:

1.1、单值缓存

可运用于邮件验证码,短信验证码等临时信息的存储,这类数据的生命周期较短,没有必要存储在数据库中,在设置键时,通常是业务名称:用户手机号/邮箱这样的格式。

java 复制代码
phone:13211111111
email:13211111111@126.com

1.2、对象缓存

对象缓存和单值缓存的区别在于,对象缓存的value通常是转换为JSON格式的Java对象,在存储时进行序列化,查询时进行反序列化。

可用于缓存页面上列表的查询条件,键可以设置为业务名称:用户ID:页面上选择的查询条件

java 复制代码
fundlist:1:查询条件1_查询条件2_查询条件3

假设我有如下的数据:

id name age
1 zhagnsan 23
2 lisi 20
3 wanger 15

可以有两种存储的方式,方式一:

  • key:业务名称:用户ID
  • value:该用户ID对应的name和age,在java中是转换为json字符串的。
shell 复制代码
127.0.0.1:6379> SET user:1 "name:zhangsan age:23"
OK
127.0.0.1:6379> get user:1
"name:zhangsan age:23"

方式二,使用mset 命令:

  • key:业务名称:用户ID:某个属性名
  • value:该用户ID对应的属性名的属性值
shell 复制代码
127.0.0.1:6379> mset user:2:name zhangsan user:2:age 23
OK
127.0.0.1:6379> mset user:2:name lisi user:2:age 20
OK
127.0.0.1:6379> mget user:2:name
1) "lisi"

第二种方式的粒度更小,比第一种方式更加便于修改。第一种方式,存储的对象是一个整体,如果需要修改,则经过反序列化->修改->重新序列化的过程。而第二种方式细化到了对象的某个属性,针对于属性频繁修改的场景。

1.3、计数器

可以运用在文章阅读的计数,或者自增序列,该操作由Redis单线程保证原子性:

shell 复制代码
127.0.0.1:6379> INCR article:readcount:1
(integer) 1
127.0.0.1:6379> INCR article:readcount:1
(integer) 2
127.0.0.1:6379> INCR article:readcount:1
(integer) 3
127.0.0.1:6379> get article:readcount:1
"3"

1.4、批量生成序号

通过INCRBY命令获取批量序号,存入内存中进行分配使用:

shell 复制代码
127.0.0.1:6379> INCRBY orderId 1000
(integer) 1000
127.0.0.1:6379> get orderId
"1000"

二、Hash

Hash在项目中的运用场景,可以是对象缓存,以及临时购物车功能。Hash结构不建议存储单个key的value过大的数据,否则在集群环境下会造成数据倾斜

2.1、对象缓存

相比较于String,Hash适合结构扁平、字段不多、经常需要单独修改或读取某个字段的场景:

shell 复制代码
127.0.0.1:6379> hset user:3 name wanger age 18
(integer) 0
127.0.0.1:6379> hget user:3 name
"wanger"

2.2、临时购物车

电商网站,销售平台的临时购物车,也可以使用Redis的Hash结构进行存储:

  • key:业务名称:用户ID
    • field:商品ID
    • value:商品数量

加入购物车:

shell 复制代码
127.0.0.1:6379> hset cart:1 1 1
(integer) 1
127.0.0.1:6379> hset cart:1 2 5
(integer) 1

从购物车获取元素:

shell 复制代码
127.0.0.1:6379> hget cart:1 2
"5"

增加购物车数量

shell 复制代码
127.0.0.1:6379> HINCRBY cart:1 1 1
(integer) 2

购物车中一共有多少种类的商品

shell 复制代码
127.0.0.1:6379> HLEN cart:1
(integer) 2

删除某一样商品

shell 复制代码
127.0.0.1:6379> hdel cart:1 1
(integer) 1

获取购物车的所有商品

shell 复制代码
127.0.0.1:6379> HGETALL cart:1
1) "2"
2) "5"

三、List

List结构常用于实现分布式场景下的栈,队列,阻塞队列。在社交项目中,还可以实现消息的推送和接收

3.1、实现栈、队列、阻塞队列

实现先进后出的栈:

shell 复制代码
127.0.0.1:6379> lpush stack a
(integer) 1
127.0.0.1:6379> lpush stack b
(integer) 2
127.0.0.1:6379> lpush stack c
(integer) 3
127.0.0.1:6379> lpop stack
"c"

实现先进先出的队列:

shell 复制代码
127.0.0.1:6379> lpush queue 1
(integer) 1
127.0.0.1:6379> lpush queue 1
(integer) 2
127.0.0.1:6379> rpop queue
"1"

实现阻塞队列,需要设置超时时间

shell 复制代码
127.0.0.1:6379> lpush blocking_queue "1"
(integer) 1
127.0.0.1:6379> lpush blocking_queue "2"
(integer) 2
127.0.0.1:6379> brpop blocking_queue 5
1) "blocking_queue"
2) "1"
127.0.0.1:6379> brpop blocking_queue 5
1) "blocking_queue"
2) "2"
127.0.0.1:6379> brpop blocking_queue 5
(nil)
(5.01s)

3.2、消息推送

当微信公众号发送新文章时,需要推送给每一个订阅的用户:

  • key:业务名称:用户ID
  • value:消息ID
shell 复制代码
127.0.0.1:6379> LPUSH msg:1 1926
(integer) 1
127.0.0.1:6379> LPUSH msg:1 1848
(integer) 2
127.0.0.1:6379> LRANGE msg:1 0 4
1) "1848"
2) "1926"

客户端拿到消息ID后进行处理

四、Set

Set在项目中可以用于抽奖、点赞,收藏,以及共同关注的场景。

4.1、抽奖

用户在页面上点击一次抽奖,就向set集合中存放一个元素,利用set去重的特性,防止同一用户多次参与:

shell 复制代码
127.0.0.1:6379> sadd cj 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd cj 1 2 3 4 5
(integer) 0

查看抽奖的用户

shell 复制代码
127.0.0.1:6379> SMEMBERS cj
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"

进行抽奖(SRANDMEMBER不会删除set中的元素,而SPOP会)

shell 复制代码
127.0.0.1:6379> SRANDMEMBER cj 2
1) "4"
2) "5"

4.2、点赞、收藏

点赞,收藏同样利用的是sadd、smembers等命令:

shell 复制代码
127.0.0.1:6379> sadd like:1848 1
(integer) 1

取消点赞:

shell 复制代码
127.0.0.1:6379> SREM like:1848 1
(integer) 1

查询用户是否点过赞

shell 复制代码
127.0.0.1:6379> sismember like:1848 1
(integer) 1

获取点赞的用户列表:

shell 复制代码
127.0.0.1:6379> SMEMBERS like:1848 
1) "1"

获取点赞的用户数量:

shell 复制代码
127.0.0.1:6379> SCARD like:1848
(integer) 1

4.3、集合操作

集合操作有交集,并集,差集,首先定义三个集合:

shell 复制代码
127.0.0.1:6379> sadd set1 a b c
(integer) 3
127.0.0.1:6379> sadd set2 b c
(integer) 2
127.0.0.1:6379> sadd set3 b c d e
(integer) 4

127.0.0.1:6379> SMEMBERS set1
1) "b"
2) "c"
3) "a"
127.0.0.1:6379> SMEMBERS set2
1) "b"
2) "c"
127.0.0.1:6379> SMEMBERS set3
1) "e"
2) "b"
3) "c"
4) "d"

交集是求集合1和集合2共有的部分:

shell 复制代码
127.0.0.1:6379> SINTER set1 set2
1) "b"
2) "c"

并集是求集合1和集合2所有的部分:

shell 复制代码
127.0.0.1:6379> sunion set1 set2
1) "b"
2) "a"
3) "c"

差集返回所有存在于第一个集合,但不存在于其他一个或多个集合中的成员:

shell 复制代码
127.0.0.1:6379> sdiff set1 set2 set3
1) "a"

五、ZSet

ZSet也称为sorted_set,继承了Set的功能之外,增加了排序的功能,可使用于项目中的排行榜功能。

点击新闻:

shell 复制代码
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews1
"1"
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews1
"2"
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews1
"3"
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews1
"4"
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews2
"1"
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews2
"2"
127.0.0.1:6379> ZINCRBY hotnews:20250622 1 hotnews3
"1"

展示当日排行

shell 复制代码
127.0.0.1:6379> ZREVRANGE hotnews:20250622 0 10 withscores
1) "hotnews1"
2) "4"
3) "hotnews2"
4) "2"
5) "hotnews3"
6) "1"

展示多日榜单

shell 复制代码
127.0.0.1:6379> ZINCRBY hotnews:20250621 1 hotnews3
"1"
127.0.0.1:6379> ZINCRBY hotnews:20250620 1 hotnews3
"1"
127.0.0.1:6379> ZREVRANGE hotnews:20250620-20250622 0 10 withscores
1) "hotnews1"
2) "4"
3) "hotnews3"
4) "3"
5) "hotnews2"
6) "2"
相关推荐
我爱挣钱我也要早睡!5 分钟前
Java 复习笔记
java·开发语言·笔记
AD钙奶-lalala2 小时前
Mac OS上搭建 http server
java
知识分享小能手3 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
汇能感知5 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun5 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao5 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾6 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
皮皮林5516 小时前
SpringBoot 全局/局部双模式 Gzip 压缩实战:14MB GeoJSON 秒变 3MB
java·spring boot
weixin_456904276 小时前
Spring Boot 用户管理系统
java·spring boot·后端
趁你还年轻_6 小时前
异步编程CompletionService
java