深入浅出Redis:五大数据结构与实战场景

一、引言核心知识点

1. Redis核心定义:开源、高性能、非关系型内存数据库,支持数据持久化,可将内存数据落地磁盘,断电不丢失,是高并发系统标配中间件。

2. 核心优势:区别于普通KV缓存,Redis支持五种核心数据结构,可适配绝大多数互联网业务场景,而非简单的单一键值存储。

3. 本文核心内容:拆解String、List、Set、Hash、ZSet五大结构的底层特点、核心命令、优缺点,匹配对应实战业务场景,附带选型与避坑指南。


二、基础知识概览

2.1 Redis数据库结构

1. 默认数据库数量默认内置16个数据库,编号0-15,数据库之间数据相互隔离。

2. 数据库切换命令:select index

示例:select 1 // 切换到1号数据库

3. 底层存储本质全局哈希表结构Key固定为字符串类型,Value存储对应数据结构的内存指针,所有数据读写时间复杂度大多为O(1)

2.2 通用基础命令(全数据结构通用)

所有命令附实操示例,重点风险命令加粗警示

1. keys *查询当前库所有key高危阻塞命令,大数据量下遍历所有key,阻塞主线程,生产环境禁止使用

示例:keys * // 列出当前数据库全部key(仅测试环境使用)

2. exists key判断key是否存在,返回1(存在)/0(不存在)

示例:exists user:1001 // 判断user:1001是否存在

3. del key删除指定key,支持批量删除

示例:del user:1001 count:view // 删除两个指定key

4. expire/pexpire设置key过期时间,expire单位秒,pexpire单位毫秒

示例:expire code:1001 300 // 验证码key5分钟后过期
示例:pexpire temp:data 10 // 临时数据10毫秒后过期

5. ttl/pttl查看key剩余过期时间,ttl单位秒,pttl单位毫秒;返回-1(永久有效)、-2(已过期)

示例:ttl code:1001 // 查看验证码剩余过期秒数

6. type key查看key对应的数据结构类型

示例:type user:1001 //返回string / hash / list等类型

7. rename oldkey newkey重命名key

示例:rename count:view count:article:1001  //给count:view起了一个新名字count:article:1001

三、String 字符串(最基础、最高频)

3.1 底层与核心特点

1. 底层:纯键值映射结构时间复杂度O(1),读写性能极高

2. 限制:仅存储字符串类型,数字本质也是字符串,数值运算需专属原子命令

3. 核心禁忌禁止存储Big Key(超大字符串),会导致读写阻塞主线程

3.2 核心基础命令

1. set key value设置键值对,存在则覆盖,初始key不存在时则创建

示例:set name zhangsan

2. get key获取key对应值

示例:get name // 返回zhangsan

3. mset k1 v1 k2 v2批量设置多个键值对,原子操作

示例:mset age 20 gender male

4. mget k1 k2批量获取多个key的值

示例:mget name age gender

5. strlen key获取字符串长度

示例:strlen name // 返回8(zhangsan有8个字符)

3.3 进阶核心命令(重点)

原子自增自减(无线程安全问题,计数器核心用法)

1. incr key数值自增1(仅纯数字字符串生效)

示例:incr count:view // 文章访问量+1

2. decr key数值自减1

示例:decr count:stock // 商品库存-1

3. incrby key num指定步长自增

示例:incrby count:like 10 // 点赞量+10

4. decrby key num指定步长自减

示例:decrby count:score 5 // 积分-5

字符串拼接与截取

5. append key value追加字符串内容

示例:append name _vip // name值变为zhangsan_vip

6. getrange key start end截取指定索引区间字符串

示例:getrange phone 0 3 // 截取手机号前4位

7. setrange key offset value从指定索引覆盖字符串

示例:setrange phone 4 **** // 手机号中间4位打码

3.4 优缺点剖析

✅ 优点:结构简单、读写极速、支持过期时间、支持原子数值运算

❌ 缺点:单key仅存单个值,修改需整体替换;超大字符串会阻塞主线程,无法做精细化局部更新

3.5 实战业务场景

1. 业务计数器:文章访问量、点赞数、用户积分统计(依赖原子incr命令)

