Skip to content

高级应用

Stream 消息队列、限流、分布式 ID、排行榜、布隆过滤器。

Updated View as Markdown
For humans

高级应用

Redis 的数据结构组合出各种应用模式。面试主线:Stream 怎么当消息队列、限流怎么做、分布式 ID 和排行榜怎么用 zset。

Stream:轻量消息队列

Stream(5.0+)是 Redis 官方的消息队列结构:

能力 说明
XADD 追加消息,返回消息 ID(毫秒时间戳加序号)
XREADGROUP 消费者组读取,组内消息分发给不同消费者
消费确认 XACK 确认,未确认消息进 Pending 列表,可重试
消息留存 MAXLEN 限制长度,不自动删除

对比 Kafka:

维度 Stream Kafka
定位 轻量,随 Redis 部署 重量级独立系统
吞吐 十万级 百万级
持久化 Redis 持久化语义 磁盘日志,强持久
生态 分区、重平衡、流处理完整

选型结论:业务量小、不想引入 Kafka 时用 Stream;高吞吐、强持久、复杂消费语义用 Kafka。

限流

方案 实现 特点
固定窗口 INCR + EXPIRE(计数到阈值拒绝) 简单,窗口边界突刺(前后窗口交界可双倍流量)
滑动窗口 zset 记录时间戳,统计窗口内请求数 精确,zset 占用随请求量增长
令牌桶 Lua 脚本维护令牌数和上次补充时间 允许突发,平滑限流
漏桶 恒定速率处理 不允许突发,实现复杂

生产常用令牌桶(Lua 原子实现)加多级限流(网关层 + 应用层 + Redis 层)。

分布式 ID

  • INCR/INCRBY:Redis 自增,简单但依赖 Redis 可用性,批量取号(一次 INCRBY 100 本地分发)可减压力
  • 雪花算法(Snowflake):时间戳 + 机器 ID + 序列号,趋势递增,无中心依赖,业界主流(美团 Leaf 等)
  • 对比:UUID 无序且太长,不适合做索引;数据库自增受单点限制

排行榜

zset 天然适配:

  • 分数即排名依据,ZADD 更新,ZREVRANGE 取前 N 名,ZRANK 查排名
  • 实时榜单(直播间热度、游戏分数)都是 zset
  • 同分处理:分数可编码(如分数加时间戳小数位),或按字典序兜底

其他常用模式

模式 实现
布隆过滤器 RedisBloom 模块,防缓存穿透
UV 统计 HyperLogLog 12KB 统计上亿
签到/位图 bitmap 按位标记
附近的人 GEO(geohash 进 zset)
延迟队列 zset 按执行时间排序,轮询取到期任务

面试追问

  1. Stream 和 Kafka 怎么选? 量小轻量用 Stream,高吞吐强持久用 Kafka。Stream 是 Redis 的附属能力
  2. 固定窗口限流的问题? 窗口边界突刺:两个窗口交界处可放行双倍流量。滑动窗口精确但占内存
  3. 令牌桶怎么实现? Lua 原子维护令牌数和补充时间,按速率补令牌,有令牌才放行。允许突发
  4. 雪花算法的组成? 时间戳 + 机器 ID + 序列号,趋势递增。时钟回拨是主要风险
  5. 排行榜用什么结构? zset,ZADD 更新分数,ZREVRANGE 取榜单,O(log n) 查询
Navigation

Type to search…

↑↓ navigate↵ selectEsc close