本文介绍Redis的字典(是种Map)扩容与ConcurrentHashMap的扩容策略,并比较它们的优缺点。

(不讨论它们的实现细节)

首先Redis的字典采用的是一种‘’单线程渐进式rehash‘’,这里的单线程是指只有一个线程在扩容,

而在扩容的同时其他的线程可以并发的进行读写。

Redis系统后台会定时给予扩容的那个线程足够的运行时间,这样不会导致它饿死。

大致过程是这样的:

ht[0],是存放数据的table,作为非扩容时容器。

ht[1],只有正在进行扩容时才会使用,它也是存放数据的table,长度为ht[0]的两倍。

扩容时,单线程A负责把数据从ht[0] copy到ht[1] 中。如果这时有其他线程

进行读操作:会先去ht[0]中找,找不到再去ht[1]中找。

进行写操作:直接写在ht[1]中。

进行删除操作:与读类似。

当然这过程中会设计到一系列的锁来保证同步性,不过这并不是本文的重点。

而ConcurrentHashMap采用的扩容策略为: "多线程协同式rehash"。

这里的多线程指的是,有多个线程并发的把数据从旧的容器搬运到新的容器中。

扩容时大致过程如下:

线程A在扩容把数据从oldTable搬到到newTable,这时其他线程

进行get操作:这个线程知道数据存放在oldTable或是newTable中,直接取即可。

进行写操作:如果要写的桶位,已经被线程A搬运到了newTable。

那么这个线程知道正在扩容,它也一起帮着扩容,扩容完成后才进行put操作。

进行删除操作:与写一致。

两者对比:

1.扩容所花费的时间对比:

一个单线程渐进扩容,一个多线程协同扩容。在平均的情况下,是ConcurrentHashMap快。这也意味着,扩容时所需要

花费的空间能够更快的进行释放。

2.读操作,两者的性能相差不多。

3.写操作,Redis的字典返回更快些,因为它不像ConcurrentHashMap那样去帮着扩容(当要写的桶位已经搬到了newTable时),等扩容完才能进行操作。

4.删除操作,与写一样。

所以是选择单线程渐进式扩容还是选择多线程协同式扩容,这个就具体问题具体分析了。

1.如果内存资源吃紧,希望能够进行快速的扩容方便释放扩容时需要的辅助空间,且那么选择后者。

2.如果对于写和删除操作要求迅速,那么可以选择前者。

个人觉得ConcurrentHashMap的扩容策略更让人惊艳,效果也不错。

本文转自:http://blog.csdn.net/jiji1995/article/details/64127460

