Redis的设计与实现 字典

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,倚天版 1GB 1个月
简介: Redis的设计与实现 字典

一 字典的概念

字典是一种保存键值对的抽象数据结构,在许多语言中都有使用,C语言并没有内置,所以Redis构建了自己的字典实现

127.0.0.1:6379> set msg "hellow yanglele"
OK

这个msg键和"hellow yanglele"值就是保存在代表数据库的字典里面,除了用来表示数据库,字典还是哈希键的底层实现,如果哈希键包含的键值对比较多,或者键值对中的元素都是比较长的字符串时,redis会使用字典作为hash键的底层实现

二 字典的实现

  1. 哈希表

    数据结构

    typedef stuct dictht {
        // 哈希表数组
        dictEntry **table;
    
        // 哈希表大小
        unsigned long size;
    
        // 哈希表大小掩码,用来计算索引值
        // 总是等于size-1
        unsigned long sizeremark;
    
        // 该hash表已有节点的数量
    }
  2. 哈希表节点

    typedef stuct dictEntry {
    
       //键
       void *key;
    
       //值
       union{
           void *val;
           unit64_t u64;
           int64_t s64;
       } v;
    
       //指向下一个hash表节点,形成链表
    
    } dictEntry;
    

    next可以将多个hash值相同的键连接在一起,从而解决hash冲突。

  3. 字典

    • 数据结构

      typedef struct dict {

      //类型特定函数
      dictType *type;;
      
      //私有数据
      void *privdata;
      
      // 哈希表
      dictht ht[2]
      
      // rehash索引
      // 当rehash不再进行时,值为-1
      int trehashindex

      } dict;

  `type`属性是为多态字典而设定的,里面包含hash值的一些函数,比如计算索引的函数,`dictht` ht[2]中包含两个数组,ht[0],和ht[1],ht[1]是对ht[0]进行rehash操作的,当rehash结束后,ht[1]就会变成ht[0];
  • 解决冲突

    如果学习过java的`HashMap`,那么就会很容易理解`redis`是怎么解决的,因为他们大概是一致的,首先通过key的hash来取的索引位置,但是索引位置可能会冲突,这时候就使用链表来解决,与HashMap一致,他们都是单项的链表,如果产生冲突,就在链表中添加元素
    
    • rehash

      这个就是前面说的,ht0与ht1,不做描述
  • 渐进式rehash

     如果值太大了,一次性移不动,怎么办,redis的解决方案就是渐进式hash,也就是一点一点移,然后通过`trehashindex`属性来看移动的进度。
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 NoSQL Java
【Redis系列】那有序集合为什么要同时使用字典和跳跃表
面试官问:那有序集合为什么要同时使用字典和跳跃表来实现?我:这个设计主要是考虑了性能因素。1. 如果单纯使用字典,查询的效率很高是O(1),但执行类似ZRANGE、ZRNK时,排序性能低。每次排序需要在内存上对字典进行排序一次,同时消耗了额外的O(n)内存空间
【Redis系列】那有序集合为什么要同时使用字典和跳跃表
|
10月前
|
缓存 NoSQL 数据建模
【Redis源码】dict字典学习(三)
【Redis源码】dict字典学习(三)
66 0
|
3月前
|
存储 缓存 NoSQL
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)(一)
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)
76 0
|
9月前
|
缓存 NoSQL Redis
【Redis 系列】redis 学习十六,redis 字典(map) 及其核心编码结构
【Redis 系列】redis 学习十六,redis 字典(map) 及其核心编码结构
|
3月前
|
存储 NoSQL 算法
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)(二)
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)
93 0
|
1月前
|
存储 Java
Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
|
9月前
|
NoSQL 安全 算法
redis6.0源码分析:字典扩容与渐进式rehash
redis6.0源码分析:字典扩容与渐进式rehash
149 0
|
9月前
|
存储 NoSQL Java
Redis源码剖析之字典(dict)
dict中的hashtable在出现hash冲突时采用的是开链方式,如果有多个entry落在同一个bucket中,那么他们就会串成一个单链表存储。
47 0
|
存储 NoSQL Redis
Redis从入门到精通之底层数据结构字典/哈希表详解
Redis中的字典(Dictionary)是一种高效的数据结构,用于存储键值对,常用于实现哈希表(Hash Table)。在本文中,我们将深入了解Redis中的字典/哈希表,包括字典的结构和操作等。字典/哈希表适合存储大量的键值对,并需要快速地查找键对应的值的场景。在实际应用中,需要根据具体的业务场景选择合适的底层数据结构。例如,如果需要按照键的顺序进行访问,可以使用有序集合(Sorted Set)等其他数据结构。
176 4
Redis从入门到精通之底层数据结构字典/哈希表详解
|
机器学习/深度学习 NoSQL 算法
Redis的设计与实现(3)-字典
Redis 的数据库使用字典实现, 对数据库的增, 删, 查, 改也是构建在对字典的操作之上的. 字典是哈希键的底层实现之一: 当一个哈希键包含的键值对比较多, 又或者键值对中的元素都是比较长的字符串时, Redis 将会使用字典作为哈希键的底层实现.
68 2