一、引言核心知识点
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 num:Hash字段原子整数增减,支持正负数值,仅纯数字字段生效
示例:hincrby user:1001 score 10 // 用户积分字段+10
示例:hincrby user:1001 score -5 // 用户积分字段-5
11. hincrbyfloat key field float-num:Hash字段浮点数原子增减,支持小数运算
示例: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 Set:List有序可重复、适合队列/时间轴;Set无序不可重复、适合去重
2. Set vs ZSet:Set无序无分值、仅去重;ZSet带分值自动排序、适配排行榜
3. String vs Hash:String存单个整体字符串、适合简单缓存/计数器;Hash存多字段对象、适合局部更新
8.2 业务场景选型速查表
|
业务需求 |
推荐数据结构 |
核心原因 |
|---|---|---|
|
计数器、验证码、简单缓存 |
String |
原子运算、支持过期、性能极致 |
|
轻量消息队列、时间轴、浏览记录 |
List |
有序、支持阻塞读写、头尾操作高效 |
|
去重、社交关系、标签匹配、抽奖 |
Set |
自动去重、支持高效集合运算 |
|
用户/商品对象存储、局部字段更新 |
Hash |
结构清晰、无需整体替换、节省key资源 |
|
实时排行榜、优先级队列、权重排序 |
ZSet |
天然分值排序、范围查询性能优异 |
8.3 生产环境避坑指南
1. 禁止使用阻塞高危命令:大数据量下禁用 keys *、smembers、hgetall,会阻塞Redis主线程,导致服务雪崩
2. 杜绝Big Key:超大String、超多层Hash、超大集合均为Big Key,会引发读写阻塞、内存溢出,需拆分key、精简数据
3. Hash结构控制字段数:单key字段数尽量低于512个,避免哈希扩容性能衰减
4. 超大集合运算规避:海量数据Set交集/并集运算需离线执行,避免线上阻塞
九、结语核心要点
Redis性能优化的核心前提:因地制宜选择匹配业务的数据结构,合理选型可规避90%的Redis性能问题。
进阶学习方向:Redis RDB/AOF持久化机制、缓存穿透/击穿/雪崩解决方案、Redis集群、分布式锁、高级数据结构实战。

896

被折叠的 条评论
为什么被折叠?



