对于Redis:Steam、Geospatial、Hyperloglog、Bitmap、Bitfield类型的解析

开篇介绍:

hello 大家,在我们系统、完整、深度学完 Redis 五大基础核心数据类型(String、List、Hash、Set、ZSet) 之后,今天我们正式进入 Redis 的 五大特殊 / 高级数据结构 学习环节。

如果说基础 5 种类型是 Redis 的「骨架与血肉」,支撑了绝大多数缓存、计数、列表、集合、排序场景,那么今天要讲的 Bitmap(位图)、BitField(位域)、HyperLogLog(基数统计)、Geospatial(地理空间)、Stream(消息流) 就是 Redis 的「专属利刃与特种工具」------ 它们不通用、不万能,但在各自的垂直领域里,是性能、内存、效率的绝对天花板,没有任何其他数据结构可以替代。

在互联网高并发、大数据、精细化运营的今天,这 5 种类型的出场频率甚至远超基础类型:

  • 想要极致节省内存做海量状态标记 (签到、在线、黑名单、是否已读、推送触达、会员状态)→ 必须用 Bitmap;
  • 想要对位图做精细化、长位、批量、带符号、原子位操作 (多字段紧凑存储、小数值计数、分段状态管理)→ 必须用 BitField;
  • 想要超轻量、低内存、高性能统计海量不重复元素个数(日活 UV、周活 UV、独立设备、独立 IP、独立访客、独立用户) ,且能接受万分之几到 1% 以内的标准误差 → 必须用 HyperLogLog;
  • 想要零开发成本实现经纬度存储、两点距离计算、指定范围地理检索、附近的人 / 门店 / 车辆 / POI 查询、地理围栏判断 → 必须用 Geospatial;
  • 想要实现可靠、可回溯、可分组消费、可负载均衡、带消息确认、支持持久化、支持消息堆积、支持历史回溯的分布式消息队列 ,彻底替代 List 实现的简易不安全队列 → 必须用 Stream。

这 5 种结构有一个共同特点:全部基于 Redis 基础类型二次封装 / 底层复用,没有全新的底层存储结构,学习门槛低、记忆成本低、落地极快,但功能专一、性能极强、内存极省。Bitmap、BitField 底层完全复用 String 的二进制安全特性;HyperLogLog 底层是基于字符串的概率统计结构;Geospatial 底层 100% 复用 ZSet 的跳表 + 哈希表结构;只有 Stream 是 Redis 5.0 版本新增的专门流结构,但依旧兼容 Redis 所有持久化、集群、过期策略。

在正式开始之前,依旧重申我们学习 Redis 通用的小细节,这个细节在所有 Redis 操作中都通用,能让你在命令行中更直观地看到中文、特殊字符,而不是被转义为十六进制的乱码,影响学习和调试:如果需要在 redis-cli 中正常显示、输入中文,不出现十六进制转义,启动客户端时请携带 --raw 参数:

复制代码
redis-cli --raw

我们先一句话、一个维度、一个场景地精准定位每一种类型,让你在深入学习前,先彻底知道「它是谁、用来干嘛、为什么非它不可、和其他方案比优势在哪、什么场景绝对不能用」,建立全局认知,避免学习过程中迷失方向。

特殊类型 底层依赖结构 核心能力 内存占用特征 时间复杂度 核心适用场景 绝对不适用场景 核心优势
Bitmap 位图 String(二进制安全字节数组) 单 bit 存储二元状态(0/1),支持位设置、位读取、位统计、位运算 极致节省内存:1 亿状态仅需约 12MB,总字节数 = 最大位偏移 / 8 + 1 所有核心命令 O (1),统计命令 O (N) 用户签到、在线状态、已读未读、黑名单、白名单、推送触达标记、用户活跃标记 需要存储非 0/1 数据、需要存储原始内容、需要高精度非二元状态 内存利用率天花板、原子操作、高性能、兼容 String 所有特性
BitField 位域 String(与 Bitmap 完全兼容) 多段位操作、指定位宽(1-64 位)、有符号 / 无符号、原子批量操作、自定义溢出策略 与 Bitmap 一致,分段存储小数值,内存更紧凑 单命令多操作 O (1),原子执行 多状态紧凑存储、小数值计数、游戏道具数量、用户等级、分段状态管理 超大数值存储、需要动态扩展超长位宽、需要复杂数值运算 位图增强、原子批量、精细化控制、兼容原生 Bitmap
HyperLogLog 基数统计 字符串 + 概率统计算法 仅统计不重复元素个数(基数),支持多实例合并 固定 12KB 内存,无论统计 1 万还是 100 亿元素,内存永不增加 PFADD O(1),PFCOUNT O(N),PFMERGE O(N) 日活 UV、独立 IP、独立设备、独立访客、运营数据统计 金融计费、精准计数、需要查询单个元素是否存在、需要存储原始数据 固定极小内存、超高性能、支持合并、误差可控
Geospatial 地理空间 ZSet(跳表 + 哈希表) 经纬度编码、距离计算、范围检索、按距离排序 与 ZSet 一致,score 存储 GeoHash 编码值 所有命令复用 ZSet 复杂度,范围查询 O (logN+M) 附近的人、附近门店、网约车、外卖、物流、地理围栏、POI 检索 高精度地理测绘、海量地理数据复杂分析、需要复杂地理运算 零开发成本、复用 ZSet 高性能、开箱即用、支持排序和范围
Stream 消息流 Redis 5.0+ 专属流结构 + 链表 + 消息节点 可靠消息队列、消费组、负载均衡、消息 ACK、历史回溯、持久化、消息堆积 随消息量线性增长,可通过截取控制内存 XADD O(1),XREADGROUP O(logN+M),XACK O(1) 订单消息、日志采集、用户行为上报、异步通知、分布式任务、微服务通信 超大规模消息队列(对标 Kafka)、需要复杂事务消息、需要消息路由过滤 官方原生、可靠不丢、消费组隔离、ACK 确认、历史可回溯、轻量高性能
  1. Bitmap(位图,最基础、最常用、生产覆盖率 100%)
  2. BitField(位域,Bitmap 专业增强版,精细化位操作)
  3. HyperLogLog(基数统计,海量去重计数神器,固定内存)
  4. Geospatial(地理空间,LBS 场景一站式解决方案,基于 ZSet)
  5. Stream(消息流,Redis 官方唯一可靠分布式消息队列,替代 List)

第一章:Redis Bitmap 位图 ------ 极致省内存的二进制状态标记神器

1.1 开篇引入:传统状态存储的致命痛点与 Bitmap 的诞生

在互联网后端开发、移动端服务、大数据运营、用户体系建设中,我们每天都会面对海量二元状态标记的需求,所谓「二元状态」,就是只有两种可能的状态:是 / 否、有 / 无、开 / 关、已 / 未、在 / 不在。