Redis的字典扩容与ConcurrentHashMap的扩容策略比较的更多相关文章

  1. 基于vip和twemproxy代理实现redis集群的无感知弹性扩容

    目标是实现redis集群的无感知弹性扩容 关键点 1是无感知,即对redis集群的用户来说服务ip和port保持不变 2.弹性扩容,指的是在需要时刻可以按照业务扩大redis存储容量. 最原始的twe ...

  2. jdk7和8中关于HashMap和concurrentHashMap的扩容过程总结,以及HashMap死循环

    题外话:为什么要hashcode进行spread? 充分使用key.hashCode()的高16位信息,保证hash分布更分散, 扩容操作是新建2倍于原表大小的新表,并将原表结点拷贝一份放在新表中,对 ...

  3. 深入理解HashMap+ConcurrentHashMap的扩容策略

    前言 理解HashMap和ConcurrentHashMap的重点在于: (1)理解HashMap的数据结构的设计和实现思路 (2)在(1)的基础上,理解ConcurrentHashMap的并发安全的 ...

  4. 基于twemproxy和vip实现redis集群的无感知弹性扩容

    目标是实现redis集群的无感知弹性扩容 关键点 1.是无感知,即对redis集群的用户来说服务ip和port保持不变 2.弹性扩容,指的是在需要时刻可以按照业务扩大redis存储容量. 1.业务场景 ...

  5. 曹工说JDK源码(1)--ConcurrentHashMap,扩容前大家同在一个哈希桶,为啥扩容后,你去新数组的高位,我只能去低位?

    如何计算,一对key/value应该放在哪个哈希桶 大家都知道,hashmap底层是数组+链表(不讨论红黑树的情况),其中,这个数组,我们一般叫做哈希桶,大家如果去看jdk的源码,会发现里面有一些变量 ...

  6. 华为云企业级Redis评测第一期:稳定性与扩容表现

    摘要:采用Redis Labs推出的多线程压测工具memtier_benchmark对比测试下GaussDB(for Redis) 和原生Redis的特性差异. 本文分享自华为云社区<华为云企业 ...

  7. 深入redis内部--字典实现

    redis的字典定义和实现在dict.h和dict.c文件中. 1.字典结构 typedef struct dict { dictType *type; //定义了字典需要的函数 void *priv ...

  8. 【Redis】字典

    Redis 字典 基本语法 字典是Redis中的一种数据结构,底层使用哈希表实现,一个哈希表中可以存储多个键值对,它的语法如下,其中KEY为键,field和value为值(也是一个键值对): HSET ...

  9. Redis之字典

    概念 字典,又称为符号表.关联数组或映射(map),是一种用于保存键值对(key-value pair)的抽象数据结构.字典中每个键都是独一无二的,程序可以根据键来更新值,或者删除整个键值对. 用途 ...

随机推荐

  1. TensorFlow进阶(六)---模型保存与恢复、自定义命令行参数

    模型保存与恢复.自定义命令行参数. 在我们训练或者测试过程中,总会遇到需要保存训练完成的模型,然后从中恢复继续我们的测试或者其它使用.模型的保存和恢复也是通过tf.train.Saver类去实现,它主 ...

  2. [Python爬虫] 之二:Selenium 调用IEDriverServer打开IE浏览器安装配置

    无论是selenium2(WebDriver)还是selenium2Library,如果想要调用ie浏览器,均需以下步骤. 下载IEDriverServer.进入索引页,首先选择版本号,IEDrive ...

  3. HDU 2897 邂逅明下 (博弈)

    题意: 给你n.p.q,每次操作是令n减小 [p, q]区间中的数,当n < p时必须全部取完了,取完最后一次的人算输,问先手必胜还是必败. 解题思路: 这种非常类似巴什博弈,可以找出必胜区间和 ...

  4. 【饿了么】—— Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(三)

    前言:接着上一篇项目总结,这一篇是学习过程记录的最后一篇,这里会梳理:评论组件.商家组件.优化.打包.相关资料链接.项目github地址:https://github.com/66Web/ljq_el ...

  5. 自用封装javascript函数

    (function(){ var JHRZ_IMG_Arr = JHRZ_IMG_Arr || {}; JHRZ_IMG_Arr.loading = ["/static/images/loa ...

  6. TCP/IP编程 - 1) 基础知识

    1. What Is a Socket?(什么是套接字) A socket is an abstraction through which an application may send and re ...

  7. 解决iOS Xcode 模拟器键盘不弹出

    1. 选中模拟器,在屏幕上方的菜单中找到Hardware->Keyboard 2. 直接快捷键shift+command+k

  8. mysql last_insert_id() (转载)

    先来看看官方的说明 The ID that was generated is maintained in the server on a per-connection basis. This mean ...

  9. 在where子句中经常使用的运算符

    比较运算符 >   <   <=   >=   =    <> 大于.小于.大于(小于)等于.不等于 BETWEEN  ...AND... 显示在某一区间的值 IN ...

  10. 树莓派/RaspberryPi Ubuntu远程连接

    网络设置 设置Ubuntu主机跟树莓派在同一网段,树莓派设置静态IP地址: 查看/etc/network/interfaces的内容,其中有#For static IP, consult /etc/d ...