Redis数据结构介绍

Redis 数据结构详解

Redis 支持多种数据结构,每种结构都有其独特的特性和适用场景。以下是 Redis 中所有核心数据结构的详细解析,包括底层实现、操作命令、使用场景及注意事项:


一、String(字符串)

底层实现

  • 动态字符串(SDS, Simple Dynamic String),支持二进制安全(可存储图片、序列化对象等)。
  • 根据内容自动选择编码方式:int(整数)、embstr(短字符串)、raw(长字符串)。

常用命令

SET key value        # 设置键值对
GET key              # 获取值
INCR key             # 值自增1(原子操作)
DECR key             # 值自减1
APPEND key value     # 追加内容
GETRANGE key start end # 截取子字符串
SETEX key seconds value # 设置值并指定过期时间

使用场景

  • 缓存:存储热点数据(如 HTML 片段、用户信息)。
  • 计数器:统计页面访问量、点赞数(利用 INCR 的原子性)。
  • 分布式锁:通过 SET key value NX EX 实现互斥锁。
  • 二进制存储:存储序列化的对象或图片。

注意事项

  • 大字符串(如超过 10KB)可能影响性能,需谨慎使用。

二、List(列表)

底层实现

  • 3.2 版本前使用 ziplist(压缩列表)或 linkedlist(双向链表)。
  • 3.2 版本后统一为 quicklist(由多个 ziplist 组成的双向链表,平衡内存和性能)。

常用命令

LPUSH key value1 [value2]  # 左侧插入元素
RPUSH key value1 [value2]  # 右侧插入元素
LPOP key                   # 左侧弹出元素
RPOP key                   # 右侧弹出元素
LRANGE key start end       # 获取指定范围内的元素
BLPOP key1 [key2] timeout  # 阻塞式左侧弹出(用于消息队列)

使用场景

  • 消息队列:使用 LPUSH + BRPOP 实现生产者-消费者模型。
  • 最新消息列表:存储用户最近的 100 条动态。
  • 栈或队列:通过 LPUSH/RPOPRPUSH/LPOP 组合实现。

注意事项

  • 避免单个 List 存储过多元素(如百万级),可能阻塞服务。

三、Hash(哈希表)

底层实现

  • 小规模数据使用 ziplist(字段和值交替存储),大规模数据使用 hashtable(类似字典结构)。

常用命令

HSET key field value     # 设置字段值
HGET key field           # 获取字段值
HGETALL key              # 获取所有字段和值
HINCRBY key field increment # 字段值自增
HDEL key field           # 删除字段

使用场景

  • 存储对象:如用户信息(user:1 包含 nameage 等字段)。
  • 聚合统计:记录商品的浏览次数、收藏量等。

注意事项

  • HGETALL 可能返回大量数据,建议用 HSCAN 分批次获取。
  • 字段过多时,内存占用可能较高。

四、Set(集合)

底层实现

  • 小规模数据使用 intset(整数数组),大规模数据使用 hashtable(仅存储键,值为 NULL)。

常用命令

SADD key member1 [member2]  # 添加成员
SMEMBERS key                # 获取所有成员(慎用,可能阻塞)
SISMEMBER key member        # 判断成员是否存在
SINTER key1 key2            # 求交集(共同好友)
SUNION key1 key2            # 求并集
SREM key member             # 删除成员

使用场景

  • 标签系统:记录用户的兴趣标签。
  • 去重统计:记录文章的唯一阅读用户。
  • 共同好友/兴趣:通过 SINTER 计算交集。

注意事项

  • SMEMBERS 可能阻塞服务,优先使用 SSCAN

五、Sorted Set(有序集合)

底层实现

  • 组合结构:跳跃表(skiplist) + 哈希表,支持按分数排序和快速查找成员。
  • 小规模数据使用 ziplist(按分数排序存储)。

常用命令

