Redis 特殊类型

61 阅读4分钟

Bitmap

Redis 的 Bitmap 不是独立数据结构,而是对字符串(String)的按位操作。每个 bit 表示一个布尔状态(0/1)。用于按位存储和操作数据,适用于海量数据的布尔状态存储统计等场景。

比如要记录某个用户是否登录、是否完成任务、是否在线,用一个 bit 就足够了。

单个 String 最多 512MB,一个 Bitmap 可以支持的最大 bit 数是 512MB * 8 = 2^32 个 bit。

这不是 SDS(简单动态字符串)本身的硬上限;SDS 头有 sdshdr64 等实现可承载更大。但 Redis 出于稳定性和资源控制,将默认上限设为 512MB。

应用场景

  • 签到:按天创建一个 key,用户 ID 作为位偏移。BITCOUNT 统计人数。
  • 黑白名单:O(1) 查询是否在名单中。

常用命令和复杂度

命令作用复杂度
SETBIT key offset value设置指定 offset 位置的值,返回旧的值O(1)
GETBIT key offset获取指定位置的值O(1)
BITCOUNT key [start end]统计 1 的个数;start/end 按字节索引O(N)(扫描范围)
BITOP AND|OR|XOR|NOT dest key [key...]对一个或多个字符串(位图)逐字节逐位做位运算,把结果写到目标键 dest(覆盖写入)O(N)
BITPOS key bit [start end]查找第一个 0/1 出现位置O(N)

HyperLogLog

HyperLogLog 以极小内存近似计算集合基数(去重后的数量),常用于UV/去重计数。只需要 12k 的空间就能存储接近2^64个不同元素。(算法原理)。

UV: 在给定时间窗口内,去重后的访问用户数。每个用户只计一次。

  • 固定内存:与集合中的元素个数无关,因为只维护固定数量 m 个寄存器且每个寄存器仅存一个小整数,与数据量无关。

  • 误差可控约 1.04/m1.04/\sqrt{m}:Redis 默认 p=14 → m=2142^{14}=16384,所以标准误差 = 1.04/163841.04/\sqrt{16384} ≈ 1.04/128 ≈ 0.008125 ≈ 0.81%。

HyperLogLog 的具体实现与数学中的伯努利实验相关,此处不再讲解。

命令作用复杂度
PFADD key elem ...一次加入 n 个元素O(n)
PFCOUNT key获取 HyperLogLog 的基数缓存命中为 O(1);否则 O(m)(扫描全部寄存器)
PFMERGE dest src1 src2 ... srcK将多个 HyperLogLog 合并到 destkey 中O(m·K)

PFCOUNT 会把最近一次计算的基数估计值缓存在 HLL 头部的 card[0..7] 字节里,并用最高位标记有效性;若该标记为有效,下次 PFCOUNT 直接返回该值,无需再次扫描 m 个寄存器,这就叫缓存命中。

Geospatial

Geospatial 是在一个键里存储大量地点(经纬度 + 名称),并支持高效的附近检索、距离计算等操作的功能。

底层是把每个地点存到一个 ZSET 里,地点名是 member,分值 score 不是普通数值,而是把经纬度编码后的 geohash* 整数。

常用命令和复杂度

命令作用复杂度
GEOADD key lon lat member ...新增/更新地点O(log N) 每个元素
GEOPOS key member查指定 member 的经纬度O(1) 每个元素
GEODIST key member1 member2 M/KM/FT/MI计算两点距离O(1)

GEOSEARCH key FROMMEMBER m | FROMLONLAT lon lat BYRADIUS r u | BYBOX w h u [ASC|DESC] [COUNT n] [WITHDIST|WITHCOORD|WITHHASH]

以一个起点(给定成员或经纬度)为中心,按圆形半径或矩形检索附近地点,并可选择返回距离、坐标和内部哈希,支持距离排序与数量截断。

  • 起点两种指定方式(二选一):

    • FROMMEMBER m:以已存在的成员 m 的位置为中心

    • FROMLONLAT lon lat:以给定坐标为中心(经度在前,纬度在后)

  • 范围两种形状(二选一):

    • BYRADIUS r unit:圆形半径;unit 为 m|km|ft|mi

    • BYBOX width height unit:以中心为中点、与经纬轴对齐的矩形,单位同上

  • 可选项:

    • ASC|DESC:按“到起点的距离”升序/降序

    • COUNT n:最多返回 n 个结果(不指定排序时仅做截断,不保证最近优先)

    • WITHDIST:同时返回到起点的距离

    • WITHCOORD:同时返回每个成员的经纬度

    • WITHHASH:返回内部 geohash 整数