2. 验证码/临时令牌:设置过期时间,实现登录验证码、短信验证码限时失效

3. 通用缓存:序列化后的JSON对象、配置参数、静态文本缓存


四、List 列表(消息队列、时间轴专属)

4.1 底层与核心特点

1. 底层:双向链表结构,元素有序、可重复

2. 核心特性:支持阻塞读写操作,天然适配生产者消费者队列模型

3. 性能特点:头尾读写O(1),中间索引查询O(n),数据量越大查询越慢

4.2 核心命令

元素推入与弹出

1. lpush key v1 v2列表头部(左侧)插入元素,初始key不存在时则创建

示例:lpush msg:queue msg1 msg2 // 消息队列头部插入两条消息

2. rpush key v1 v2列表尾部(右侧)插入元素,初始key不存在时则创建

示例:rpush timeline:user1001 dynamic1 dynamic2 // 追加用户最新动态

3. lpop key (num)弹出头部第一个元素(可指定数量)

示例:lpop msg:queue     //默认从左侧弹出一个元素
示例:lpop msg:queue 3   //从左侧弹出3个元素

4. rpop key (num)弹出尾部最后一个元素(可指定数量)

示例:rpop timeline:user1001
示例:rpop timeline:user1001 2   //从右侧弹出2个元素

5.linsert key before/after "元素" value: 在指定元素前/后插入新元素

示例:linsert msg:queue before m1 m3   //在m1前插入m3
示例:linsert msg:queue after m1 m5    //在m1后插入m5

范围查询与长度统计

1. lrange key start end查询指定区间元素,-1代表最后一位

示例:lrange timeline:user1001 0 -1 // 查询用户全部动态

2. lindex key index根据索引查询单个元素

示例:lindex msg:queue 0 // 查询队列第一个消息(不弹出)

3. llen key获取列表元素总数

示例:llen msg:queue // 统计未消费消息数量

删除与修剪

1. lrem key count value删除指定数量的指定元素

示例:lrem msg:queue 3 msg1 // 删除3条msg1消息

2. ltrim key start end修剪列表,仅保留指定区间元素

示例:ltrim timeline:user1001 0 9 // 仅保留最新10条动态

3.lset key index value修改指定索引位置的元素

示例:lset msg:queue 2 msg4 // 修改索引为4的位置为msg4消息

阻塞队列核心命令(重点)

1. blpop key timeout阻塞式左弹出,无元素时阻塞等待(单位秒)

示例:blpop msg:queue 30 // 阻塞30秒等待消息

2. brpop key timeout阻塞式右弹出

示例:brpop task:queue 60

4.3 优缺点剖析

✅ 优点:头尾读写性能极高、元素有序、支持栈/队列模式、阻塞操作适配消息队列、支持动态修剪

❌ 缺点:中间索引查询为O(n)复杂度,索引越大速度越慢;元素不支持自动去重,需手动处理重复数据

4.4 实战业务场景

1. 轻量消息队列:基于blpop/brpop实现生产者-消费者模式,适配异步任务处理

2. 时间轴/最新动态:朋友圈、微博最新内容展示,保留有限条数动态

3. 操作日志/浏览历史:按时间顺序存储用户操作、商品浏览记录


五、Set 集合(去重、社交关系、集合运算)

5.1 底层与核心特点

1. 底层:哈希表结构元素无序、唯一不可重复

2. 核心亮点:支持高效交集、并集、差集运算,适配社交类业务

3. 查找复杂度:单元素查找O(1),集合大规模运算可能阻塞主线程

5.2 基础核心命令

1. sadd key m1 m2向集合添加元素,自动去重,初始key不存在时则创建

示例:sadd follow:1001 1002 1003 // 用户1001关注1002、1003

2. smembers key获取集合所有元素,大数据量高危阻塞命令,慎用

示例:smembers follow:1001

3. srem key m1 m2删除集合指定元素

示例:srem follow:1001 1002 // 取消关注1002

4. scard key获取集合元素总数

示例:scard follow:1001 // 统计用户关注数

5. sismember key member判断元素是否在集合中(1存在/0不存在)