举几个最常见、最核心、几乎所有业务都会遇到的场景:

  • 用户今日是否完成签到?是 → 1,否 → 0;
  • 用户当前是否在线?在线 → 1,离线 → 0;
  • 某条消息是否已读?已读 → 1,未读 → 0;
  • 用户是否在黑名单 / 白名单中?在 → 1,不在 → 0;
  • 用户今日是否访问过 APP / 小程序?访问 → 1,未访问 → 0;
  • 某条推送是否已经触达用户?触达 → 1,未触达 → 0;
  • 用户是否开通会员 / 特权?开通 → 1,未开通 → 0。

如果我们用传统 String 类型 存储这类状态,会出现无法解决的痛点:假设我们有 1 亿用户,每个用户用一个独立 Key 存储状态,例如 user:sign:20260208:100000000 = 1,仅仅存储 1 亿个二元状态,就需要创建 1 亿个 Key,不仅 Redis 内存会瞬间爆炸、Key 数量超限、查询效率极低,而且无法批量统计、无法批量合并、无法做跨天 / 跨维度的状态运算,完全无法满足生产需求。

如果我们用Set 类型 存储这类状态,例如把所有签到成功的用户 ID 塞进 Set,虽然能去重、能统计总数,但无法快速判断单个用户的状态(需要 SISMEMBER,性能低于 Bitmap)、无法批量做位运算(如连续签到)、内存占用依旧远高于 Bitmap、无法按偏移快速定位,只能满足基础的去重和统计,无法满足精细化状态管理。

在这样的背景下,Redis 基于 String 二进制安全的特性,推出了 Bitmap 位图 功能,它彻底解决了传统存储的所有痛点,用最小的内存、最快的速度、最简单的命令、最强大的运算能力,支撑海量二元状态的存储、查询、统计、合并。

Bitmap 的核心设计理念只有一句话:用 1 个二进制位(bit)存储 1 个二元状态,8 个状态占用 1 个字节,内存利用率达到理论上限。

1.2 Bitmap 核心基础认知

1.2.1 什么是 Redis Bitmap?

Bitmap 不是 Redis 独立的数据类型 ,很多初学者会误以为 Bitmap 是和 String、List 并列的新类型,这是完全错误的。Bitmap 是基于 String 类型的二进制位操作扩展功能 ,它利用 String 是「二进制安全的字节数组」这一核心特性,把字符串底层的连续字节,当成一整串连续、可寻址、可修改、可统计的二进制位(bit)数组来使用。

简单直白地说:Bitmap = 一长串连续的 0 和 1,每一位对应一个二元状态,通过数字偏移量(下标)定位每一位,偏移量从 0 开始,支持无限大(理论上限 2^32 位)。

你可以把 Bitmap 想象成一个超长的开关面板,每一个开关对应一个用户 / 一个状态,开关打开是 1,关闭是 0,通过开关的编号(偏移量)快速找到并控制开关,整个面板只占用极小的空间。

1.2.2 Bitmap 三大不可违背的核心铁律

  1. 位偏移量(下标)从 0 开始,支持极大偏移量偏移量可以是 0、1、100、10000、1 亿、10 亿,Redis 会自动扩展底层 String 的长度,不会报错,理论最大支持 2^32 位(约 512MB 长度),完全满足所有互联网业务的需求。

  2. 每一位的取值只能是 0 或 1,无其他可能无论你设置什么数字,Redis 只会识别 0 和 1,设置 2、3、100 会被强制转为 1,设置负数会直接报错,这是 Bitmap 只存储二元状态的核心保证。

  3. 未被设置过的位,默认值永远是 0,且不占用实际物理内存 这是 Redis 对 Bitmap 的稀疏优化,如果你只设置了偏移量 1 亿的位为 1,中间 0~99999999 的位都未设置,这些位默认是 0,但不会占用实际内存,只有被设置过的位才会占用内存,极大节省空间。

1.2.3 Bitmap 内存精确计算公式

Bitmap 的内存占用完全由最大的位偏移量决定,和设置了多少个 1 无关,计算公式是行业通用标准,简单易记:

  1. 总字节数 = 最大位偏移量 / 8 + 1(+1 是因为偏移量从 0 开始);
  2. 总千字节 KB = 总字节数 / 1024;
  3. 总兆字节 MB = 总字节数 / 1024 / 1024。

我们用实际业务场景举例,直观感受 Bitmap 的内存优势:

  • 场景 1:标记 1 万用户(最大偏移量 9999)→ 9999/8+1 = 1250 字节 ≈ 1.22KB;
  • 场景 2:标记 100 万用户(最大偏移量 999999)→ 999999/8+1 ≈ 125000 字节 ≈ 122KB;
  • 场景 3:标记 1 亿用户(最大偏移量 99999999)→ 99999999/8+1 ≈ 12500000 字节 ≈ 11.92MB ≈ 12MB;
  • 场景 4:标记 10 亿用户(最大偏移量 999999999)→ 约 119MB。

对比传统 String:10 亿用户用 String 存储需要上百 GB 内存,Bitmap 仅需 119MB,内存差距接近 10000 倍,这就是 Bitmap 成为生产必备的核心原因。

1.2.4 Bitmap 核心特性全表(零基础一眼看懂)

特性维度 具体说明 生产价值
底层依赖 普通 String 类型,二进制安全 复用 String 的过期、持久化、集群、主从、备份所有特性
存储单位 二进制位(bit),1 字节 = 8 位 内存利用率达到理论最大值,无任何浪费
取值范围 仅支持 0(关闭 / 否 / 未)和 1(开启 / 是 / 已) 专门适配二元状态,无冗余功能
偏移量规则 从 0 开始递增,支持超大整数,无上限(理论 2^32) 可标记任意长度的 ID、编号、序列
默认值 未设置的位永久为 0,稀疏存储不占内存 无需提前初始化,随用随设,节省内存
原子性 所有位操作命令都是原子执行 高并发场景下无竞争、无数据错乱、无需加锁
时间复杂度 SETBIT/GETBIT O(1);BITCOUNT O(N);BITOP O(N) 单 bit 操作极致性能,统计 / 运算满足批量需求
兼容性 可直接使用 String 所有命令(EXPIRE、DEL、APPEND 等) 学习成本低,无缝接入现有 Redis 体系

1.3 Bitmap 核心命令全解

Bitmap 的功能专一,因此命令数量极少,一共只有 4 个核心命令,全部掌握不超过 10 分钟,但能覆盖 100% 的生产场景、面试场景、测试场景。这 4 个命令分别是:

  1. SETBIT:设置指定偏移量位的值(0/1),写入核心命令;
  2. GETBIT:获取指定偏移量位的值(0/1),读取核心命令;
  3. BITCOUNT:统计指定范围内值为 1 的位的总个数,统计核心命令;
  4. BITOP:对多个 Bitmap 执行位运算(与、或、异或、非),合并核心命令。