ZADD key score1 member1 [score2 member2]  # 添加成员及分数
ZRANGE key start end [WITHSCORES]         # 按分数升序获取成员
ZREVRANGE key start end                   # 按分数降序获取成员
ZRANK key member                          # 获取成员排名(升序)
ZSCORE key member                         # 获取成员分数
ZRANGEBYSCORE key min max                 # 按分数范围查询

使用场景

  • 排行榜:实时更新游戏玩家分数排名。
  • 带权重的队列:按优先级处理任务。
  • 时间轴:按时间戳排序的消息列表。

注意事项

  • 分数(score)为浮点数,可重复,但成员(member)唯一。

六、Bitmaps(位图)

底层实现

  • 基于 String 类型,按位操作,最大支持 2^32 位。

常用命令

SETBIT key offset 1/0       # 设置某位的值(0或1)
GETBIT key offset           # 获取某位的值
BITCOUNT key [start end]    # 统计值为1的位数
BITOP AND/OR/XOR destkey key1 key2 # 位运算(与/或/异或)

使用场景

  • 用户在线状态:每天用一个 Bitmap 记录用户的登录状态。
  • 活跃用户统计:统计一周内连续打卡的用户。
  • 布隆过滤器:结合多个哈希函数实现低成本存在性检测。

注意事项

  • 偏移量(offset)从0开始,最大值为 2^32-1。

七、HyperLogLog(基数统计)

底层实现

  • 概率算法,固定使用 12KB 内存,误差率约 0.81%。

常用命令

PFADD key element1 [element2]  # 添加元素
PFCOUNT key1 [key2]            # 估算基数(独立元素数量)
PFMERGE destkey key1 key2      # 合并多个 HLL

使用场景

  • 独立访客统计(UV):统计一天内访问网站的不同用户数。
  • 大规模数据去重:如统计搜索关键词的唯一数量。

注意事项

  • 结果为近似值,不能获取具体成员。

八、GEO(地理位置)

底层实现

  • 基于 Sorted Set,使用 Geohash 编码将经纬度转换为分数(score)。

常用命令

GEOADD key longitude latitude member  # 添加地理位置
GEODIST key member1 member2 [unit]    # 计算两地距离(米/千米等)
GEORADIUS key longitude latitude radius unit [WITHCOORD] # 查询范围内的成员

使用场景

  • 附近的人:根据用户位置查找附近的服务或用户。
  • 地理位置围栏:监控车辆是否进入特定区域。

注意事项

  • 底层为 Sorted Set,可使用 ZREM 删除成员。

九、Stream(消息流)

底层实现

  • 类似日志结构,每个条目包含唯一 ID 和多个键值对,支持消费者组。

常用命令

XADD key * field1 value1 [field2 value2]  # 添加消息(*自动生成ID)
XREAD [COUNT n] [BLOCK ms] STREAMS key ID # 读取消息
XGROUP CREATE key groupname ID            # 创建消费者组
XACK key groupname ID                     # 确认消息处理完成

使用场景

  • 消息队列:支持多消费者组、消息回溯和持久化。
  • 事件溯源:记录用户操作日志,支持按时间查询。

注意事项

  • 消息 ID 格式为 <时间戳>-<序列号>(如 1630000000000-0)。

十、其他扩展类型

  1. Bitfield

    • 将 String 视为位数组,支持对任意位进行原子操作(如无符号整数读写)。
    • 命令:BITFIELD key SET type offset value
  2. JSON 模块(需额外加载)

    • 支持 JSON 数据的存储和查询(如 JSON.SET, JSON.GET)。

总结:数据结构选择指南

场景推荐数据结构
简单键值存储String
对象存储(多字段)Hash
队列/栈List
无序去重集合Set
有序排行榜Sorted Set
二值状态统计Bitmaps
近似去重统计HyperLogLog
地理位置GEO
消息队列(高级需求)Stream

通过合理选择数据结构,可以显著提升 Redis 的性能和内存利用率。如果需要更深入某个结构的实现原理(如跳跃表、压缩列表),或实际应用案例,可以进一步探讨!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值