Redis核心数据结构以及应用场景

Redis 常用8 种数据结构:String、List、Hash、Set、ZSet、Geo、Bitmap、HyperLogLog,附带底层、用法、典型场景。

一、1. String(字符串)

底层

简单动态字符串 SDS,最大 512MB。

常用命令

set / get / mset / mget / incr / decr / setnx / expire

应用场景

  1. 缓存:用户信息、商品数据、接口结果(最常用)

  2. 计数器:文章阅读量、点赞数、访问次数

  3. 分布式锁:setnx + expire 实现简单锁

  4. 限流:IP 限流、接口防刷

  5. 全局唯一 ID:incr 自增生成 ID

  6. 会话存储:登录 token、session

    二、2. List(列表)

底层

双向链表,头尾操作极快,中间访问慢。

常用命令

lpush / rpush / lpop / rpop / lrange / brpop(阻塞弹出)

应用场景

  1. 消息队列 / 简易队列:lpush + rpop

  2. 阻塞队列:brpop 实现简单延时/消费队列

  3. 时间线、信息流:朋友圈、动态列表、评论列表

  4. 栈:lpush + lpop

    三、3. Hash(哈希)

底层

ziplist / hashtable,field-value 结构。

常用命令

hset / hget / hmset / hmget / hincrby / hdel

应用场景

  1. 存储对象:用户信息、商品信息(比 String 更省内存)

  2. 购物车:用户ID→商品ID→数量

  3. 短字段聚合数据:多个小字段统一管理

    对比:存单个对象优先 Hash,不要拆多个 String。

    四、4. Set(集合)

底层

intset / 哈希表,无序、去重。

常用命令

sadd / smembers / sismember / sinter / sunion / sdiff / spop

应用场景

  1. 去重:访客 IP 去重、点赞用户去重

  2. 交集/并集/差集:

◦ 共同好友、共同关注

◦ 好友推荐、粉丝对比

  1. 随机抽奖:spop 随机弹出中奖用户

  2. 标签系统:文章/用户标签

    五、5. ZSet(有序集合 / Sorted Set)

底层

ziplist / 跳表(skiplist),去重 + 按 score 排序。

常用命令

zadd / zrange / zrevrange / zrank / zrem / zscore

应用场景(高频考点)

  1. 排行榜:热度榜、积分榜、销量榜、直播间榜单

  2. 延时队列:score 存时间戳,轮询取到期任务

  3. 带权重排序:优先队列、任务权重排序

  4. 范围查询:按分数区间筛选数据

    六、6. Bitmap(位图)

本质还是 String,按位操作。

常用命令

setbit / getbit / bitcount

应用场景

  1. 签到统计:用户每日签到(1 位代表 1 天)

  2. 活跃状态:用户在线/离线标记

  3. 海量布尔值统计(极度省内存)

    七、7. HyperLogLog

基数统计,概率算法,有误差(0.81%),极小内存统计海量去重数量。

常用命令

pfadd / pfcount / pfmerge

应用场景

  1. 页面 UV 统计(独立访客数)

  2. 海量数据去重计数(不计明细,只算总数)

    特点:只存数量,不存原始数据。

    八、8. Geo(地理位置)

基于 ZSet 实现,存储经纬度。

常用命令

geoadd / geohash / geopos / geodist / georadius

应用场景

  1. 附近的人 / 附近门店

  2. 距离计算、范围查找

    二、场景选型速查表(面试直接背)

• 单纯缓存、计数器、分布式锁、限流 → String

• 对象、购物车、多字段实体 → Hash

• 队列、栈、信息流、消息队列 → List

• 去重、交集并集、好友、标签、抽奖 → Set

• 排行榜、延时队列、有序任务 → ZSet

• 签到、布尔状态、海量标记 → Bitmap

• 大数据量 UV、独立访客计数(允许误差)→ HyperLogLog

• 经纬度、附近位置 → Geo

三、高频面试补充

  1. List 为什么适合做队列?

    双向链表,头尾 O(1),阻塞命令 brpop 可实现简单消息队列。

  2. ZSet 底层为什么用跳表不用红黑树?

    跳表范围查询、排序、区间遍历更优,实现简单,内存友好。

  3. Hash 与 String 存对象区别?

    Hash 可单独更新某个字段,省内存;String 需要整存整取。

  4. HyperLogLog 误差?

    标准误差 0.81%,适合统计量,不要求绝对精确。

相关推荐
Rust研习社16 小时前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
IT_陈寒16 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro17 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax17 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH17 小时前
Koa和Express的区别
后端
MariaH17 小时前
Koa框架的使用
后端
luckdewei18 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某20 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy20 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom20 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github