我们对每个命令进行极致细化讲解,包含:命令作用(人话翻译)、完整语法、支持版本、时间复杂度、返回值含义、所有参数详解、逐行实操示例、常见误区、生产实战场景,无任何省略、无任何跳步。

1.3.1 SETBIT:设置指定位的值(Bitmap 写入核心,最常用)

命令作用

找到 Bitmap 中指定偏移量的那一位,把它设置为 0 或 1;如果对应的 Key 不存在,Redis 会自动创建一个空的 String 并扩展到对应偏移量长度;命令返回该位被修改之前的值。

完整语法
复制代码
SETBIT key offset value
  • key:Bitmap 的 Key 名称(本质是 String Key);
  • offset:位偏移量(下标),必须是 ≥ 0 的整数;
  • value:要设置的值,只能是 0 或 1。
支持版本

Redis 2.2.0 及以上版本(所有稳定版本都支持,无兼容性问题)

时间复杂度

O (1):无论偏移量多大,只修改单个位,内存按需扩展,性能极致。

返回值含义
  • 整数 0:该位修改之前的值是 0;
  • 整数 1:该位修改之前的值是 1。
逐行实操示例
复制代码
# 示例 1:创建 Key 为 bitmap:user:sign:20260208,设置偏移量 1001(用户ID 1001)的位为 1
# 执行逻辑:Key 不存在→自动创建,偏移量 1001 未设置→原值 0,设置为 1,返回 0
127.0.0.1:6379> SETBIT bitmap:user:sign:20260208 1001 1
(integer) 0

# 示例 2:再次设置偏移量 1001 为 1,原值已经是 1,返回 1
127.0.0.1:6379> SETBIT bitmap:user:sign:20260208 1001 1
(integer) 1

# 示例 3:设置偏移量 1002 为 0,原值 0,返回 0
127.0.0.1:6379> SETBIT bitmap:user:sign:20260208 1002 0
(integer) 0

# 示例 4:设置超大偏移量 100000000(1亿)为 1,自动扩展内存,返回 0
127.0.0.1:6379> SETBIT bitmap:user:sign:20260208 100000000 1
(integer) 0
常见误区
  1. 偏移量可以设置为极大值(如 1 亿),但不要无意义地跳跃超大偏移量(例如先设 0,再设 1 亿),会瞬间占用大量内存,导致 Redis 性能波动;
  2. value 只能是 0 或 1,输入 2、3、10 会被强制转为 1,输入负数、小数会直接报错;
  3. SETBIT 是原子操作,高并发下多个客户端同时设置同一位,不会出现数据错乱;
  4. 设置偏移量后,底层 String 长度会自动扩展,未设置的位默认 0,不占用物理内存。
生产实战场景(全覆盖)
  • 用户每日签到:SETBIT user:sign:{yyyyMMdd} {uid} 1;
  • 用户上线标记:SETBIT user:online {uid} 1;
  • 用户下线标记:SETBIT user:online {uid} 0;
  • 消息已读标记:SETBIT msg:read:{uid} {msgId} 1;
  • 黑名单标记:SETBIT user:blacklist {uid} 1;
  • 今日访问标记:SETBIT user:visit:{yyyyMMdd} {uid} 1。

1.3.2 GETBIT:获取指定位的值(Bitmap 读取核心,最常用)

命令作用

读取 Bitmap 中指定偏移量位的当前值;如果 Key 不存在,或者偏移量超出当前 Bitmap 长度,一律返回 0,不会报错。

完整语法
复制代码
GETBIT key offset
  • key:Bitmap Key;
  • offset:位偏移量(≥0)。
支持版本

Redis 2.2.0 及以上

时间复杂度

O (1):直接定位到位,无任何遍历,性能极致。

返回值含义
  • 整数 0:位未设置 / Key 不存在 / 偏移量越界;
  • 整数 1:位已设置为 1。
逐行实操示例
复制代码
# 示例 1:读取用户 1001 的签到状态,返回 1(已签到)
127.0.0.1:6379> GETBIT bitmap:user:sign:20260208 1001
(integer) 1

# 示例 2:读取用户 1002 的签到状态,返回 0(未签到)
127.0.0.1:6379> GETBIT bitmap:user:sign:20260208 1002
(integer) 0

# 示例 3:读取不存在的用户 9999,返回 0
127.0.0.1:6379> GETBIT bitmap:user:sign:20260208 9999
(integer) 0

# 示例 4:读取不存在的 Key,返回 0
127.0.0.1:6379> GETBIT bitmap:not:exist 1001
(integer) 0
生产实战场景
  • 判断用户是否签到:GETBIT user:sign:{yyyyMMdd} {uid};
  • 判断用户是否在线:GETBIT user:online {uid};
  • 判断消息是否已读:GETBIT msg:read:{uid} {msgId};
  • 判断用户是否在黑名单:GETBIT user:blacklist {uid}。

1.3.3 BITCOUNT:统计范围内 1 的个数(Bitmap 统计核心,运营必备)

命令作用

统计 Bitmap 中指定范围内值为 1 的位的总数量 ;默认统计整个 Bitmap 所有位 ;支持指定起始和结束位置,Redis 7.0 以下版本默认按字节下标 统计,Redis 7.0 及以上支持按位下标统计。

完整语法
复制代码
BITCOUNT key [start end] [BYTE | BIT]
  • key:Bitmap Key;
  • start end:范围下标,默认是字节下标(Redis 7.0-),支持负数(-1 最后一个字节);
  • BYTE | BIT:Redis 7.0+ 新增,指定按字节 / 按位统计,解决新手字节 / 位混淆问题。
支持版本

Redis 2.6.0 及以上

时间复杂度

O (N):N 是统计范围内的字节数,实际执行速度极快,满足批量统计需求。

返回值含义

整数:范围内值为 1 的位的总个数。

关键注意(90% 新手必踩坑,重中之重)

Redis 7.0 以下版本,start 和 end 是「字节下标」,不是「位下标」 !例如:你想统计 0~100 位的 1 的个数,不能直接写 BITCOUNT key 0 100,这会统计 0~100 字节(800 位),Redis 7.0+ 可以用 BIT 参数精准按位统计。

逐行实操示例
复制代码
# 示例 1:统计今日所有签到用户总数(全量统计),返回 2
127.0.0.1:6379> BITCOUNT bitmap:user:sign:20260208
(integer) 2

# 示例 2:统计 0~0 字节内的 1 的个数,返回 2
127.0.0.1:6379> BITCOUNT bitmap:user:sign:20260208 0 0
(integer) 2