示例:sismember follow:1001 1003 // 判断是否关注1003

6. spop key count随机弹出指定数量元素(抽奖核心命令)

示例:spop prize:user 1 // 随机抽取1名中奖用户并移除

7. srandmember key count随机获取指定数量的元素(不删除)

示例:srandmember prize:user 3   // 随机抽取3名中奖用户(不移除)

5.3 核心集合运算命令(重点)

1. sinter k1 k2求两个集合交集(共同元素)

示例:sinter follow:1001 follow:1002 // 查看两人共同关注

2. sunion k1 k2求两个集合并集(所有不重复元素)

示例:sunion friend:1001 friend:1002 // 合并两人好友列表

3. sdiff k1 k2求两个集合差集(前者独有元素)

示例:sdiff follow:1001 follow:1002 // 1001独有关注

4. sinterstore newk k1 k2交集结果存入新key(持久化运算结果)

示例:sinterstore common:follow follow:1001 follow:1002

5. sunionstore newk k1 k2并集结果存入新key

6. sdiffstore newk k1 k2差集结果存入新key

5.4 优缺点剖析

✅ 优点:自动去重、单元素查询极速、集合运算高效,完美适配社交关联业务

❌ 缺点:元素无序,展示需二次排序;内存占用较高;超大集合运算会阻塞主线程

5.5 实战业务场景

1. 社交关系:共同好友、共同关注、粉丝关联计算(依赖交集运算)

2. 抽奖系统:spop随机弹出元素,实现无重复抽奖

3. 标签系统:商品/用户多标签存储、共同标签匹配

4. 黑白名单:去重存储黑名单用户、IP,快速校验是否存在


六、Hash 哈希(对象存储神器)

6.1 底层与核心特点

1. 底层:嵌套哈希表结构,类比Java Map、Python Dict,一个key存储多个field-value键值对

2. 核心优势:支持局部字段更新、局部查询,无需操作整个对象

3. 性能阈值:单key字段数超过512个后性能显著下降,底层哈希扩容产生开销

6.2 核心命令

1. hset key field value设置单个字段,初始key不存在则创建

示例:hset user:1001 name lisi

2. hget key field获取单个字段值

示例:hget user:1001 name // 返回lisi

3. hmset key f1 v1 f2 v2批量设置多个字段(新版hset兼容批量,可替代)

示例:hmset user:1001 age 25 gender female

4. hmget key f1 f2批量获取多个字段

示例:hmget user:1001 name age gender

5. hgetall key获取所有字段和值,大数据量阻塞高危命令,慎用

示例:hgetall user:1001

6. hdel key f1 f2删除指定字段

示例:hdel user:1001 gender

7. hexists key field判断字段是否存在

示例:hexists user:1001 age

8. hlen key获取字段总数

示例:hlen user:1001

9. hkeys key获取所有字段名

示例:hkeys user:1001

10. hincrby key field numHash字段原子整数增减,支持正负数值,仅纯数字字段生效

示例:hincrby user:1001 score 10 // 用户积分字段+10

示例:hincrby user:1001 score -5 // 用户积分字段-5

11. hincrbyfloat key field float-numHash字段浮点数原子增减,支持小数运算

示例:hincrbyfloat goods:1001 price 0.5 // 商品单价+0.5

示例:hincrbyfloat goods:1001 price -1.2 // 商品单价-1.2

6.3 优缺点剖析

✅ 优点:单key存储完整对象,键值层级清晰;支持局部更新,无需整体替换;字段支持原子数值自增

❌ 缺点:字段数超512个性能骤降;大数据量下hgetall全量读取极易阻塞主线程

6.4 实战业务场景

1. 用户信息管理:单key存储用户ID、昵称、年龄、头像等信息,支持单独更新昵称、积分等字段

2. 电商购物车:key=用户ID,field=商品ID,value=商品数量,精准修改单品数量

3. 商品基础信息缓存:存储商品价格、库存、简介等可独立更新的字段


七、ZSet 有序集合(排行榜、优先级队列)

7.1 底层与核心特点

1. 底层:跳表+哈希表联合结构,兼顾有序性和查询效率

