文章目录
- 一、Redis核心数据类型应用场景复习
- 1. String结构
- 2. Hash类型
- 3. List类型
- 4. Set类型
- 5. ZSet类型
- 二、 Bitmap(位图)
- 1. 核心原理
- 2. 常用命令
- 3. 应用场景
- 三、 Geo(地理位置)
- 1. 核心原理
- 2. 常用命令
- 3. 企业级应用场景
- 四、 Stream(数据流)
- 1. 核心原理
- 2. 常用命令
- 3. 企业级应用场景
- 五、 HyperLogLog(基数统计)
- 1. 核心原理
- 2. 常用命令
- 3. 企业级应用场景
一、Redis核心数据类型应用场景复习
1. String结构
- 单值缓存
- 对象缓存
- 分布式锁
2. Hash类型
- 对象缓存
- 购物车
3. List类型
- 数据结构的实现:栈、队列、阻塞队列
- 排队机
- 简化MQ
4. Set类型
- 微信抽奖小程序
- 朋友圈点赞
- 集合操作
5. ZSet类型
- 排行榜
二、 Bitmap(位图)
1. 核心原理
Bitmap 本质上依然是String类型(最大 512MB)。它允许你直接对字符串的二进制位(Bit)进行操作。每个位只能是 0 或 1。由于 1 个字节(Byte)等于 8 个二进制位,用它来记录只有两种状态的数据,内存占用极小。
2. 常用命令
# 1. 设置指定偏移量(offset)上的位值(0或1)SETBIT user:sign:1001:202605271# 2. 获取指定偏移量上的位值GETBIT user:sign:1001:20260527# 3. 统计字符串中被设置为 1 的二进制位数量(注意:start 和 end 是字节/Byte索引,非bit索引)BITCOUNT user:sign:1001:2026050-1# 4. 位运算:对多个 Bitmap 进行 AND(与)、OR(或)、NOT(非)、XOR(异或),结果存入 destkeyBITOP AND active:result:20260527_28 active:20260527 active:20260528# 5. 查找第一个被设置为 0 或 1 的比特位位置BITPOS active:2026052813. 应用场景
用户每日签到与打卡系统:
设计:
key = user:sign:用户ID:年份月份(如user:sign:1001:202605),offset代表当月的第几天(从 0 开始,即天数 - 1)。落地:用户在 5 月 28 日签到,直接执行
SETBIT ... 27 1。月底通过BITCOUNT瞬间算出该用户本月的总签到天数。配合BITPOS还能快速定位用户当月首次签到是哪一天。
亿级活跃用户(UV)与留存率统计:
设计:
key = active:20260528(日期作为 key),offset直接设为用户整型 ID。落地:只要用户今日登录,就把对应 ID 的位设为 1。若要统计“ 5月27日 和 5月28日 两天都活跃的留存用户”,直接使用
BITOP AND dest_key active:20260527 active:20260528进行交集运算,再对dest_key执行BITCOUNT。
用户在线状态 / 权限标签标记:
- 落地:在即时通讯(IM)系统或大型网游中,用一个全局 key 记录所有用户的在线状态。上线置 1,下线置 0。判断一个用户是否在线只需
GETBIT,比查数据库快几个数量级。
- 落地:在即时通讯(IM)系统或大型网游中,用一个全局 key 记录所有用户的在线状态。上线置 1,下线置 0。判断一个用户是否在线只需
三、 Geo(地理位置)
1. 核心原理
Geo 是 Redis 3.2 引入的地理位置类型,其底层是基于Sorted Set(Zset)实现的。Redis 使用了Geohash 算法,将二维的经纬度坐标(Longitude, Latitude)编码成一个一维的二进制字符串(并通过 Base32 展现),最终这个二进制串会被转化为一个 52 位的整数,作为 Zset 的score分数存储。
2. 常用命令
# 1. 添加一个或多个地理位置的点位(经度、纬度、名称)GEOADD china:matrix116.40396339.915119"天安门饭店"116.40411139.909222"前门小吃"# 2. 获取指定点位的经纬度GEOPOS china:matrix"天安门饭店"# 3. 计算两个点位之间的物理距离(支持 m、km、mi英里、ft英尺)GEODIST china:matrix"天安门饭店""前门小吃"km# 4. 范围搜索(Redis 6.2+ 核心推荐,取代了旧版的 GEORADIUS)# 示例:以经纬度 (116.40, 39.91) 为中心,搜索方圆 5 公里内的点,按距离升序排列,返回坐标和距离GEOSEARCH china:matrix FROMLONLAT116.4039.91BYRADIUS5km ASC WITHCOORD WITHDIST# 5. 获取元素的 Geohash 字符串值GEOHASH china:matrix"天安门饭店"3. 企业级应用场景
外卖 App / 打车软件的“附近的商家 / 附近的车”:
- 落地:商家或外卖骑手上线时,通过后台定时任务或者经纬度上报接口,将最新的坐标用
GEOADD写入 Redis(以城市或区域为 Key)。当用户打开 App 时,App 获取用户的当前定位,调用GEOSEARCH瞬间搜出方圆 3 公里内的所有商家/车辆,并直接按距离由近到远排序输出。
- 落地:商家或外卖骑手上线时,通过后台定时任务或者经纬度上报接口,将最新的坐标用
物流货运 / 快递路线轨迹规划与时效预测:
- 落地:快递货车在行驶过程中实时上报 GPS 坐标,通过
GEODIST计算货车当前位置与下一个分拨中心、各个中转站之间的物理距离,结合时速算法动态预测剩余送达时间(ETA),并在用户前端地图上展示车辆轨迹。
- 落地:快递货车在行驶过程中实时上报 GPS 坐标,通过
社交软件“附近的人”与同城交友:
- 落地:用户开启“允许查看附近的人”后,将其 ID 和经纬度存入 GEO。当其检索附近的人时,不仅能拉出物理距离最近的用户,还可以通过 Zset 的原生命令进行多维度复合筛选(如结合在线时间)。
四、 Stream(数据流)
1. 核心原理
Stream 是 Redis 5.0 引入的全新数据结构,是专门为了解决原生 List、Pub/Sub 做消息队列时的痛点而设计的“专业级 Redis 版 MQ”。它底层依赖Rax 树(基数树)和Listpack(紧凑列表)。它兼具消息持久化、阻塞读取、支持消费者组(Consumer Group)以及消息消费确认(ACK 机制)等核心特性,结构高度类似于轻量级的 Kafka。
2. 常用命令
# 1. 向 Stream 队列中追加消息(* 表示由 Redis 自动生成全局唯一ID:时间戳-自增序列)# MAXLEN ~ 10000 表示自适应修剪队列长度,防止队列无限增长撑爆内存XADD order_stream MAXLEN ~10000* order_id20260528001price99.8# 2. 独立/阻塞式读取消息(不使用消费者组,$ 代表读取最新消息,0 代表从头读取)XREAD COUNT5BLOCK2000STREAMS order_stream $# 3. 为指定的 Stream 创建一个消费者组XGROUP CREATE order_stream group_warehouse0# 4. 消费者组内的消费者去消费消息(> 代表读取从未分配给其他消费者的最新消息)XREADGROUP GROUP group_warehouse worker_001 COUNT2BLOCK2000STREAMS order_stream># 5. 查看消费者的待确认列表(PEL,Pending Entries List)XPENDING order_stream group_warehouse - +10# 6. 确认消息(ACK),将该消息从正在处理的待确认列表(PEL)中彻底移除XACK order_stream group_warehouse1685286000000-0# 7. 消息转移(XCLAIM):当某个消费者挂掉导致消息长期未 ACK,由另一个消费者强行接管XCLAIM order_stream group_warehouse worker_00236000001685286000000-03. 企业级应用场景
中小型项目的轻量级分布式消息队列(MQ):
落地:在电商或政务系统中,订单系统生成订单后,通过
XADD异步写入order_stream。仓储系统和支付系统分别挂在不同的“消费者组”下。一条订单消息会被分发给支付组和仓储组,但仓储组内的各个worker之间是竞争消费(保证不重复处理)。异常处理:如果某个
worker抓取了消息但在写入数据库前突然宕机,这条消息会一直卡在它的PEL(待确认列表)中。系统重启或守护线程通过XCLAIM可以把这条死信重新捞出来派发给其他正常运行的worker,确保消息绝对不丢失。
实时日志 / 事件流式数据收集:
- 落地:用于行为日志、IoT 设备传感器数据的并发高频写入。利用
MAXLEN ~ 10000维持一个滚动窗口,只保留最新的 1 万条数据。后端分析程序通过消费者组像流水线一样源源不断地消费并进行流式计算。
- 落地:用于行为日志、IoT 设备传感器数据的并发高频写入。利用
五、 HyperLogLog(基数统计)
1. 核心原理
HyperLogLog(HLL)是 Redis 2.8.9 引入的一种概率性数据结构,专门用来做基数统计(即去重计数)。它的底层基于伯努利试验和基数估算算法。
它的最大魅力在于:无论你往里面输入多少个元素(哪怕是几十亿个),它所占用的内存都是固定的(最大只需 12KB 左右)。代价是它有极小的标准误差(约0.81 % 0.81\%0.81%),且只能计数,不能取出具体存入了哪些数据。
2. 常用命令
# 1. 添加一个或多个元素到 HyperLogLog 中# 复杂度:O(1)PFADD website:uv:20260528"user_id_9527""user_id_8888""user_id_9527"# 2. 统计指定 HyperLogLog 的近似基数(去重后的数量)# 复杂度:O(1) 或 O(N)(小规模时)PFCOUNT website:uv:20260528# 3. 合并多个 HyperLogLog 到一个新 key 中(求并集)# 复杂度:O(N),N 为被合并的 key 数量PFMERGE website:uv:may_total website:uv:20260527 website:uv:202605283. 企业级应用场景
百万/亿级高并发网站的页面 UV(独立访客)统计:
- 落地:比如大促期间统计某个爆款商品的独立浏览用户数。如果用
Set存储几十万个用户 ID,内存会轻易飙升到几十兆;而使用PFADD product:uv:1001 user_id,无论来多少用户,Redis 始终只用12KB搞定。
- 落地:比如大促期间统计某个爆款商品的独立浏览用户数。如果用
海量网络爬虫的 URL 去重计数 / 广告点击去重:
- 落地:广告主投放广告时,按点击的独立 IP 数计费。为了防止作弊和重复计费,可以为每个广告位生成一个 HLL,当点击事件发生时进行
PFADD。结算时调用PFCOUNT即可获得精准度极高(99.19 % 99.19\%99.19%以上)的扣费基数。
- 落地:广告主投放广告时,按点击的独立 IP 数计费。为了防止作弊和重复计费,可以为每个广告位生成一个 HLL,当点击事件发生时进行
多维度数据聚合统计(如月度活跃、季度活跃):
- 落地:每天生成一个 HLL 记录活跃用户。到了月底,通过
PFMERGE将 31 天的 HLL 合并成一个全新的month_total,然后通过PFCOUNT直接拿到整个月的去重活跃总人数。
- 落地:每天生成一个 HLL 记录活跃用户。到了月底,通过