如何永久保存微信聊天记录:完全免费的本地化备份终极方案
2026/6/7 17:40:18
Redis 数据结构全景表格
| 数据结构 | 核心命令 | 使用场景 |
|---|---|---|
| String (字符串) | SET,GET,INCR,DECR,APPEND,STRLEN,MSET,MGET | 缓存对象、计数器、分布式锁、Session存储、限速器 |
| Hash (哈希表) | HSET,HGET,HGETALL,HDEL,HINCRBY,HLEN,HMSET,HMGET | 存储对象属性(如用户信息)、购物车、配置项、结构化数据存储 |
| List (列表) | LPUSH,RPUSH,LPOP,RPOP,LRANGE,LLEN,BLPOP,BRPOP | 消息队列、最新消息排行、任务队列、关注列表、时间线 |
| Set (集合) | SADD,SREM,SMEMBERS,SISMEMBER,SCARD,SINTER,SUNION,SDIFF | 标签系统、好友关系、抽奖活动、共同关注、去重集合 |
| Sorted Set (有序集合) | ZADD,ZREM,ZRANGE,ZREVRANGE,ZRANK,ZSCORE,ZINCRBY,ZCARD | 排行榜、延时队列、范围查询、带权重的任务调度、热门内容 |
| Bitmap (位图) | SETBIT,GETBIT,BITCOUNT,BITOP,BITPOS | 用户签到、活跃用户统计、布隆过滤器、特征标记、日活统计 |
| HyperLogLog | PFADD,PFCOUNT,PFMERGE | 海量数据去重计数(UV统计)、基数估算、大数据量唯一值统计 |
| Geospatial (地理空间) | GEOADD,GEODIST,GEOPOS,GEORADIUS,GEORADIUSBYMEMBER | 附近的人/店、地理位置存储、距离计算、基于位置的服务(LBS) |
| Stream (流) | XADD,XREAD,XRANGE,XLEN,XGROUP,XREADGROUP,ACK | 事件溯源、消息队列(支持消费者组)、日志收集、实时数据处理 |
# 基础操作SET key value[EX seconds][NX|XX]# NX=不存在才设置(分布式锁),XX=存在才更新GET key DEL key# 数值操作(原子性)INCR key# 原子自增(计数器)INCRBY key100# 增加指定值DECR key SETNX key value# 等价于 SET key value NX# 批量操作MSET key1 val1 key2 val2# 批量设置(原子性)MGET key1 key2# 批量获取# 高级SETEX key60value# 设置并带过期(原子)GETSET key newvalue# 设置新值并返回旧值STRRLEN key# 获取字符串长度# 左右插入(栈/队列)LPUSH list:a value1 value2# 从左侧插入(栈:后进先出)RPUSH list:a value3# 从右侧插入(队列:先进先出)# 弹出LPOP list:a# 左侧弹出RPOP list:a# 右侧弹出BLPOP list:a10# 阻塞弹出(10秒超时),用于消息队列# 范围查询LRANGE list:a0-1# 获取全部元素LRANGE list:a09# 获取前10个(注意:O(n),大数据量慎用)# 长度LLEN list:a# 指定位置操作LINDEX list:a0# 获取索引0元素LSET list:a0newval# 设置索引0值LINSERT list:a BEFORE value2 value1.5# 插入LREM list:a2value# 删除前2个value# 增删SADD set:a member1 member2 SREM set:a member1# 查询SMEMBERS set:a# 获取所有成员(O(n),大 Set 慎用)SCARD set:a# 获取成员数量SISMEMBER set:a member1# 判断成员是否存在(O(1))# 随机操作SRANDMEMBER set:a3# 随机获取3个成员(不删除)SPOP set:a# 随机弹出1个成员(删除)# 集合运算SINTER set:a set:b# 交集(共同好友)SUNION set:a set:b# 并集SDIFF set:a set:b# 差集(a 有但 b 没有)# 添加(score 为 double 类型)ZADD zset:a100"player1"200"player2"150"player3"# 范围查询(按 score 排序)ZRANGE zset:a0-1 WITHSCORES# 升序获取全部ZREVRANGE zset:a09WITHSCORES# 降序获取 Top10# 按 score 范围查询ZRANGEBYSCORE zset:a100200WITHSCORES LIMIT010# 成员操作ZSCORE zset:a"player1"# 获取成员 scoreZINCRBY zset:a50"player1"# score 增加 50ZCARD zset:a# 成员数量# 排名ZRANK zset:a"player1"# 升序排名(从0开始)ZREVRANK zset:a"player1"# 降序排名(Top1 返回 0)# 删除ZREM zset:a"player1"ZREMRANGEBYRANK zset:a02# 删除排名 0-2 的成员ZREMRANGEBYSCORE zset:a0100# 删除 score 0-100 的成员// 延迟队列实现// 生产者ZADD delay_queue1704067200"task:email:1001"// 2024-01-01 执行// 消费者(定时任务)while(true){Set<String>tasks=ZRANGEBYSCORE delay_queue0NOW()LIMIT010;for(Stringtask:tasks){// 处理任务processTask(task);ZREM delay_queue task;// 移除}Thread.sleep(100);}# 单字段操作HSET user:1001 name"tom"age25HGET user:1001 name HDEL user:1001 age# 批量操作HMSET user:1001 name"tom"age25email"tom@example.com"HMGET user:1001 name age# 查询HGETALL user:1001# 获取所有字段(O(n))HKEYS user:1001# 获取所有 keyHVALS user:1001# 获取所有 valueHLEN user:1001# 字段数量# 存在判断HEXISTS user:1001 name# 数值操作HINCRBY user:1001 age1# age 原子加 1# 设置位SETBIT active:2024010110011# 用户1001 在 2024-01-01 活跃# 获取位GETBIT active:202401011001# 返回 0/1# 统计位数BITCOUNT active:20240101# 统计 1 的个数(日活)# 位运算BITOP AND result:3days active:20210101 active:20210102 active:20210103# 3日留存用户BITOP OR result:active active:20210101 active:20210102# 两日总活跃# 添加元素PFADD page:uv:20240101"user1""user2""user3"# 统计基数(去重后数量)PFCOUNT page:uv:20240101# 返回估算值# 合并多个 HLLPFMERGE result:uv page:uv:20240101 page:uv:20240102# 合并两日 UV# 添加坐标GEOADD cities116.4039.90"Beijing"121.4731.23"Shanghai"# 查询坐标GEOPOS cities"Beijing"# 计算距离(默认米)GEODIST cities"Beijing""Shanghai"km# 返回公里数# 查询半径内成员GEORADIUS cities116.4039.90100km# 北京100km内的城市GEORADIUSBYMEMBER cities"Beijing"100km# 以成员为中心查询# 获取哈希GEOHASH cities"Beijing"# 返回52位geohash字符串# 添加消息XADD stream:orders * user_id1001amount99.00# * 表示自动生成 ID(时间戳-序列号)# 读取消息XRANGE stream:orders - +# 读取所有消息XRANGE stream:orders1704067200000-01704153600000-0# 按时间范围# 阻塞读取(消费者)XREAD COUNT10BLOCK1000STREAMS stream:orders $# $ 表示只读取新消息,阻塞1000ms# 消费者组XGROUP CREATE stream:orders order_group $ MKSTREAM# 创建消费者组# 消费者读取(ACK 机制)XREADGROUP GROUP order_group consumer1 COUNT1BLOCK1000STREAMS stream:orders># 确认消息(ACK)XACK stream:orders order_group1704067200000-0# 未 ACK 消息查询XPENDING stream:orders order_group# 消息删除XDEL stream:orders1704067200000-0# 标记删除(非真正删除)# 识别 BigKeyredis-cli --bigkeys# 阈值String: value>10KB List/Set/ZSet/Hash: 元素数>5000CONFIG SET slowlog-log-slower-than10000# 超过 10ms 记录SLOWLOG GET10# 查看慢查询# 设置过期EXPIRE key60# 60秒后过期SETEX key60value# 原子设置+过期PERSIST key# 移除过期# 淘汰策略(maxmemory-policy)noeviction# 不淘汰,返回错误(默认)allkeys-lru# 所有 key LRU 淘汰volatile-lru# 仅过期 key LRU 淘汰allkeys-random# 随机淘汰volatile-ttl# 淘汰 TTL 短的# MULTI/EXEC 打包命令(非原子性,仅排队)MULTI SET a1SET b2EXEC# 一起执行,但中间可能被其他命令插入# WATCH 实现乐观锁WATCH balance MULTI DECRBY balance100INCRBY points10EXEC# 如果 balance 被修改,EXEC 返回 nil(回滚)注意:Redis 事务不支持回滚,命令语法错误会全部失败,运行时错误会继续执行后续命令
-- 原子执行,保证多个命令不被打断 EVAL"if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"1lock:order:1001"uuid"Pipeline pipeline=jedis.pipelined();for(int i=0;i<1000;i++){pipeline.set("key"+ i,"value"+ i);}pipeline.sync();// 一次性发送存储单个值? ├── 是 → String(缓存、计数器) │ 存储对象(多个字段)? ├── 是 → Hash(用户资料、配置) │ 需要队列/栈? ├── 是 → List(消息队列、最新列表) │ 需要去重集合? ├── 是 → Set(标签、抽奖) │ 需要排序/排行榜? ├── 是 → ZSet(积分排行) │ 需要判断存在性且数据量大? ├── 是 → Bitmap(日活、签到) │ 需要估算去重数? ├── 是 → HyperLogLog(UV) │ 需要地理位置? ├── 是 → Geospatial(附近的人) │ 需要可靠消息队列? └── 是 → Stream(带 ACK 的 MQ)Redis 的数据结构是"为场景而生":String 负责缓存计数,Hash 存储对象,List 实现队列,Set 去重,ZSet 排序,Bitmap 极致空间,HyperLogLog 估算去重,Geospatial 处理位置,Stream 支撑可靠消息。核心注意点是:避免 BigKey、警惕慢查询、理解内存编码、合理设置过期