欢迎光临
我们一直在努力

Redis存储结构有哪些

目录

一、常见数据类型

‌String (字符串)‌

‌Hash (哈希)‌

‌List (列表)‌

‌Set (集合)‌

‌Sorted Set (有序集合,Zset)‌

二、高级数据类型

‌Bitmap (位图)‌

‌HyperLogLog‌

‌Geospatial (地理空间索引)‌

‌Stream‌

三、扩展

1、简单动态字符串(SDS)

2、压缩列表(ziplist)

3、哈希表(hashtable)


Redis支持多种数据类型,每种都有其特定的内部结构和适用场景。数据类型通常分为常见类型和高级类型。

一、常见数据类型

这些是Redis最核心和广泛使用的五种数据结构。

  • ‌String (字符串)‌

    • ‌结构‌:最简单的键值对,值可以是字符串、整数或浮点数。内部会根据值的类型使用int或简单动态字符串(SDS)来存储。
    • ‌应用场景‌:
      • ‌单值缓存‌:存储单个值,如验证码、配置项。
      • ‌对象缓存‌:将对象序列化为JSON字符串后存储。
      • ‌计数器‌:利用INCR、DECR命令实现文章阅读量、点赞数等计数功能。
      • ‌分布式锁‌:通过SET key value NX EX命令实现简单的分布式锁。
      • ‌共享Session‌:在分布式系统中集中管理用户会话信息。
  • ‌Hash (哈希)‌

    • ‌结构‌:键值对集合,适合存储对象。其内部编码有两种:当字段数量和值长度较小时,使用ziplist(压缩列表)以节省内存;否则使用hashtable(哈希表)。
    • ‌应用场景‌:
      • ‌存储对象信息‌:如用户信息(hset user:1 name Tom age 25),比将整个对象存为JSON字符串更直观,且支持单独修改某个字段‌1官网。
      • ‌购物车‌:以用户ID为key,商品ID为field,商品数量为value进行存储。
  • ‌List (列表)‌

    • ‌结构‌:有序的字符串列表,可在两端插入或弹出元素。底层实现可以是ziplist或linkedlist(双向链表),根据元素数量和大小自动选择。
    • ‌应用场景‌:
      • ‌消息队列‌:使用LPUSH/RPUSH生产消息,BRPOP/BLPOP阻塞消费消息,实现简单的队列功能。
      • ‌最新消息/文章列表‌:如朋友圈时间线,使用LPUSH加入新内容,LRANGE获取最新几条。
      • ‌历史记录‌:如用户最近的搜索记录。
  • ‌Set (集合)‌

    • ‌结构‌:无序且元素唯一的字符串集合。内部实现可以是intset(整数集合)或hashtable。
    • ‌应用场景‌:
      • ‌共同关注/好友‌:利用SINTER求交集,可以找出两个用户的共同关注。
      • ‌抽奖/随机推荐‌:使用SRANDMEMBER随机获取元素。
      • ‌标签系统‌:给内容打标签,一个内容的所有标签可以存为一个集合。
  • ‌Sorted Set (有序集合,Zset)‌

    • ‌结构‌:在Set的基础上,为每个元素关联一个分数(score),用于排序。内部使用ziplist或skiplist(跳跃表)+ dict(字典)的组合实现。
    • ‌应用场景‌:
      • ‌排行榜‌:如游戏积分榜、热搜榜,通过分数进行排序,使用ZRANGE获取排名。
      • ‌带权重的队列‌:将优先级作为分数,实现优先级队列。
      • ‌范围查找‌:如查找价格在某个区间的商品。
  • 二、高级数据类型

    这些是Redis后续版本新增的、用于解决特定问题的数据结构。

  • ‌Bitmap (位图)‌

    • ‌结构‌:本质上是String,但将字符串视为一系列二进制位(bit)进行操作。
    • ‌应用场景‌:
      • ‌用户签到‌:以用户ID+日期为key,偏移量代表某一天,值1/0代表是否签到。
      • ‌活跃用户统计‌:统计一段时间内连续或间断活跃的用户。
      • ‌布隆过滤器‌:实现大规模数据下的存在性判断。
  • ‌HyperLogLog‌

    • ‌结构‌:用于基数统计(估算一个集合中不重复元素的数量)的概率算法数据结构。
    • ‌应用场景‌:
      • ‌大规模去重计数‌:如统计网站的独立访客数(UV),在数据量极大时能使用极小的内存空间完成估算,标准误差约0.81%。
  • ‌Geospatial (地理空间索引)‌

    • ‌结构‌:基于Sorted Set实现,存储经纬度信息。
    • ‌应用场景‌:
      • ‌附近的人/地点‌:使用GEORADIUS命令查询指定坐标半径内的元素‌1官网。
      • ‌计算距离‌:使用GEODIST计算两个地理位置间的距离。
  • ‌Stream‌

    • ‌结构‌:Redis 5.0引入的,为消息队列场景设计的更强大的数据结构,支持多消费者组、消息持久化、回溯消费等。
    • ‌应用场景‌:
      • ‌可靠的消息队列‌:替代之前的PUB/SUB和List方案,用于实现异步通信、事件驱动架构等。
  • 三、扩展

    1、简单动态字符串(SDS)

    SDS 是 Redis 为所有字符串键值以及字符串元素设计的底层表示,它解决了 C 语言原生字符串的诸多缺陷。

    • ‌核心结构‌:SDS 是一个结构体,主要包含三个关键属性:
      • len:记录字符串已使用的字节数,使得获取字符串长度的操作时间复杂度为 ‌O(1)‌。
      • free:记录未使用的字节数。
      • buf[]:一个柔性数组,用于实际保存字符串数据,其末尾会自动追加一个空字符 \\0 以兼容部分 C 字符串函数。
    • ‌核心优势‌:
    • ‌常数时间复杂度获取长度‌:通过 len 属性直接获取,无需遍历。
    • ‌杜绝缓冲区溢出‌:SDS 的 API 在修改字符串前会自动检查并扩展空间。
    • ‌减少内存重分配‌:通过 ‌空间预分配‌ 和 ‌惰性空间释放‌ 策略优化性能。当字符串需要增长时,不仅分配所需空间,还会额外分配冗余空间(free)。具体策略是:增长后长度小于 1MB 时,分配与 len 等大的 free 空间;超过 1MB 时,则固定多分配 1MB 的 free 空间。
    • ‌二进制安全‌:SDS API 以处理二进制数据的方式处理 buf 数组,程序仅依赖 len 属性而非空字符 \\0 来判断字符串结束,因此可以安全保存包含空字符在内的任意二进制数据(如图片、音频)。
    • ‌应用‌:所有字符串键值、AOF 缓冲区、客户端输入缓冲区等均由 SDS 实现。

    2、压缩列表(ziplist)

    压缩列表是 Redis 为节省内存而设计的一种紧凑的‌顺序型数据结构‌,用于列表键和哈希键的底层实现之一。

    • ‌核心结构‌:ziplist 是一块‌连续的内存块‌,由一系列特殊编码的 ‌entry(条目)‌ 组成。每个 entry 可以保存一个字节数组或一个整数值。它没有像链表那样额外的指针开销,所有数据紧密排列。
    • ‌核心优势‌:
    • ‌极高的内存利用率‌:因为是连续存储,没有指针等元数据开销,特别适合存储‌少量的小整数或短字符串‌。
    • ‌顺序访问‌:由于数据连续,遍历效率高。
    • ‌应用与转换‌:
      • ‌Hash 类型‌:默认采用 ziplist 编码以节省内存。在 ziplist 中,相邻的两个 entry 分别保存 field 和 value。
      • ‌List 类型‌:在旧版本中,当列表元素较少且较小时,也使用 ziplist。
      • ‌转换条件‌:当存储的数据量变大或元素变长时,为了维持操作效率,Redis 会自动将 ziplist 转换为更适用于大量数据操作的结构(如 hashtable 或 linkedlist/quicklist)。对于 Hash 结构,触发转换的两个典型条件是:哈希表中的键值对数量或某个值的长度超过预设阈值。

    3、哈希表(hashtable)

    哈希表是 Redis 字典(Dict)的底层实现,用于实现高效的键值对查找,是 Hash 类型的主要底层结构之一。

    • ‌核心结构‌:Redis 的哈希表使用 ‌链地址法‌ 解决哈希冲突。其核心是一个数组(table),数组的每个元素是一个指向 ‌哈希表节点(dictEntry)‌ 的指针。每个 dictEntry 包含:
      • key:键,指向一个 SDS 对象。
      • value:值,可以指向各种类型的 Redis 对象。
      • next:指向下一个哈希表节点的指针,形成链表以解决键冲突。
    • ‌核心操作与优化‌:
    • ‌哈希算法与索引计算‌:添加新键值对时,先计算键的哈希值,然后通过 hash & sizemask(sizemask 等于数组大小减一)计算索引值,决定放入数组的哪个位置。
    • ‌渐进式 rehash‌:当哈希表需要扩容或收缩时,Redis 采用渐进式 rehash。它会同时维护两个哈希表(ht[0] 和 ht[1]),在 rehash 期间,每次对字典的增删改查操作,除了执行指定操作外,还会顺带将 ht[0] 中对应索引上的所有键值对 ‌渐进式地‌ 迁移到 ht[1]。这避免了一次性 rehash 导致的服务器长时间阻塞。
    • ‌应用‌:当 Hash 类型的键值对数量或值长度超过 ziplist 的承载能力时,其底层结构就会从 ziplist 转换为 hashtable,以确保操作效率。此外,整个 Redis 的键空间(Key Space)本身就是一个巨大的全局哈希表。
    赞(0)
    未经允许不得转载:171主机测评 » Redis存储结构有哪些
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址