一、BitMap:极简高效的位图操作
🔍 核心原理
BitMap本质是二进制数组(0/1),通过位运算实现高效存储:
# 用户访问记录(用户ID作为偏移量)
SETBIT uv:20220930 1001 1 # ID1001用户访问
SETBIT uv:20220930 1005 1
GETBIT uv:20220930 1001 # 返回1表示访问过
BITCOUNT uv:20220930 # 统计总访问用户数
💡 空间优势对比
| 数据类型 | 1亿用户存储 | 日活5000万 |
|---|---|---|
| Set | 400MB | 400MB/日 |
| BitMap | 12.5MB | 12.5MB/日 |
实际案例:某社交平台用BitMap记录每日签到,存储成本降低96%
二、布隆过滤器:概率型守护者
🌈 工作流程

⚙️ 缓存穿透解决方案
// Java实现布隆过滤器核心逻辑
public boolean mightContain(String element) {long[] indexes = getHashIndexes(element);for (long index : indexes) {if (!getBit(index)) return false;}return true; // 可能存在(有误判概率)
}
某电商平台实践:拦截99.8%恶意查询请求,数据库压力下降90%
三、HyperLogLog:百万级统计的魔法
🎲 伯努利实验分桶原理
-
数据转换:元素→64位哈希值
-
分桶策略:前14位决定16384个桶
-
值记录:后50位首次出现1的位置
-
估算公式:调和平均数计算桶值
📊 精准度测试
import redis
r = redis.Redis()# 添加10万不重复元素
for i in range(100000):r.pfadd("hll-demo", f"user-{i}")print(r.pfcount("hll-demo"))
# 输出:100267(误差0.267%)
四、Geo:地理位置之光
🗺️ 底层ZSet结构揭秘
GEOADD cities 116.28 39.55 Beijing
GEOADD cities 117.12 39.08 Tianjin
GEODIST cities Beijing Tianjin km
# 返回"89.2061"(单位公里)GEORADIUS cities 116.28 39.55 150 km
# 1) "Beijing"
# 2) "Tianjin"
# 3) "Baoding"
📍 微信附近的人实现
// 查询150公里范围内的城市
List<GeoRadiusResponse> results = jedis.georadius("cities", 116.28, 39.55, 150, GeoUnit.KM
);results.forEach(res -> System.out.println(res.getMemberByString())
);
💎 总结:四剑客最佳实践
| 数据结构 | 适用场景 | 优势 | 注意事项 |
|---|---|---|---|
| BitMap | 二值状态记录(签到/标记) | 极致空间利用率 | 偏移量范围控制 |
| 布隆过滤器 | 存在性预判(缓存穿透防护) | 高效内存消耗 | 需接受误判率 |
| HyperLogLog | 海量去重统计(UV/PV) | 固定12KB存储 | 非精确计数 |
| Geo | 地理位置服务(LBS应用) | 内置距离计算 | 基于ZSet实现 |
实战选择建议:
精确统计用BitMap
防穿透用布隆过滤器
亿级UV用HyperLogLog
地理位置用Geo
