Redis数据结构原理浅析

 更新时间:2023年02月20日 09:14:24   作者:yunmengmeng  
这篇文章主要为大家介绍了Redis数据结构原理浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

RedisDb

Redis服务器默认有16个数据库,一个数据库对应一个RedisDB数据结构。

typedef struct redisDb {
    dict *dict;
    dict *expires;
    dict * blocking_keys;
    dict * ready_keys;
    dict * watched_keys;
    ......
}

  • dict:键空间散列表,用于存放所有键值对
  • expires:过期时间散列表,存放键的过期时间
  • blocking_keys:处于阻塞状态的键和对应的client
  • ready_keys:解除阻塞状态的键和对应的client,与blocking_keys属性相对
  • watched_keys:watch的键和对应的client,主要用于事务

RedisObject

Redis的键值都是redisObject对象,每次当我们在Redis的数据库中新创建一个键值对时,会生成一个用于键名的redisObject对象和一个用于键值的redisObject对象

trpedef struct RedisObject {
    int4 type;
    int4 encoding;
    void *ptr;
    int24 lru;
    int32 refcount;
}
字段描述说明
type用于表示Redis对应的类型string、list、hash、set、zset、stream等,用枚举表示
encoding内部编码int,embstr,raw,hashtable,quicklist, ziplist,intset,skiplist等,用枚举表示
lru24位,可选LFU或LRU当为LRU时,表示最后一次访问时间;当为LFU时,高16位用来表示分钟级别的访问时间,低8位用来表示访问频次,频次的增加使用的是概率算法,基数越大越难增加;访问时间更新时,存在一定概率将访问频次衰减。(两者共有)访问时间是对一个数取模,当前时间也取模, 当前时间大于访问时间,则为两数之差;当前时间小于访问时间,则为当前时间加上模数与访问时间之差
refcount引用计数初始值为1,实际应用中参考意义不大
ptr指针,占8个字节,指向数据的地址dict、expires等,指针指向同一个地址

object命令,就是对RedisObject的相关操作。

修改内存淘汰策略

object idletime key # 返回key的空闲时间,即上次读写键以来经过的近似描述,在lfu模式下不可用

config set maxmemory-policy volatile-lfu # 修改内存淘汰策略
set name zhangsan
object freq name # 获取计数值,仅lfu模式下可用,初始化为5

get name

object freq name # 再次访问,返回为6

int

当string值为整数并且小于等于long的最大值时,encoding为int类型,ptr直接指向该int型地址

embstr与raw

Redis的字符串叫SDS(Simple Dynamic String,简单字符串),对应key,非整数型的String值

trpedef struct SDS {
    int8 capacity; // 数组容量
    int8 len; // 实际长度
    int8 flags;
    byte[] content; // 数组内容
}

可以看出,SDS与Java的ArrayList结构类似,也是分配初始长度,长度超出时扩容。Redis规定字符串的长度不能超过512M。

当长度特别短时,使用embstr形式存储;当长度超出44字节时,使用raw形式存储。

已知内存分配器最大分配单位是64字节,RedisObject占16个字节,SDS标识占3个字节,字符串以NULL结尾需要占用一个字节,因此当字符串长度小于等于44时,只需要分配一次内存。RedisObject与SDS在同一内存单位,我们将这种数据结构称为embstr,而不在同一内存单位的,称为raw。

dict

dict(encoding编码为hashtable类型,字典)对应hash、set、zset(用于存储value与score的映射)集合。

dict与Java的HashMap结构类似,不同的是HashMap扩容是申请数组,然后遍历,将旧数据重新hash后挂到数组下面,作为单线程的Redis很难承受这样耗时的过程,所以它使用了两个数组,先返回,然后空闲的时候一点一点搬数据,搬完之后再将旧数据清空,我们将这样的过程成为渐进式rehash

typedef struct dict {
    dictht ht[2];
}

以上就是Redis数据结构原理浅析的详细内容,更多关于Redis数据结构的资料请关注脚本之家其它相关文章!

相关文章

  • 浅谈Redis缓存击穿、缓存穿透、缓存雪崩的解决方案

    浅谈Redis缓存击穿、缓存穿透、缓存雪崩的解决方案

    这篇文章主要介绍了浅谈Redis缓存击穿、缓存穿透、缓存雪崩的解决方案,缓存是分布式系统中的重要组件,主要解决在高并发、大数据场景下,热点数据访问的性能问题,需要的朋友可以参考下
    2023-03-03
  • 使用Docker部署Redis并配置持久化与密码保护的详细步骤

    使用Docker部署Redis并配置持久化与密码保护的详细步骤

    本文将详细介绍如何使用 Docker 部署 Redis,并通过 redis.conf 配置文件实现数据持久化和密码保护,适合在生产环境中使用,文章通过代码示例讲解的非常详细,需要的朋友可以参考下
    2025-03-03
  • 如何使用Redis锁处理并发问题详解

    如何使用Redis锁处理并发问题详解

    这篇文章主要给大家介绍了关于如何使用Redis锁处理并发问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • Redis主从复制操作和配置详情

    Redis主从复制操作和配置详情

    这篇文章主要介绍了Redis主从复制操作和配置详情,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 聊一聊redis奇葩数据类型与集群知识

    聊一聊redis奇葩数据类型与集群知识

    现在越来越多的项目都会利用到redis,多实例redis服务比单实例要复杂的多,这里面涉及到定位、容错、扩容等技术问题,下面这篇文章主要给大家介绍了关于redis奇葩数据类型与集群知识的相关资料,需要的朋友可以参考下
    2022-01-01
  • Redis实现每日签到功能(大数据量)

    Redis实现每日签到功能(大数据量)

    在面对百万级用户签到情况下,传统数据库存储和判断会遇到瓶颈,使用Redis的二进制数据类型可实现高效的签到功能,示例代码展示了如何调用这些功能,包括当天签到、补签以及查询签到记录,PHP结合Redis二进制数据类型可有效处理大数据量下的签到问题
    2024-10-10
  • Spring Boot整合Redis实现订单超时处理问题

    Spring Boot整合Redis实现订单超时处理问题

    这篇文章主要介绍了Spring Boot整合Redis实现订单超时处理,通过这个基本的示例,你可以了解如何使用Spring Boot和Redis来处理订单超时问题,并根据需要进行扩展和定制,需要的朋友可以参考下
    2023-11-11
  • 一文详解Redis的主从同步原理

    一文详解Redis的主从同步原理

    Redis为了保证服务高可用,其中一种实现就是主从模式,本篇文章将对主从模式中为了保证主节点和从节点数据一致而实现的主从同步机制进行学习,感兴趣的同学可以参考阅读下
    2023-07-07
  • 基于redis集群设置密码的实例

    基于redis集群设置密码的实例

    今天小编就为大家分享一篇基于redis集群设置密码的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 基于Redis实现API接口访问次数限制

    基于Redis实现API接口访问次数限制

    日常开发中会有一个常见的需求,需要限制接口在单位时间内的访问次数,比如说某个免费的接口限制单个IP一分钟内只能访问5次,该怎么实现呢,本文小编给大家介绍了如何基于Redis实现API接口访问次数限制,需要的朋友可以参考下
    2024-11-11

最新评论