Redis五种数据类型及其底层实现

Redis五种数据类型底层实现

底层实现主要依赖这 8 种数据结构:简单动态字符串(SDS)、LinkedList(双向链表)、Hash Table(哈希表)、SkipList(跳跃表)、Intset(整数集合)、ZipList(压缩列表)、QuickList(快速列表)。

String List Hash Set Zset
INT,简单动态字符串(SDS) 双向链表(LinkedList)/压缩列表(ZipList)/快速列表(QuickList) 哈希表(Hash Table)、压缩列表(ZipList) 压缩列表(ZipList)、整数集合(Intset) 压缩列表(ZipList)、跳跃表(SkipList)
String

String 是最基本的 key-value 结构,key 是唯一标识,value 是具体的值,value其实不仅是字符串, 也可以是数字(整数或浮点数),value 最多可以容纳的数据长度是 512M

  • 底层实现(Redis5.0)

    • 整型:INT编码
    • 小于44字节的字符串:embstr编码的简单动态字符串
    • 大于44字节:raw编码的简单动态字符串(SDS)
      • SDS 不仅可以保存文本数据,还可以保存二进制数据
      • SDS 获取字符串长度的时间复杂度是 O(1)。
      • Redis 的 SDS API 是安全的,拼接字符串不会造成缓冲区溢出
  • 应用场景

    • 缓存对象

      • 直接缓存整个对象的 JSON,命令例子: SET user:1 '{"name":"xiaolin", "age":18}'
      • 采用将 key 进行分离为 user:ID:属性,采用 MSET 存储,用 MGET 获取各属性值,命令例子: MSET user:1:name xiaolin user:1:age 18 user:2:name xiaomei user:2:age 20
    • 常规计数:计算访问次数、点赞、转发、库存数量等

    • 分布式锁

      一般而言,还会对分布式锁加上过期时间,分布式锁的命令如下:

      SET lock_key unique_value NX PX 10000
      
      • lock_key 就是 key 键;
      • unique_value 是客户端生成的唯一的标识;
      • NX 代表只在 lock_key 不存在时,才对 lock_key 进行设置操作(如果 key 不存在,则显示插入成功,可以用来表示加锁成功;如果 key 存在,则会显示插入失败,可以用来表示加锁失败。)
      • PX 10000 表示设置 lock_key 的过期时间为 10s,这是为了避免客户端发生异常而无法释放锁。
    • 共享 Session 信息

List

List 列表是简单的字符串列表,按照插入顺序排序,可以从头部或尾部向 List 列表添加元素。

列表的最大长度为 2^32 - 1,也即每个列表支持超过 40 亿个元素。

  • 底层实现
    • Redis3.2之前:压缩列表+双端链表
      • 压缩列表(列表的元素个数小于 512 个,列表每个元素的值都小于 64 字节)
      • 双端链表
    • Redis3.2之后:快速列表
  • 应用场景
    • 消息队列
Hash

Hash 是一个键值对(key - value)集合,其中 value 的形式如: value=[{field1,value1},...{fieldN,valueN}]。Hash 特别适合用于存储对象。

  • 底层实现

    • 压缩列表(当Hash对象中保存的属性的数量小于512个,并且所有键值对的长度都小于64字节时)
    • 哈希表

    在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。

  • 应用场景

    • 缓存对象

    • 购物车

      添加商品:`HSET cart:{用户id} {商品id} 1`
      添加数量:`HINCRBY cart:{用户id} {商品id} 1`
      商品总数:`HLEN cart:{用户id}`
      删除商品:`HDEL cart:{用户id} {商品id}`
      获取购物车所有商品:`HGETALL cart:{用户id}`
      
Set

Set 类型是一个无序并唯一的键值集合,它的存储顺序不会按照插入的先后顺序进行存储。

一个集合最多可以存储 2^32-1 个元素。概念和数学中个的集合基本类似,可以交集,并集,差集等等,所以 Set 类型除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集。

  • 底层实现

    • 整数集合(Intset):元素个数不超过512个时

    • 哈希表

  • 应用场景

    • 点赞
    • 共同关注
    • 抽奖活动(Set 类型因为有去重功能,可以保证同一个用户不会中奖两次)
Zset

Zset 类型(有序集合类型)相比于 Set 类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序集合的元素值,一个是排序值。

有序集合保留了集合不能有重复成员的特性(分值可以重复),但不同的是,有序集合中的元素可以排序。

  • 底层实现

    • 压缩列表(如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时)

    • 跳表(类似于省市区的划分,可以快速查找):「多层」的有序链表

    在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。

  • 应用场景

    • 排行榜
    • 电话、姓名排序

你可能感兴趣的:(redis,java,哈希算法)