聊聊缓存世界的扫地僧
这篇文章,笔者想聊聊那些在业务系统中较少被使用,但却活跃于中间件或者框架里,强大却又低调的缓存,笔者愿称他们为缓存世界的扫地僧。
一、HashMap/ConcurrentHashMap 配置缓存HashMap 是一种基于哈希表的集合类,它提供了快速的插入、查找和删除操作。
(资料图片仅供参考)
HashMap 是很多程序员接触的第一种缓存 , 因为现实业务场景里,我们可能需要给缓存添加缓存统计、过期失效、淘汰策略等功能,HashMap 的功能就显得孱弱 ,所以 HashMap 在业务系统中使用得并不算多。
但HashMap 在中间件中却是香饽饽,我们消息中间件 RocketMQ 为例。
上图是 RocketMQ 的集群模式 ,Broker 分为 Master 与 Slave,一个 Master 可以对应多个 Slave,但是一个 Slave 只能对应一个 Master。
每个 Broker 与 Name Server 集群中的所有节点建立长连接,定时每隔 30 秒注册主题的路由信息到所有 Name Server。
消息发送者、消息消费者,在同一时间只会连接 Name Server 集群中的一台服务器,并且会每隔 30s 会定时更新 Topic 的路由信息。
我们可以理解 Name Server 集群的作用就是注册中心,注册中心会保存路由信息(主题的读写队列数、操作权限等),路由信息就是保存在HashMap中 。
路由信息通过几个 HashMap 来保存,当 Broker 向 Nameserver 发送心跳包(路由信息),Nameserver 需要对 HashMap 进行数据更新,但我们都知道 HashMap 并不是线程安全的,高并发场景下,容易出现 CPU 100% 问题,所以更新 HashMap 时需要加锁,RocketMQ 使用了 JDK 的读写锁 ReentrantReadWriteLock 。
下面我们看下路由信息如何更新和读取:
1、写操作:更新路由信息,操作写锁2、读操作:查询主题信息,操作读锁同时,我们需要注意 Name Server 维护路由信息还需要定时任务的支撑。
每个 Broker 定时每隔 30 秒注册主题的路由信息到所有 Name ServerName Server 定时任务每隔10 秒清除已宕机的 Broker我们做一个小小的总结,Name Server 维护路由的模式是:HashMap + 读写锁 + 定时任务更新。
HashMap 作为存储容器读写锁控制锁的颗粒度定时任务定时更新缓存写到这里,我们不禁想到 ConcurrentHashMap 。
ConcurrentHashMap 可以保证线程安全,JDK1.7 之前使用分段锁机制实现,JDK1.8 则使用数组+链表+红黑树数据结构和CAS原子操作实现。
Broker 使用不同的 ConcurrentHashMap 分别用来存储消费组、消费进度、消息过滤信息等。
那么名字服务为什么不使用 ConcurrentHashMap 作为存储容器呢 ?
最核心的原因在于:路由信息由多个 HashMap 组成,通过每次写操作可能要操作多个对象 ,为了保证其一致性,所以才需要加读写锁。
二、LinkedHashMap 最近最少使用缓存LinkedHashMap 是 HashMap 的子类,但是内部还有一个双向链表维护键值对的顺序,每个键值对既位于哈希表中,也位于双向链表中。
LinkedHashMap 支持两种顺序插入顺序 、 访问顺序。
插入顺序:先添加的在前面,后添加的在后面,修改操作并不影响顺序访问顺序:问指的是 get/put 操作,对一个键执行 get/put 操作后,其对应的键值对会移动到链表末尾,所以最末尾的是最近访问的,最开始的是最久没有被访问的,这就是访问顺序。LinkedHashMap 经典的用法是作为 LruCache (最近最少使用缓存) ,而 MyBatis 的二级缓存的淘汰机制就是使用的 LinkedHashMap 。
MyBatis 的二级缓存是使用责任链+装饰器的设计模式实现的。
上图中,装饰器包目录下 Cache 接口有不同的实现类,比如过期淘汰、日志记录等。
LruCache 使用了装饰器模式 ,使用 LinkedHashMap 默认保存 1024 个缓存 key ,当 key 最久未被访问,并且 keyMap 的大小超过 1024 时 ,记录最老的 key ,当下次添加缓存对象时,删除最老的 key。
使用 LinkedHashMap 重点需要做到使用访问顺序模式和重写 removeEldestEntry 方法。因为 LinkedHashMap 并不是线程安全的,Mybatis 二级缓存责任链中 SynchronizedCache 对象可以实现线程安全的对缓存读写。
三、TreeMap 排序对象缓存TreeMap 是一种基于红黑树的有序 Map,它可以按照键的顺序进行遍历。
TreeMap 有两种应用场景让笔者印象极为深刻 ,他们分别是一致性哈希算法和 RocketMQ 消费快照 。
本文重点介绍 TreeMap 在一致性哈希算法中的应用。
一致性哈希(Consistent Hashing)算法被广泛应用于缓存系统、分布式数据库、负载均衡器等分布式系统中,以实现高性能和高可用性。它解决了传统哈希算法在动态环境下扩展性和负载均衡性能的问题。
一致性哈希的主要优点是在节点增减时,只有少量的数据需要重新映射,因为只有那些直接或间接与新增或删除节点相邻的数据项需要迁移。这大大减少了系统的迁移开销和影响,使得系统更具扩展性和可伸缩性。
TreeMap 在一致性哈希中可以用作节点/虚拟节点的存储结构,用来维护节点在哈希环上的位置和键的有序性。
1、我们定义一个 TreeMap 存储节点/虚拟节点 。2、初始化节点构造函数包含三个部分:物理节点集合、每个物理节点对应的虚拟节点个数、哈希函数 。
我们重点看下添加节点逻辑:
3、按照 key 查询节点添加完节点之后,节点分布类似下图:
当需要定位某个 key 属于哪个节点时,先通过哈希函数计算 key 的哈希值,并在环上顺时针方向找到第一个大于等于该哈希值的节点位置。该节点即为数据的归属节点 。
我们添加一个新的节点 node5 , 从下图中,我们可以看到,影响的范围(深黄色)并不大 ,这也就是一致性哈希算法的优势。
四、ByteBuffer 网络编程缓冲池ByteBuffer 是字节缓冲区,主要用于用户读取和缓存字节数据,多用于网络编程、文件 IO 处理等。
笔者第一次接触 ByteBuffer 是在分库分表中间件 Cobar 中 。在网络编程里,经常需要分配内存,在高并发场景下,性能压力比较大。
Cobar 抽象了一个 NIOProcessor 类用来处理网络请求,每个处理器初始化的时候都会创建一个缓冲池 BufferPool 。BufferPool 用于池化 ByteBuffer ,这和我们平常使用的数据库连接池的思路是一致的。
下图展示了缓冲池 BufferPool 的源码:
缓冲池 BufferPool 的核心功能是分配缓存和回收缓存,通过将缓存池化,可以大大提升系统的性能。
如今 ,Netty 内置了更为强大的内存池化工具 ByteBuf ,我们会在后面的文章里详聊。
五、写到最后这篇文章,笔者总结了四种强大且低调的缓存。
1、HashMap/ConcurrentHashMap 经常用于配置缓存,对于 HashMap 来讲,HashMap + 读写锁 + 定时任务更新是常用的模式。而 ConcurrentHashMap 广泛存在于各种中间件,线程安全且灵活易用。
2、LinkedHashMap 经常被用于创建最近最少使用缓存 LruCache 。推荐学习 Mybatis 二级缓存的设计,它使用责任链+装饰器的设计模式,内置 LruCache 的实现就是使用 LinkedHashMap 。
3、TreeMap 是一种基于红黑树的有序 Map 。TreeMap 在一致性哈希中可以用作节点/虚拟节点的存储结构,用来维护节点在哈希环上的位置和键的有序性。
4、ByteBuffer 是字节缓冲区,主要用于用户读取和缓存字节数据,多用于网络编程、文件 IO 处理等。分库分表中间件 Cobar 在网络请求处理中,创建了缓冲池 BufferPool 用于池化 ByteBuffer ,从而大大提升系统的性能。
关键词:
- 聊聊缓存世界的扫地僧(2023-06-27 02:38:43)
- 陈戌源正式宣布,里皮接替李铁悬念揭晓,国足敲定教练组升级计划(2023-06-27 02:34:34)
- 甘肃省山丹县市场监管局开展燃气用品质量安全监管专项整治行动|热消息(2023-06-27 02:44:57)
- 广东高考2022年提前批非军检投档情况 每日热点(2023-06-27 02:41:24)
- 微资讯!高效纤维球滤料商品报价动态(2023-06-26)(2023-06-27 02:54:54)
- 天天新资讯:刚刚,我市中招考试开考!19万余名考生参加考试(2023-06-27 02:31:45)
- 全球报道:新华文轩(601811)6月26日主力资金净卖出2624.22万元(2023-06-27 02:50:31)
- 常州停车收费公示牌样式(最新)(2023-06-27 02:47:07)
- “兔赢赢”来了!河北省第十届残运会吉祥物发布(2023-06-27 02:44:15)
- 【世界独家】津膜科技控股股东航膜科技增持432.52万股 耗资3508.27万(2023-06-27 02:38:23)
- 最新资讯:厦门第四届鼓浪屿音乐节流行乐专场购票须知(2023-06-27 02:39:15)
- 2023太原新城市音乐节除了演出还有什么好玩的吗?(2023-06-27 02:45:12)
- 鸡腿怎么炒才好吃最简单的做法?(2023-06-27 02:37:14)
- 每日消息!福建农信:立足福建海洋资源优势 推进金融服务创新(2023-06-27 02:29:26)
- 王者荣耀S32赛季明日开启 除新英雄亚连还有这些变化(2023-06-27 02:40:52)
- 最爱操心的五大星座(2023-06-27 02:37:37)
- 林园针对A股调整发声:现在已经被低估!机会是留给乐观的人的,在这些领域被套了可以再买一点(2023-06-27 02:34:12)
- Win10“钉子户”换用Win11后 坦言打开了新世界:告别偏见-焦点资讯(2023-06-27 02:31:34)
- 阿汤哥17岁女儿最新出街美到我了!小姑娘还化妆了,身材曲线很棒(2023-06-27 02:41:35)
- 厦门市同安火炬实验小学预计今年9月投用 位于同翔高新城 环球新动态(2023-06-27 02:51:44)
- 提升为民服务水平!枣庄薛城打造“一站式”公共法律服务中心(2023-06-27 02:31:50)
- 市贸促会“贸促讲堂”第三期开讲:新时期的新商机与新招商_焦点快报(2023-06-27 02:44:10)
- 天天新消息丨浙皖一家亲,共绘山水情——“坐着高铁来越城”专场推介会走进合肥蜀山(2023-06-27 02:50:43)
- 【世界时快讯】这种车,禁止生产销售!新规即将实施……(2023-06-27 02:48:12)
- “杭州米其林面馆最贵一碗面涨到80元”上热搜,吃货和老板都有话说(2023-06-27 02:41:18)
- 【中国那些事儿】亚美尼亚驻华大使:亚美尼亚永远都是中国最可靠的伙伴(2023-06-27 02:33:13)
- 环球最资讯丨扬州全力推进外资外贸工作“双过半”(2023-06-27 02:27:54)
- 特色产业激发乡村振兴新活力(2023-06-27 02:39:49)
- 前途无量的意思_前途无量(2023-06-27 02:39:46)
- 天天速讯:游戏公司擅自出版网游被罚没72万(2023-06-27 02:37:11)
-
鸡腿怎么炒才好吃最简单的做法?
用料:鸡腿肉、蚝油1勺、酱油1 2勺、糖、盐、料酒1勺、黑胡椒碎、油做
-
每日消息!福建农信:立足福建海洋资源优势
“我们要主动投身海洋经济发展战略大局,立足福建省海洋资源禀赋的优势
-
王者荣耀S32赛季明日开启 除新英雄亚连还
王者荣耀S31赛季将在6月下旬结束,那么,S32新赛季会在哪天更新呢?6月
-
最爱操心的五大星座
就算对方没有主动开口,巨蟹座也能从各种细节中察觉出别人的难处,然后
-
林园针对A股调整发声:现在已经被低估!机
1 我们觉得现在已经处在令人兴奋的状态,是可以有一些买入行为的,机会
-
Win10“钉子户”换用Win11后 坦言打开了新
Win10“钉子户”换用Win11后坦言打开了新世界:告别偏见
-
阿汤哥17岁女儿最新出街美到我了!小姑娘还
17岁的小苏瑞已经有着非常好看的曲线了,还记得阿汤哥抱着她出街的时候
-
厦门市同安火炬实验小学预计今年9月投用
“希望小孩9月份可以读上家门口的实验小学。”家住布塘村的陈先生满是
-
提升为民服务水平!枣庄薛城打造“一站式”
齐鲁网·闪电新闻6月26日讯 近年来,枣庄市薛城区以群众实际法律需求
-
市贸促会“贸促讲堂”第三期开讲:新时期的
汨罗融媒体讯(通讯员杨杏)端午节系列活动沸腾了汨罗,火爆现象的背后
- 滚动
- 综合
- 房产