本文分享自天翼云开发者社区《redis渐进式rehash》,作者:l****n

Redis是k-v型数据库,其内部设计了一种dict类型的数据结构用来存储键值结构。

dict 通常的存储结构是 Key-Value 形式的,通过 Hash 函数对 key 求 Hash 值来确定 Value 的位置,因此也叫 Hash 表,是一种用来解决算法中查找问题的数据结构,默认的算法复杂度接近 O(1)。

使用哈希表总是会遇到哈希碰撞问题,dict使用拉链法将发生碰撞的元素组成链表,挂在发生碰撞的桶下,但是随着存储元素的不断增加,碰撞发生的几率也不断增大,一个桶下链接的链表长度越来越长,定位一个key的时间复杂度就无法保证了,redis作为内存数据库,本身追求的是更高的处理性能,线性增加的耗时无疑是不能接受的,为了减少hash碰撞,需要创建一个更长的hash表,让元素能够均匀的分布在hash表上。

所以,Dict内部定义了两个hashtable,分别是dictht[0]和dictht[1],元素数量不多时,dict只在dictht[0]上存储元素,dictht[1]不分配空间。当dictht[0]的元素个数达到一定数量,会触发扩容过程,让dictht[1]指向一个2倍长度的空间,然后进行rehash, 将dictht[0]上的元素重新映射到dictht[1]上。

如果dictht[0]上有很多元素,进行rehash无疑是一个很耗时的过程,加上redis是单线程,如果想一次完成rehash,就会很长时间的阻塞业务,所以redis选择渐进式rehash。每次dictht[0]收到一个请求,只会将一个索引上的链表进行重新映射。

在将数据拷贝至dictht[1]时,dictht[0]仍然对客户端提供服务。Rehash期间,如果有新的插入元素请求时,直接将元素插入到dictht[1]中,有客户端查询请求到来, 按照dictht[0]->dictht[1]的顺序依次进行查询。

redis渐进式rehash的更多相关文章

  1. redis渐进式rehash机制

    在Redis中,键值对(Key-Value Pair)存储方式是由字典(Dict)保存的,而字典底层是通过哈希表来实现的.通过哈希表中的节点保存字典中的键值对.我们知道当HashMap中由于Hash冲 ...

  2. redis渐进式 rehash

    转载(http://redisbook.com/preview/dict/incremental_rehashing.html) 上一节说过, 扩展或收缩哈希表需要将 ht[0] 里面的所有键值对 r ...

  3. redis字典快速映射+hash釜底抽薪+渐进式rehash | redis为什么那么快

    前言 相信你一定使用过新华字典吧!小时候不会读的字都是通过字典去查找的.在Redis中也存在相同功能叫做字典又称为符号表!是一种保存键值对的抽象数据结构 本篇仍然定位在[redis前传]系列中,因为本 ...

  4. redis的rehash过程

    在扩容和收缩的时候,如果哈希字典中有很多元素,一次性将这些键全部rehash到ht[1]的话,可能会导致服务器在一段时间内停止服务.所以,采用渐进式rehash的方式,详细步骤如下: 为ht[1]分配 ...

  5. 图解Redis之数据结构篇——字典

    前言     字典在Redis中的应用非常广泛,数据库与哈希对象的底层实现就是字典. 系列文章 图解Redis之数据结构篇--简单动态字符串SDS 图解Redis之数据结构篇--链表 图解Redis之 ...

  6. Java后端技术面试汇总(第四套)

    1.Java基础 • 为什么JVM调优经常会将-Xms和-Xmx参数设置成一样:• Java线程池的核心属性以及处理流程:• Java内存模型,方法区存什么:• CMS垃圾回收过程:• Full GC ...

  7. 拿捏了!ConcurrentHashMap!

    概述 本文将对JDK8中 ConcurrentHashMap 源码进行一定程度的解读.解读主要分为六个部分:主要属性与相关内部类介绍.构造函数.put过程.扩容过程.size过程.get过程.与JDK ...

  8. Redis的字典(dict)rehash过程源代码解析

    Redis的内存存储结构是个大的字典存储,也就是我们通常说的哈希表.Redis小到能够存储几万记录的CACHE,大到能够存储几千万甚至上亿的记录(看内存而定),这充分说明Redis作为缓冲的强大.Re ...

  9. 美团针对Redis Rehash机制的探索和实践

    背景 Squirrel(松鼠)是美团技术团队基于Redis Cluster打造的缓存系统.经过不断的迭代研发,目前已形成一整套自动化运维体系,涵盖一键运维集群.细粒度的监控.支持自动扩缩容以及热点Ke ...

  10. 《闲扯Redis八》Redis字典的哈希表执行Rehash过程分析

    一.前言 随着操作的不断执行, 哈希表保存的键值对会逐渐地增多或者减少, 为了让哈希表的负载因子(load factor)维持在一个合理的范围之内, 当哈希表保存的键值对数量太多或者太少时, 程序需要 ...

随机推荐

  1. 本机环境virtualbox出现问题重装

    vagrant reload 的时候 电脑卡住死机了,然后我重启了以后就没办法启动了,于是重装这个 vagrant 使用  sudo apt-get remove vagrant  然后如果清除不干净 ...

  2. 关于开启了auth的站点如何使用curl访问

    有的站点开了 auth 如何访问呢 可以直接这样 将 用户名密码放入URL中 http://username:password@host:8080/index.html 即可.

  3. kafka之介绍

    Kafka 由于高吞吐量.可持久化.分布式.支持流数据处理等特性而被广泛应用.但当前关于Kafka原理及应用的相关资料较少,在我打算编写本文时,还没有见到中文版本的Kafka相关书籍,对于初学者甚至是 ...

  4. 系统日志查询之journalctl

    journalctl是什么 查询系统日志的工具 journalctl -xe是什么意思 -xe是排查问题时最常用的参数:-e 从结尾开始看-x 相关目录(如:问题相关的网址) journalctl - ...

  5. 解决GitHub无法访问问题

    作为开发者,经常使用借助GitHub进行开发,但是最近一直无法访问github.com站点,决定搞一下!!! 由于国内某些原因,导致我们有时候不能访问到 www.github.com.此时我们必须找到 ...

  6. Blazor 组件库 BootstrapBlazor 中Carousel组件介绍

    组件介绍 Carousel 走马灯的作用是在有限空间内,循环播放同一类型的图片.文字等内容. 代码如下: <Carousel Images="@Images" Width=& ...

  7. mysql 自定义函数写法

    1.业务场景 有时候我们希望通过sql语句解决一些复杂的问题,比如根据一个ID 查询组织的路径.这个时候我们可以使用函数来实现. 2.函数编写 CREATE FUNCTION getGroupById ...

  8. 【分块】LibreOJ 6278 数列分块入门2

    题目 https://loj.ac/p/6278 题解 将 \(n\) 个元素的数组 \(a\) 按块长 \(\sqrt{n}\) 进行分块处理.为每个块设置一个懒添加标记 \(add[i]\),代表 ...

  9. openEuler欧拉安装Jenkins并修改构建workspace路径

    ​一.系统优化 关闭防火墙 systemctl stop firewalld systemctl disable firewalld 关闭selinux sed -ri 's/SELINUX=enfo ...

  10. js面试题-代码实现

    新 API 最新的 url 参数获取的 API? URLSearchParams // 有如下一个url: http://localhost?a=1&b=2 function getUrlPa ...