2. 核心特性:元素Member唯一,附带Score分值根据分值自动排序,分值可重复

3. 复杂度:增删改查为O(log n),维护跳表有轻微性能开销,远优于数据库排序

7.2 基础核心命令

1. zadd key score member添加有序元素(分值+成员)

示例:zadd rank:article 99 article1001 88 article1002 // 文章热度排行榜

2. zrange key start end [withscores]正序查询(分值从小到大)

示例:zrange rank:article 0 -1 withscores // 正序查全部文章及分值

3. zrevrange key start end [withscores]倒序查询(分值从大到小,排行榜核心)

示例:zrevrange rank:article 0 9 withscores // 查询热度前十文章

4. zscore key member查询指定成员的分值

示例:zscore rank:article article1001

5. zcard key获取有序集合元素总数

示例:zcard rank:article

6. zrem key member删除指定成员

示例:zrem rank:article article1002

7. zrank key member查询成员正序排名(从小到大排名,从0开始)

示例:zrank rank:article article1001

8. zrevrank key member查询成员逆序排名(从大到小排名,从0开始)

示例:zrevrank rank:article article1002

9. zincrby key increment member给指定成员增加指定步长

示例:zincrby rank:article 20 article1001

7.3 重点范围查询命令

inf:正无穷,-inf:负无穷

(min (max:不好含最小值与最大值

min max:包含最小值与最大值(不带括号,默认包含最小与最大值)

1. zcount key min max统计指定分值区间的元素数量

示例:zcount rank:article 80 100 // 统计热度80-100的文章数

2. zrangebyscore key min max根据分值区间查询元素(按从小到大)

示例:zrangebyscore rank:article 90 100 // 查询高分热度文章

3. zrevrangebyscore key max min根据分值区间查询元素(按从大到小)

示例:zrevrangebyscore rank:article 100 90 // 查询高分热度文章

7.4 优缺点剖析

✅ 优点:天然有序、范围查询性能极佳、支持精准排名,无需手动排序

❌ 缺点:相比其他结构,增删改查开销更高(O(log n)),跳表维护有内存开销

7.5 实战业务场景

1. 实时排行榜:文章热度、用户积分、商品销量、比赛积分榜

2. 优先级队列:根据任务权重分值,实现高优先级任务优先执行

3. 搜索自动补全:根据关键词搜索频次设置分值,优先展示高频关键词


八、核心总结与选型避坑指南

8.1 易混淆数据结构对比

1. List vs SetList有序可重复、适合队列/时间轴Set无序不可重复、适合去重

2. Set vs ZSetSet无序无分值、仅去重ZSet带分值自动排序、适配排行榜

3. String vs HashString存单个整体字符串、适合简单缓存/计数器Hash存多字段对象、适合局部更新

8.2 业务场景选型速查表

业务需求

推荐数据结构

核心原因

计数器、验证码、简单缓存

String

原子运算、支持过期、性能极致

轻量消息队列、时间轴、浏览记录

List

有序、支持阻塞读写、头尾操作高效

去重、社交关系、标签匹配、抽奖

Set

自动去重、支持高效集合运算

用户/商品对象存储、局部字段更新

Hash

结构清晰、无需整体替换、节省key资源

实时排行榜、优先级队列、权重排序

ZSet

天然分值排序、范围查询性能优异

8.3 生产环境避坑指南

1. 禁止使用阻塞高危命令大数据量下禁用 keys *smembershgetall,会阻塞Redis主线程,导致服务雪崩

2. 杜绝Big Key超大String、超多层Hash、超大集合均为Big Key,会引发读写阻塞、内存溢出,需拆分key、精简数据

3. Hash结构控制字段数:单key字段数尽量低于512个,避免哈希扩容性能衰减

4. 超大集合运算规避:海量数据Set交集/并集运算需离线执行,避免线上阻塞


九、结语核心要点

Redis性能优化的核心前提:因地制宜选择匹配业务的数据结构,合理选型可规避90%的Redis性能问题。

进阶学习方向:Redis RDB/AOF持久化机制、缓存穿透/击穿/雪崩解决方案、Redis集群、分布式锁、高级数据结构实战。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值