# 示例 3:Redis 7.0+ 按位统计 0~2000 位的 1 的个数
127.0.0.1:6379> BITCOUNT bitmap:user:sign:20260208 0 2000 BIT
(integer) 2
生产实战场景
  • 统计当日签到总人数:BITCOUNT user:sign:{yyyyMMdd};
  • 统计当前在线总人数:BITCOUNT user:online;
  • 统计已读消息总数:BITCOUNT msg:read:{uid};
  • 统计黑名单总人数:BITCOUNT user:blacklist。

1.3.4 BITOP:多位图位运算(Bitmap 合并核心,跨维度统计必备)

命令作用(人话翻译)

对多个 Bitmap 执行逻辑与(AND)、逻辑或(OR)、逻辑异或(XOR)、逻辑非(NOT) 运算,运算结果保存到一个新的 Bitmap Key 中;用于实现多维度状态合并、跨天统计、交集 / 并集计算。

完整语法
复制代码
BITOP operation destkey key [key ...]
  • operation:运算类型,AND(与)、OR(或)、XOR(异或)、NOT(非);
  • destkey:保存运算结果的目标 Key;
  • key [key ...]:参与运算的源 Bitmap Key(NOT 仅支持 1 个源 Key)。
支持版本

Redis 2.6.0 及以上

时间复杂度

O (N):N 是最长 Bitmap 的长度,批量运算性能优秀。

运算逻辑通俗解释
  • AND(与):只有所有源位图对应位都是 1,结果位才是 1 → 求共同状态(连续签到);
  • OR(或):任意一个源位图对应位是 1,结果位就是 1 → 求全部状态(累计签到);
  • XOR(异或):源位图对应位不同,结果位是 1 → 求差异状态;
  • NOT(非):对单个位图取反,0 变 1,1 变 0 → 求反向状态(未签到用户)。
逐行实操示例(连续 3 天签到用户统计,最经典场景)
复制代码
# 第 1 步:2026-02-06 签到用户
SETBIT user:sign:20260206 1001 1
SETBIT user:sign:20260206 1002 1

# 第 2 步:2026-02-07 签到用户
SETBIT user:sign:20260207 1001 1
SETBIT user:sign:20260207 1003 1

# 第 3 步:2026-02-08 签到用户
SETBIT user:sign:20260208 1001 1
SETBIT user:sign:20260208 1004 1

# 第 4 步:AND 运算(3 天都签到的用户,只有 1001),结果保存到 user:sign:3day
BITOP AND user:sign:3day user:sign:20260206 user:sign:20260207 user:sign:20260208

# 第 5 步:统计连续 3 天签到人数,返回 1
BITCOUNT user:sign:3day
生产实战场景
  • 连续 N 天签到用户统计:BITOP AND;
  • 累计 N 天签到用户统计:BITOP OR;
  • 在线且活跃用户统计:BITOP AND;
  • 不在黑名单的白名单用户:BITOP NOT + AND。

1.4 Bitmap 内部存储结构

Bitmap 底层就是普通的 String 字节数组,Redis 把每 8 个连续的 bit 合并为 1 个字节存储,偏移量 0~7 对应第一个字节,8~15 对应第二个字节,以此类推。

  • 稀疏 Bitmap(大量 0):只有被设置为 1 的位会占用实际物理内存,未设置的位只存在逻辑上,不占内存;
  • 密集 Bitmap(大量 1):内存占用等于最大偏移量对应的字节数;
  • 完全兼容 String 命令:可以用 EXPIRE 设置过期时间、DEL 删除、DUMP/RESTORE 备份恢复、TYPE key 查看类型会返回 string。

1.5 Bitmap 生产实战全场景

场景 1:用户每日签到系统(最经典、全行业通用)

需求
  1. 记录每个用户每日是否签到;
  2. 快速判断单个用户当日是否签到;
  3. 统计当日总签到人数;
  4. 统计连续 3/7/30 天签到用户;
  5. 统计累计签到用户。
Key 设计规范(生产通用)

user:sign:{yyyyMMdd}:按日期存储每日签到位图,按天拆分避免大 Key。

完整命令落地
复制代码
# 1. 用户 1001 今日签到
SETBIT user:sign:20260208 1001 1

# 2. 判断用户 1001 是否签到
GETBIT user:sign:20260208 1001

# 3. 当日签到总人数
BITCOUNT user:sign:20260208

# 4. 连续 7 天签到用户合并
BITOP AND user:sign:7day user:sign:20260202 user:sign:20260203 user:sign:20260204 user:sign:20260205 user:sign:20260206 user:sign:20260207 user:sign:20260208

# 5. 连续 7 天签到人数
BITCOUNT user:sign:7day

# 6. 累计 7 天签到用户
BITOP OR user:sign:total7day user:sign:20260202 user:sign:20260203 user:sign:20260204 user:sign:20260205 user:sign:20260206 user:sign:20260207 user:sign:20260208

场景 2:亿级用户在线状态实时统计

Key 设计

user:online:全局在线状态位图。

命令落地
复制代码
# 用户上线
SETBIT user:online 1001 1

# 用户下线
SETBIT user:online 1001 0

# 判断是否在线
GETBIT user:online 1001

# 实时在线总人数
BITCOUNT user:online

场景 3:消息已读 / 未读标记系统

Key 设计

msg:read:{uid}:每个用户的消息已读位图。

命令落地
复制代码
# 用户 1001 已读消息 5253
SETBIT msg:read:1001 5253 1

# 判断消息 5253 是否已读
GETBIT msg:read:1001 5253

# 已读消息总数
BITCOUNT msg:read:1001

场景 4:全局黑名单 / 白名单系统

Key 设计

user:blacklist、user:whitelist。

命令落地
复制代码
# 加入黑名单
SETBIT user:blacklist 1001 1

# 判断是否在黑名单
GETBIT user:blacklist 1001

# 黑名单总人数
BITCOUNT user:blacklist

