Redis 原理 - Hash

打印 上一主题 下一主题

主题 551|帖子 551|积分 1653

Hash 数据结构


  • 使用 ziplist
    当同时满足下面两个条件时,使用 ziplist 存储数据

    • 元素个数少于512个 (hash-max-ziplist-entries: 512)
    • 每个元素长度小于64字节 (hash-max-ziplist-value: 64)

  • 不满足上面的条件, 使用 hashtable
Hash使用 ziplist 图解


可以看到, 当hash以ziplist编码存储时,键值对依次按顺序存放在ziplist中,key在前,value在后.
Hash使用 hashtable 图解

哈希表相关的数据结构
  1. //字典
  2. typedef struct dict {
  3.     dictType *type; // 类型特定函数
  4.     void *privdata; // 私有数据
  5.     dictht ht[2]; // 每个字典使用两个哈希表,实现渐进式 rehash
  6.     int rehashidx;   // rehash 索引,当 rehash 不在进行时,值为 -1
  7.     int iterators; // 目前正在运行的安全迭代器的数量
  8. } dict;
  9. //哈希表
  10. typedef struct dictht {
  11.     dictEntry **table; // 哈希表数组
  12.     unsigned long size; // 哈希表大小
  13.     unsigned long sizemask; // 哈希表大小掩码,用于计算索引值, 总是等于 size - 1
  14.     unsigned long used; // 该哈希表已有节点的数量
  15. } dictht;
  16. //哈希表节点
  17. typedef struct dictEntry {
  18.     void *key; // 键
  19.     union {
  20.         void *val; // 值, 正常是指向一个 redisObject
  21.         uint64_t u64;
  22.         int64_t s64;
  23.     } v;
  24.     struct dictEntry *next; // 指向下个哈希表节点,形成链表 (拉链法解决hash冲突)
  25. } dictEntry;
复制代码
哈希表图解


渐进式rehash流程

当hashtable需要扩容时,redis使用渐进式rehash

  • 为ht[1]分配空间,此时字典同时持有ht[0]和ht[1]
  • 将rehashidx设为0,表示rehash正式开始
  • 在rehash期间,每次对字典执行任意操作时,程序除了执行对应操作之外,还会顺带将ht[0]在rehashidx索引上的所有键值对rehash到ht[1],操作完后将rehashidx的值 + 1
  • Redis本身也会有事件轮询,哪怕没有命令访问,也会通过轮询事件逐渐完成数据迁移
  • 当rehashidx的值增加到 ht[0].size,此时ht[0]的所有键值对都已经迁移到ht[1]了。程序会把ht[1]赋值给ht[0],并重新在ht[1]上新建一个空表。将rehashidx重新置为-1,以此表示rehash完成
Redis为什么需要渐进式rehash?

当存在超大的hashTable进行扩容时,如果不去渐进式扩容,单次扩容时间太长,扩容期间Redis服务不可用,将导致线程阻塞
Hash的常用命令


  • HSET key field value 将一个或多个field/value插入到哈希表中
  • HGET key field 返回key中指定 field 的 value 值
  • HKEYS key 返回哈希表 key 中的所有field
  • HGETALL key 返回哈希表 key 中,所有的field和value
  • HVALS key 返回哈希表 key 中的所有value
  • HEXISTS key field 检查哈希表 key 中,field 是否存在
  • HDEL key field 删除哈希表 key 中的一个或多个field
  • HLEN key 返回哈希表 key 中field的数量
  • HSETNX key field value :将哈希表 key 中的 field 的值设置为 value , 仅当 field 不存在时才会执行

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表