本文介绍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. IDEA下clean Maven项目

    如何调试出窗口: 点击菜单栏View->Tool Windows->Maven projects ♦如下图,选中之后.点击绿色三角形就可以clean了

  2. Java项目在jsp页面中引入jquery框架的步骤

    环境:在Java  web项目中引入juqery框架 工具:MyEclipse8.5 [步骤如下] A:新建一个Java web项目TestJquery,在WebRoot目录下创建一个jquery文件 ...

  3. (剑指Offer)面试题50:树中两个结点的最低公共祖先

    题目: 求树中两个结点的最低公共祖先 思路: 考虑一下几种情况: 1.该树为二叉搜索树 二叉搜索树是排序树,位于左子树点的结点都比父结点小,而位于右子树的结点都比父结点大,只需要从树的根结点开始和两个 ...

  4. <The Art of Readable Code> 笔记二 (上)

    第2章  封装信息到名字 (Packing information into names) 2.1  use specific words GetPage() 不如 FetchPage() 和 Dow ...

  5. 【数据压缩】LZW算法原理与源代码解析

    转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/50331883 <勿在浮沙筑高台> LZW压缩算法原理很easy,因 ...

  6. 算法笔记_141:无向图的欧拉回路判断问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 Problem Description 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个图,问是否存在欧拉回 ...

  7. [原]理解HTTP之Content-Type

    http://homeway.me/2015/07/19/understand-http-about-content-type/ 0x01.About 查看Restful API 报头插件:utm_s ...

  8. javascript:void(0)和onclick=fn(this)

    今天在写代码中遇到一个这样的问题.关于点击在html中添加点击事件,顺便把this对象通过参数传过去. <a href='#' \>查看详情</a> <a href='j ...

  9. 基于Django的在线考试系统

    概述 基于Django的在线考试系统,适配电脑端,可以实现出题,答题,排行榜,倒计时等等等功能 详细 代码下载:http://www.demodashi.com/demo/13923.html 项目目 ...

  10. Echarts实例

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...