1.6 Bitmap 生产避坑指南

  1. 超大偏移量瞬间扩展内存:避免无意义设置超大偏移量,防止 Redis 瞬间内存暴涨、主线程阻塞;
  2. 字节下标与位下标混淆:Redis 7.0 以下 BITCOUNT 默认按字节统计,务必注意范围;
  3. Bitmap 最大长度限制:理论最大 2^32 位(512MB),超过会直接报错;
  4. NOT 运算仅支持单个源 Key:多 Key 执行 NOT 会报错,只能单 Key 取反;
  5. 高并发下无需加锁:SETBIT/GETBIT 都是原子操作,多线程无竞争;
  6. 禁止用 Bitmap 存储非 0/1 数据:违背设计初衷,浪费内存且无意义;
  7. 大 Key 拆分:单日签到用户超 1 亿,可按用户 ID 范围拆分为多个位图(如 user:sign:20260208:1、user:sign:20260208:2);
  8. 过期策略:历史签到位图设置过期时间(如 EXPIRE user:sign:20260208 2592000),释放内存;
  9. 集群环境 HashTag:BITOP 涉及多个 Key,需用 {hash_tag} 保证所有 Key 在同一 Slot;
  10. 稀疏位图与密集位图切换:大量设置 1 后,位图变密集,内存固定占用,需定期清理;
  11. BITCOUNT 性能:全量统计超大位图时,耗时略高,可异步统计或分范围统计;
  12. 偏移量从 0 开始:用户 ID 从 1 开始时,可直接用 ID 作为偏移量,无需减 1;
  13. Key 命名规范:必须按业务 + 功能 + 维度命名,避免 Key 冲突;
  14. 监控内存:超大位图需监控内存占用,防止超出 Redis 最大内存限制;
  15. 持久化影响:密集位图会增大 RDB/AOF 文件,影响持久化速度,需合理评估。

1.7 Bitmap 与其他方案详细对比

存储方案 内存占用 单状态查询 批量统计 多维度合并 适用规模 学习成本
String 单 Key 极高(线性增长) O(1) O(N) 无法实现 万级用户 极低
Set 集合 中(存原始 ID) O(1)(SISMEMBER) O(1)(SCARD) 支持(SINTER/SUNION) 百万级用户 低
Bitmap 位图 极低(固定由最大偏移决定) O(1) O (N)(极快) 支持(BITOP) 亿级 + 用户 低

1.8 Bitmap 最佳实践

  1. 按时间 / ID 范围拆分大 Key,避免单 Key 超过 100MB;
  2. 优先使用 Redis 7.0+,享受 BIT 参数精准按位统计;
  3. 历史数据设置过期策略,自动释放内存;
  4. 集群环境用 HashTag 保证 BITOP 多 Key 同 Slot;
  5. 高并发统计异步执行,不阻塞主线程;
  6. 稀疏位图优先,避免无意义密集设置;
  7. 偏移量直接使用业务 ID(用户 ID、消息 ID),无需映射。

第二章:Redis BitField 位域 ------ Bitmap 的精细化、长位、原子增强工具

2.1 开篇:原生 Bitmap 的功能局限与 BitField 的诞生

原生 Bitmap 只能操作单个 1 位 ,只能存储 0/1 二元状态,在实际生产中,我们会遇到大量需要用多个位存储小数值、需要分段存储多个状态、需要原子批量操作、需要带符号数值、需要控制数值溢出的场景,原生 Bitmap 完全无法满足:

  • 场景 1:用 4 位存储用户等级(0~15),8 位存储用户积分(0~255),1 位存储 VIP 状态,紧凑存储节省内存;
  • 场景 2:对小数值进行原子自增 / 自减,避免客户端 GET+SET 的非原子问题;
  • 场景 3:控制数值溢出,自增超出范围时不循环、不报错、直接截断;
  • 场景 4:批量操作多个位段,一次命令完成多个状态修改,保证原子性。

为了解决这些问题,Redis 在 3.2 版本推出了 BitField 位域 命令,它完全兼容原生 Bitmap ,底层依旧复用 String 二进制安全特性,是 Bitmap 的专业级增强工具。

BitField 的核心设计理念:把一整个位图,划分成多个独立、连续、自定义位宽的「位段」,每个位段可以存储有符号 / 无符号小数值,支持原子批量读取、设置、自增,支持自定义溢出策略。

2.2 BitField 核心基础认知

2.2.1 什么是 Redis BitField?

BitField 不是独立数据类型,是一条原子批量位域操作命令,允许开发者在一个 String(位图)中,定义多个独立的位段,每个位段包含:

  1. 位宽:1~64 位(u 无符号、i 有符号);
  2. 偏移量:绝对位偏移 / 按段对齐偏移;
  3. 操作类型:GET(读取)、SET(设置)、INCRBY(自增 / 自减);
  4. 溢出策略:WRAP(循环)、SAT(截断)、FAIL(失败)。

2.2.2 BitField 核心特性

  1. 完全兼容 Bitmap:和 SETBIT/GETBIT 共用同一个位图,可互相操作;
  2. 原子批量操作:一条命令执行多个位段操作,全部原子执行,无中间状态;
  3. 位宽自定义:1~64 位,支持无符号(uN)和有符号(iN)数值;
  4. 溢出可控:三种溢出策略,满足不同业务需求;
  5. 两种偏移方式:绝对位偏移、按段对齐偏移(#0、#1);
  6. 时间复杂度 O (1):所有操作都是直接定位,无遍历,性能极致。

2.2.3 位宽与数值范围

  • 无符号 uN:范围 0 ~ 2^N - 1(u4 → 0~15,u8 → 0~255,u16 → 0~65535);
  • 有符号 iN:范围 -2^(N-1) ~ 2^(N-1) - 1(i4 → -8~7,i8 → -128~127)。

2.2.4 三种溢出策略

  1. WRAP(默认,循环环绕):数值溢出后从头开始循环(u8 255+1=0);
  2. SAT(饱和截断):数值溢出后保持最大值 / 最小值,不再变化(u8 255+1=255);
  3. FAIL(失败拒绝):数值溢出后放弃操作,返回 nil,不修改任何数据。

2.3 BitField 唯一核心命令:BITFIELD

BitField 只有一条核心命令,但支持批量子操作,功能极强,是专业位操作的唯一选择。

2.3.1 命令作用

在一个位图中,原子执行多个位段操作(读取、设置、自增),支持指定位宽、偏移、溢出策略,所有操作要么全部成功,要么全部不执行,保证原子性。

2.3.2 完整语法

复制代码
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
  • key:位图 Key(与 Bitmap 共用);
  • GET type offset:读取指定位段的值;
  • SET type offset value:设置指定位段的值;
  • INCRBY type offset increment:位段值自增 / 自减;
  • OVERFLOW:设置溢出策略,作用于后续所有 INCRBY;
  • type:uN(无符号 N 位)/iN(有符号 N 位),N=1~64;
  • offset:偏移量(数字 = 绝对偏移,#0 = 第 0 段对齐偏移)。

2.3.3 支持版本

Redis 3.2.0 及以上

2.3.4 时间复杂度

O (1):单命令多操作,原子执行,性能极致。

2.3.5 逐行实操示例

复制代码
# 示例 1:设置 u4(无符号4位,0~15)偏移量 0,值为 5 → 返回旧值 0
127.0.0.1:6379> BITFIELD bf:demo SET u4 0 5
1) (integer) 0

# 示例 2:读取 u4 偏移量 0 的值 → 返回 5
127.0.0.1:6379> BITFIELD bf:demo GET u4 0
1) (integer) 5

