• Redis的字典扩容与ConcurrentHashMap的扩容策略比较


    本文介绍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

  • 相关阅读:
    Space for commit to queue couldn't be acquired
    数据埋点(浅谈埋点方式与上报收集)
    Hashed Indexes Geospatial Index
    线程安全 对StringBuilder抛出ArrayIndexOutOfBoundsException的探究
    [a,s]=[22,3]
    Flume-ng-sdk源码分析
    pstree
    将线上服务器生成的日志信息实时导入kafka,采用agent和collector分层传输,app的数据通过thrift传给agent,agent通过avro sink将数据发给collector,collector将数据汇集后,发送给kafka
    线程池 最大线程数
    es 300G 数据删除 执行计划 curl REST 操作
  • 原文地址:https://www.cnblogs.com/nizuimeiabc1/p/8353612.html
Copyright © 2020-2023  润新知