# 示例 3:自增 +2 → 5+2=7,返回 7
127.0.0.1:6379> BITFIELD bf:demo INCRBY u4 0 2
1) (integer) 7

# 示例 4:设置溢出策略为 SAT(饱和),u3(0~7)自增 1 → 7+1=8 溢出,保持 7
127.0.0.1:6379> BITFIELD bf:demo OVERFLOW SAT INCRBY u3 0 1
1) (integer) 7

# 示例 5:批量操作:读取+设置+自增,原子执行
127.0.0.1:6379> BITFIELD bf:demo GET u4 0 SET u8 4 100 INCRBY u16 20 50
1) (integer) 7
2) (integer) 0
3) (integer) 50

2.4 BitField 生产实战全场景

场景 1:用户多状态紧凑存储(等级 + 积分 + VIP)

位段划分
  • 偏移 0~3(u4):用户等级(0~15);
  • 偏移 4~11(u8):用户积分(0~255);
  • 偏移 12(u1):VIP 状态(0/1)。
命令落地
复制代码
# 批量设置:等级 10、积分 100、VIP 1
BITFIELD user:data:1001 SET u4 0 10 SET u8 4 100 SET u1 12 1

# 批量读取
BITFIELD user:data:1001 GET u4 0 GET u8 4 GET u1 12

场景 2:视频播放量精准小数值计数

复制代码
# u20 最大支持 1048575,满足普通视频播放量
BITFIELD video:play:5253 INCRBY u20 0 1

场景 3:游戏道具数量存储(多道具分段)

复制代码
# 道具1:u8 偏移0,道具2:u8 偏移8,道具3:u8 偏移16
BITFIELD game:item:1001 SET u8 0 5 SET u8 8 10 SET u8 16 1

2.5 BitField 避坑指南

  1. 位宽最大支持 64 位,超过 64 位直接报错;
  2. 有符号数最高位是符号位,数值范围更小,避免溢出;
  3. OVERFLOW FAIL 溢出时返回 nil,业务需判断结果;
  4. 偏移量冲突会覆盖其他位段数据,需严格规划位段划分;
  5. 与 Bitmap 共用时,避免 SETBIT 覆盖 BitField 位段;
  6. 批量操作中子命令顺序不影响结果,全部原子执行;
  7. 按段对齐偏移(#0)仅适用于同位宽的连续位段;
  8. INCRBY 支持负数(自减),实现数值减少;
  9. Redis 3.2 以下版本不支持 BitField,需升级版本;
  10. 超大位宽(64 位)需注意浮点数精度问题,无超纲。

2.6 BitField 最佳实践

  1. 提前规划位段划分,标注偏移量、位宽、用途,避免冲突;
  2. 优先使用无符号位宽(uN),满足绝大多数正数计数场景;
  3. 计数场景使用 SAT 溢出策略,避免数值循环错乱;
  4. 批量操作合并多次请求,减少网络 IO,提升性能;
  5. 与 Bitmap 混合使用时,位段偏移量从高位开始,避免冲突。

第三章:Redis HyperLogLog ------ 超轻量级海量基数统计神器

3.1 开篇:基数统计的行业痛点与 HyperLogLog 诞生

基数(Cardinality) 指一个集合中不重复元素的个数,是互联网运营、大数据统计最核心的指标:

  • 日活 UV(Daily Unique User):一天内独立访问用户数;
  • 独立 IP 数:一天内独立访问 IP 个数;
  • 独立设备数:独立手机 / PC 设备数;
  • 独立访客数:网页 / 小程序独立访客数;
  • 独立用户数:接口调用独立用户数。

传统精准统计方案:

  • Set:100% 精准,但内存随元素量线性增长,1 亿 UV 需上 GB 内存,无法支撑海量数据;
  • Bitmap:100% 精准,但需要元素 ID 连续,内存固定,但无法处理无序、非连续 ID;
  • 数据库:性能极差,无法支撑高并发、实时统计。

在允许极小误差(<1%) 的前提下,Redis 推出了 HyperLogLog(简称 HLL) ,这是基于概率统计算法 的基数统计结构,无论统计 1 万、1 亿、100 亿元素,内存永远固定 12KB,误差控制在 0.81% 以内,完全满足所有运营统计场景。

3.2 HyperLogLog 核心基础认知

3.2.1 什么是 Redis HyperLogLog?

HyperLogLog 是 Redis 提供的概率型基数统计工具 ,不存储原始元素,只存储极小的概率统计特征值,通过这些特征值估算不重复元素个数,内存固定 12KB,支持多实例合并,性能极致。

3.2.2 HyperLogLog 三大铁律

  1. 只统计基数,不存储任何原始元素:无法查询单个元素是否存在,只能查总数;
  2. 内存永远固定 12KB:与统计元素数量无关,1 万和 100 亿占用内存完全相同;
  3. 标准误差 0.81%:满足所有运营、非金融、非精准计费场景。

3.2.3 适用 / 不适用场景

绝对适用:日活 UV、周活 UV、月活 UV、独立 IP、独立设备、运营数据统计、非精准计数;

绝对不适用:金融计费、精准对账、需要查询单个元素、需要 100% 准确计数。

3.3 HyperLogLog 3 大核心命令

HyperLogLog 只有 3 个核心命令,学习成本极低,生产全覆盖:

  1. PFADD:添加元素,自动去重;
  2. PFCOUNT:统计基数(估算值);
  3. PFMERGE:合并多个 HLL,求并集基数。

3.3.1 PFADD:添加元素(写入核心)

语法
复制代码
PFADD key element [element ...]
作用

添加一个 / 多个元素到 HLL,自动去重,返回 1 = 基数估算变化,0 = 无变化。

3.3.2 PFCOUNT:统计基数(读取核心)

语法
复制代码
PFCOUNT key [key ...]
作用

返回 HLL 的基数估算值,支持多 Key 合并统计(无需 PFMERGE)。

3.3.3 PFMERGE:合并多个 HLL(合并核心)

语法
复制代码
PFMERGE destkey sourcekey [sourcekey ...]
作用

合并多个源 HLL 到目标 HLL,结果为并集基数,用于多天 / 多维度合并。

3.4 实操示例

复制代码
# 示例 1:批量添加 4 个用户 ID,其中 1001 重复
PFADD uv:20260208 1001 1002 1003 1001

# 示例 2:统计 UV,返回 3(去重后)
PFCOUNT uv:20260208

# 示例 3:添加 2026-02-07 UV
PFADD uv:20260207 1001 1004 1005

# 示例 4:合并 2 天 UV 到 uv:202602
PFMERGE uv:202602 uv:20260207 uv:20260208

# 示例 5:统计 2 天总 UV,返回 5
PFCOUNT uv:202602

3.5 HyperLogLog 生产实战全场景

场景 1:亿级日活 UV 实时统计

复制代码
# 用户访问时添加 ID
PFADD uv:20260208 {uid}

# 实时统计 UV
PFCOUNT uv:20260208

场景 2:独立 IP 统计

复制代码
PFADD ip:20260208 192.168.1.1 192.168.1.2 192.168.1.1
PFCOUNT ip:20260208

场景 3:月度 UV 合并统计

复制代码
PFMERGE uv:202602 uv:20260201 uv:20260202 ... uv:20260228
PFCOUNT uv:202602

3.6 HyperLogLog 避坑指南

  1. 不存储原始元素:无法用 SISMEMBER/GETBIT 判断元素是否存在;
  2. 误差 0.81%:金融、计费、精准统计场景绝对禁用;
  3. 内存固定 12KB:不要创建大量无用 HLL,避免内存浪费;
  4. PFCOUNT 耗时略高:不要频繁调用,建议异步 / 定时统计;
  5. 不支持删除单个元素:只能删除整个 Key;
  6. 多 Key 合并需同集群 Slot:用 HashTag 保证;
  7. 重复添加元素无影响:自动去重,不改变基数;
  8. 空 HLL 统计返回 0;
  9. 与 Set/Bitmap 不可互相转换;
  10. 持久化:HLL 会被持久化,重启后数据不丢失。

3.7 HyperLogLog 最佳实践

  1. 按时间拆分 Key(日 / 周 / 月),便于合并统计;
  2. PFCOUNT 结果前端展示时标注「统计值,误差 < 1%」;
  3. 定时删除历史 HLL Key,释放内存;
  4. 高并发场景异步统计,不阻塞主线程;
  5. 与 Bitmap 互补:Bitmap 做精准状态,HLL 做海量基数统计。

第四章:Redis Geospatial 地理空间 ------ LBS 场景一站式解决方案(基于 ZSet)

4.1 开篇:LBS 场景开发痛点与 Geospatial 诞生

LBS(基于位置的服务)是移动互联网核心场景:

  • 外卖:附近 3km 商家;
  • 网约车:附近 5km 车辆;
  • 社交:附近的人;
  • 地图:附近 POI、门店、站点;
  • 物流:距离计算、路线规划。

传统开发方案:

  • MySQL 空间索引:性能差、不支持高并发、开发复杂;
  • 自研 GeoHash 编码:开发成本高、调试复杂、精度难控制;
  • 专业 GIS 系统:成本极高、部署复杂、不适合轻量场景。

Redis Geospatial(GEO)基于 ZSet 实现 ,把经纬度编码为 52 位 GeoHash 值作为 ZSet 的 score,直接复用 ZSet 的排序、范围查询、高性能特性,零开发成本、开箱即用、高性能、支持所有 LBS 核心需求。

4.2 Geospatial 核心基础认知

4.2.1 什么是 Redis GEO?

GEO 不是独立数据类型,是基于 ZSet 的地理空间操作扩展:

  • member:地理元素名称(用户 ID、门店 ID、车辆 ID);
  • score:经纬度 GeoHash 编码值(52 位整数);
  • 所有 GEO 命令最终都会转换为 ZSet 命令执行。

4.2.2 GEO 核心能力

  1. 存储经纬度坐标;
  2. 计算两点之间距离;
  3. 指定中心坐标范围检索(附近元素);
  4. 指定元素中心范围检索;
  5. 按距离排序、限制返回数量。

4.2.3 距离单位

  • m:米(默认);
  • km:千米;
  • mi:英里;
  • ft:英尺。

4.3 GEO 核心命令全解(5 大核心命令)

4.3.1 GEOADD:添加经纬度坐标

复制代码
GEOADD key longitude latitude member [lon lat member ...]

示例:

复制代码
GEOADD shop:geo 116.481028 39.922982 "shop1" 116.465318 39.942577 "shop2"

4.3.2 GEOPOS:获取元素经纬度

复制代码
GEOPOS key member [member ...]

4.3.3 GEODIST:计算两点距离

复制代码
GEODIST key member1 member2 [unit]

示例:

复制代码
GEODIST shop:geo shop1 shop2 km

4.3.4 GEORADIUS:中心坐标范围检索(核心)

复制代码
GEORADIUS key lon lat radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]

示例:查找 116.48,39.92 周围 5km 商家:

复制代码
GEORADIUS shop:geo 116.48 39.92 5 km WITHCOORD WITHDIST ASC

4.3.5 GEORADIUSBYMEMBER:按元素中心检索

复制代码
GEORADIUSBYMEMBER key member radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]

4.4 GEO 生产实战场景

场景:附近的人 / 附近门店

复制代码
# 添加用户位置
GEOADD user:geo 116.481028 39.922982 1001

# 查找用户 1001 附近 1km 内的人,按距离升序,最多 10 个
GEORADIUSBYMEMBER user:geo 1001 1 km ASC COUNT 10 WITHCOORD WITHDIST

4.5 GEO 避坑指南

  1. 底层是 ZSet:可用 ZREM 删除元素、ZCARD 统计数量、ZRANGE 查看;
  2. 经纬度范围:lon -180~180,lat -85.05112878~85.05112878;
  3. GEORADIUS 是重命令:避免超大范围(>10km)高并发查询;
  4. 集群 HashTag:多元素操作需同 Slot;
  5. 精度:日常 LBS 足够,不适合高精度测绘;
  6. 无法修改坐标:先 ZREM 再 GEOADD。

第五章:Redis Stream ------ Redis 官方唯一可靠分布式消息队列(替代 List)

5.1 开篇:List 队列的致命缺陷与 Stream 诞生

Redis List 常被用作简易队列(LPUSH+BRPOP),但有 4 个致命缺陷:

  1. 消息不可回溯:弹出即删除,丢失无法找回;
  2. 无消费组:无法多消费者分组负载均衡;
  3. 无 ACK 确认:无法知道消息是否被成功消费;
  4. 无持久化堆积:无法堆积海量消息,易丢失。

Redis 5.0 推出 Stream,是官方原生、可靠、可回溯、带消费组、带 ACK、支持持久化的专业消息队列,对标 Kafka 轻量级版本,完美解决 List 队列所有问题。

5.2 Stream 核心概念

  1. Stream Key:消息队列主体;
  2. Message ID :时间戳-序号(全局唯一、递增、不可重复);
  3. Message:key-value 结构化消息;
  4. Consumer Group:消费组(隔离、负载、偏移量、ACK);
  5. Consumer:组内消费者;
  6. Pending List:未 ACK 消息(处理中,防止丢失);
  7. 特殊 ID:* 自动生成 ID,0-0 最早消息,$ 最新消息,> 组内新消息。

5.3 Stream 核心命令全解(生产最常用)

5.3.1 XADD:追加消息(生产者)

复制代码
XADD key [MAXLEN ~ count] * field value [field value ...]

示例:

复制代码
XADD order:stream * user 1001 money 99.0 status 0

5.3.2 XGROUP CREATE:创建消费组

复制代码
XGROUP CREATE key groupname id|$

示例:

复制代码
XGROUP CREATE order:stream group1 0-0

5.3.3 XREADGROUP:组内消费(核心)

复制代码
XREADGROUP GROUP groupname consumername [COUNT count] [BLOCK ms] STREAMS key id

示例:

复制代码
XREADGROUP GROUP group1 consumer1 BLOCK 0 STREAMS order:stream >

5.3.4 XACK:确认消息消费成功

复制代码
XACK key groupname id [id ...]

5.3.5 XPENDING:查看未 ACK 消息

复制代码
XPENDING key groupname

5.3.6 XTRIM:截取消息(控制长度)

复制代码
XTRIM key MAXLEN ~ count

5.4 Stream 生产实战:订单异步消息队列

复制代码
# 创建消费组
XGROUP CREATE order:stream order-group 0-0

# 生产者发送订单消息
XADD order:stream * orderId 10001 userId 1001 amount 198.0

# 消费者组内阻塞读取新消息
XREADGROUP GROUP order-group consumer-1 BLOCK 0 STREAMS order:stream >

# 消费成功,ACK 确认
XACK order:stream order-group 1706123456789-0

5.5 Stream 避坑指南

  1. 消费组必须先创建,否则报错;
  2. > 只读新消息,0-0 读未 ACK 消息;
  3. 未 ACK 消息会堆积在 Pending List,占用内存;
  4. 消息 ID 严格递增,不可手动乱序插入;
  5. 定期 XTRIM 截取,避免无限堆积;
  6. Pending List 过大需处理死信、重试。

结语

恭喜你,在吃透 Redis 五大基础数据类型之后,顺利拿下了五大高级 / 特殊数据结构 这一核心进阶模块。如果说 String、List、Hash、Set、ZSet 是 Redis 支撑通用缓存、计数、列表、集合、排序场景的「基础骨架」,那么今天我们系统学习的 Bitmap、BitField、HyperLogLog、Geospatial、Stream ,就是 Redis 面向垂直细分场景的「专精利刃」------ 它们不追求全能通用,却在各自的领域里做到了内存极致、性能极致、功能专一、落地极简,是高并发、大数据、精细化运营场景下无可替代的核心工具。

回顾整篇内容,我们从每一种结构的行业痛点、诞生背景、核心原理、底层依赖、核心命令、实战场景、避坑指南出发,完整搭建了 Redis 高级结构的知识体系:

  • 我们掌握了 Bitmap 用单 bit 存储二元状态的极致内存方案,搞定了亿级用户签到、在线状态、黑名单、已读标记等高频场景;
  • 学会了 BitField 对 Bitmap 的精细化增强,实现多段位、小数值、原子批量、带溢出控制的紧凑存储,填补了原生位图只支持 0/1 的空白;
  • 解锁了 HyperLogLog 固定 12KB 内存统计海量基数的黑科技,在允许微小误差的前提下,轻松支撑亿级 UV、独立 IP、独立设备的实时统计;
  • 落地了 Geospatial 基于 ZSet 封装的 LBS 一站式方案,零开发成本实现经纬度存储、距离计算、附近的人 / 门店 / 车辆检索;
  • 吃透了 Stream 作为 Redis 官方唯一可靠消息队列的核心能力,解决了 List 简易队列不可回溯、无消费组、无 ACK、易丢消息的致命缺陷,实现分布式可靠消息、异步任务、日志采集等企业级场景。

这 5 种结构有一个贯穿始终的核心设计思想:全部基于 Redis 基础类型复用底层实现,无全新冗余存储结构,学习成本低、兼容度高、性能拉满。Bitmap/BitField 复用 String 二进制安全特性,HyperLogLog 基于字符串概率统计,Geospatial 完全依托 ZSet 跳表 + 哈希表,只有 Stream 为流场景专属设计,却依旧兼容 Redis 所有持久化、集群、过期策略。这也是它们能在生产环境中大规模落地、稳定运行的核心原因。

学习 Redis 高级结构的关键,从来不是死记硬背命令,而是精准选型、按需使用、规避陷阱:

  • 存二元状态、追求极致省内存 → 选 Bitmap;
  • 需分段存小数值、原子批量位操作 → 选 BitField;
  • 海量去重计数、允许微小误差 → 选 HyperLogLog;
  • LBS 地理检索、距离计算 → 选 Geospatial;
  • 可靠分布式消息、消费组、ACK 确认 → 选 Stream。

同时我们也清晰认知了它们的边界:Bitmap 不存非 0/1 数据、HyperLogLog 不支持精准计费与单元素查询、Geospatial 不适合高精度测绘、Stream 不替代专业 MQ(Kafka/RocketMQ)、BitField 需严格规划位段避免冲突。懂其适用场景,更懂其不可用场景,才是真正的精通。

至此,Redis 从基础核心到高级专精的全部数据类型已学习完毕。从简单的键值存储,到复杂的有序集合、位图统计、地理检索、可靠消息队列,你已经拥有了应对绝大多数互联网后端场景的 Redis 核心能力。真正的 Redis 实战高手,永远是基础类型打通用场景,高级结构攻垂直难题,二者灵活组合、精准搭配,才能实现系统的高性能、低内存、高可靠。

我们下篇 Redis 高阶实战内容,继续深入学习~

相关推荐
lie..1 小时前
30天从零开始学AI应用开发(Day 17):ChromaDB 上手:给本地文档建一个“外挂大脑”
数据库·人工智能·oracle
朝朝辞暮i1 小时前
C++ 第 31C 课:Subscriber 到底是什么
开发语言·c++·算法
海绵宝宝转agent2 小时前
操作系统八股开源笔记分享
java·面试
code_whiter2 小时前
01-MySQL数据库基础
数据库·mysql
殷色玫瑰2 小时前
C++ string类详解:常用接口、字符串操作与模拟实现
java·linux·c语言·开发语言·数据结构·c++
李游Leo2 小时前
HarmonyOS 7 + Spatial Recon Kit-C++:3DGS 高斯参数的非有限值隔离与可渲染性门禁【鸿蒙心迹】
开发语言·c++·3d·harmonyos
weixin_382395232 小时前
本地部署 ERP 选型记录:从 Excel 到轻量系统的这几年
数据库·人工智能·数据挖掘
时间的拾荒人3 小时前
Qt 文件操作详解:从基础类到读写实战
开发语言·qt·面试
2401_891409263 小时前
期货量化用得上的几类行情数据:逐笔、Level2、分钟线和五档tick
数据库