300分钟吃透分布式缓存-08讲:MC系统架构是如何布局的?

系统架构

我们来看一下 Mc 的系统架构。

如下图所示,Mc 的系统架构主要包括网络处理模块、多线程处理模块、哈希表、LRU、slab 内存分配模块 5 部分。Mc 基于 Libevent 实现了网络处理模块,通过多线程并发处理用户请求;基于哈希表对 key 进行快速定位,基于 LRU 来管理冷数据的剔除淘汰,基于 slab 机制进行快速的内存分配及存储。
在这里插入图片描述
系统架构

Mc 基于 Libevent 开发实现了多线程网络模型。Mc 的多线程网络模型分为主线程、工作线程。这些线程通过多路复用 IO 来进行网络 IO 接入以及读写处理。在 Linux 下,通常使用 epoll。通过多路复用 IO,特别是 epoll 的使用,Mc 线程无须遍历整个被侦听的描述符集,只要在被通知后遍历 Ready 队列的描述符集合就 OK 了。这些描述符是在各项准备工作完成之后,才被内核 IO 事件异步通知。也就是说,只在连接做好准备后,系统才会进行事件通知,Mc 才会进行 I/O 操作。这样就不会发生阻塞,使 Mc 在支持高并发的同时,拥有非常高的 IO 吞吐效率。

Mc 除了用于 IO 的主线程和工作线程外,还用于多个辅助线程,如 Item 爬虫线程、LRU 维护线程、哈希表维护线程等,通过多线程并发工作,Mc 可以充分利用机器的多个核心,实现很好的网络 IO 性能和数据处理能力。

Mc 通过哈希表即 Hashtable 来快速定位 key。数据存储时,数据 Item 结构在存入 slab 中的 chunk 后,也会被存放到 Hashtable 中。同时,Mc 的哈希表会在每个桶,通过 Item 记录一个单向链表,以此来解决不同 key 在哈希表中的 Hash 冲突问题。 当需要查找给定 key 的 Item 时,首先计算 key 的 Hash 值,然后对哈希表中与 Hash 值对应的 bucket 中进行搜索,通过轮询 bucket 里的单向链表,找到该 key 对应的 Item 指针,这样就找到了 key 对应的存储 Item,如下图所示。
在这里插入图片描述
正常情况下,Mc 对哈希表的插入、查找操作都是在主表中进行的。当表中 Item 数量大于哈希表 bucket 节点数的 1.5 倍时,就对哈希表进行扩容。如下图所示,扩容时,Mc 内部使用两张 Hashtable,一个主哈希表 primary_hashtable,一个是旧哈希表 old_hashtable。当扩容开始时,原来的主哈希表就成为旧哈希表,而新分配一个 2 倍容量的哈希表作为新的主表。扩容过程中,维护线程会将旧表的 Item 指针,逐步复制插入到新主哈希表。迁移过程中,根据迁移位置,用户请求会同时查旧表和新的主表,当数据全部迁移完成,所有的操作就重新回到主表中进行。
在这里插入图片描述
LRU 机制

Mc 主要通过 LRU 机制,来进行冷数据淘汰的。自 1.4.24 版本之后,Mc 不断优化 LRU 算法,当前 Mc 版本已默认启用分段 LRU 了。在启用分段 LRU 之前,每个 slabclass id 只对应一个 COLD LRU,在内存不足时,会直接从 COLD LRU 剔除数据。而在启用分段 LRU 之后,每个 slabclass id 就有 TEMP、HOT、WARM 和 COLD 四个 LRU。

如下图所示,TEMP LRU 中 Item 剩余过期时间通常很短,默认是 61 秒以内。该列队中的 Item 永远不会发生在队列内搬运,也不会迁移到其他队列。在插入新 key/value 时,如果 key 的剩余过期时间小于 61 秒,则直接进入 TEMP LRU。后面,在必要时直接进行过期即可。这样避免了锁竞争,性能也更高。
在这里插入图片描述
对于 HOT LRU,内部不搬运,当队列满时,如果队尾 Item 是 Active 状态,即被访问过,那么会迁移到 WARM 队列,否则迁移到 COLD 队列。

对于 WARM LRU,如果队列的 Item 被再次访问,就搬到队首,否则迁移到 COLD 队列。

对于 COLD LRU,存放的是最不活跃的 Item,一旦内存满了,队尾的 Item 会被剔除。如果 COLD LRU 里的 Item 被再次访问,会迁移到 WARM LRU。

slab 分配机制

一般应用系统的内存分配是直接采用 malloc 和 free 来进行分配及回收的。长时间运行后,内存碎片越来越多,严重增加系统内存管理器的负担。碎片的不断产生,不仅导致大量的内存浪费,而且碎片整理越来越复杂,会导致内存分配越来越慢,进而导致系统分配速度和存储效率越来越差。Mc 的 slab 分配机制的出现,碎片问题迎刃而解。下面我们来先简单了解一下 Mc 的 slab 分配机制。

Mc 通过 slab 机制来分配管理内存的,如下图所示。可以说,slab 分配机制的使用,是 Mc 分配及存储高性能的关键所在。在 Mc 启动时,会创建 64 个 slabclass,但索引为 0 的 slabclass 做 slab 重新分配之用,基本不参与其他 slabclass 的日常分配活动。每个 slabclass 会根据需要不断分配默认大小为 1MB 的 slab。

每个 slab 又被分为相同大小的 chunk。chunk 就是 Mc 存储数据的基本存储单位。slabclass 1 的 chunk size 最小,默认最小 chunk 的大小是 102 字节,后续的 slabclass 会按照增长因子逐步增大 chunk size,具体数值会进一步对 8 取整。Mc 默认的增长因子是 1.25,启动时可以通过 -f 将增长因子设为其他值。比如采用默认值,slabclass 1 的 chunk size 是 102,slabclass 2 的 chunk size 是 102×1.25,再对 8 取整后是 128。
在这里插入图片描述
Mc slab 中的 chunk 中通过 Item 结构存 key/value 键值对,Item 结构体的头部存链表的指针、flag、过期时间等,然后存 key 及 value。一般情况下,Item 并不会将 chunk 填满,但由于每个 key/value 在存储时,都会根据 kev/value size,选择最接近的 slabclass,所以 chunk 浪费的字节非常有限,基本可以忽略。

每次新分配一个 slab 后,会将 slab 空间等分成相同 size 的 chunk,这些 chunk 会被加入到 slabclass 的 freelist 中,在需要时进行分配。分配出去的 chunk 存储 Item 数据,在过期被剔除后,会再次进入 freelist,供后续使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/493383.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ETH Denver见!来参加DAO的领袖和爱好者的活动吧

我们将和 DAOBase 在美国丹佛举办 DAO 领袖和爱好者的盛会——“去中心化对话:DAO 治理的新时代”活动! 随着加密货币和区块链技术的快速发展,DAO 已成为数字经济不可或缺的一部分。目前,已有超过 10 万个 DAO,拥有超…

pageHelper分页查询

文章目录 前言一、集成1.引入库2.配置yml 二、编码1.Controller2.Service3.Mapper4.Mapper.xml5.StudentResult 三、测试1.根据页码和页数2.根据name 总结 前言 本篇文章介绍在java中使用pageHelper完成分页的功能。 使用的数据库为mysql,持久层框架mybatis。 一、集成 1.引入…

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树 106.从中序与后序遍历序列构造二叉树:star:思路分析递归解法 105. 从前序与中序遍历序列构造二叉树递归解法 ---------------🎈🎈题目链接&a…

PSA制氧装置的基本原理及在医疗领域的应用现状

随着医疗技术的不断进步,PSA(Pressure Swing Adsorption,变压吸附)制氧装置在医疗领域的应用日益广泛,其高效、安全、便捷的特点为现代医疗带来了革命性的变化。恒业通将从PSA制氧装置的基本原理出发,深入探讨其在医疗领域的应用现…

modbus-tcp协议详解

本文参考:Modbus协议中文版【完整版】.pdf,加上自己的理解的记录,该文章主要讲modbus-TCP协议。(文档下载链接:【免费】modbus协议中文详细解释文档资源-CSDN文库) 本系列文章分为三章: 1.mod…

蓝桥杯-标题统计

知识点: 关键是考察getline的作用 #include <iostream> using namespace std; int main() { string a; int t0; getline(cin,a);//每次读取一整行并把Enter键生成的换行符抛弃 for(int i0;i<a.length();i){ if(a[i]! )t; } cout<<t; return …

搜维尔科技:第九届元宇宙数字人大赛,参赛小组报名确认公告

各位参赛选手大家好&#xff0c;近期已收到新增报名信息如下表&#xff0c;请各位参赛选手确认&#xff0c;如果信息有误或信息不完整请电话联系赛务组工作人员进行更正 随着元宇宙时代的来临&#xff0c;数字人设计成为了创新前沿领域之一。为了提高大学生元宇宙虚拟人角色策划…

一个Post请求入门NestJS的路由与控制器

​ NestJS的控制器 控制器负责处理传入请求并向客户端返回响应。 控制器的目的是接收应用的特定请求。路由机制控制哪个控制器接收哪些请求。 通常&#xff0c;每个控制器都有不止一条路由&#xff0c;不同的路由可以执行不同的操作。 在使用了脚手架的项目中&#xff0c;我…

牛客周赛 Round 34 解题报告 | 珂学家 | 构造思维 + 置换环

前言 整体评价 好绝望的牛客周赛&#xff0c;彻底暴露了CF菜菜的本质&#xff0c;F题没思路&#xff0c;G题用置换环骗了50%, 这大概是唯一的亮点了。 A. 小红的字符串生成 思路: 枚举 a,b两字符在相等情况下比较特殊 a, b input().split() if a b:print (2)print (a)pri…

峰值检测电路

常用的峰值检测电路&#xff0c;如下图所示。 该电路有两种工作状态&#xff1a; 1、充电状态&#xff1a;D2导通&#xff0c;D1截止。 当U1的端比-端大时&#xff0c;V1VIN&#xff0c;VCV1-VD2&#xff0c;VOUTVC。这时&#xff0c;给电容C1充电。由于D1截止没有环路&#…

代码随想录算法训练营第二十三天| 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

文章目录 [1.修剪二叉搜索树(https://leetcode.cn/problems/trim-a-binary-search-tree/description/)2.将有序数组转换为二叉搜索树3.把二叉搜索树转换为累加树 [1.修剪二叉搜索树(https://leetcode.cn/problems/trim-a-binary-search-tree/description/) 遇到超范围节点&…

【Java】线程池总结——干货满满!!!

目录 一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 1) 任务(Runnable /Callable) 2) 任务的执行(Executor) 3) 异步计算的结果(Future) 2.3 Executor 框架的使用示意图 三 (重要)ThreadPoolExecutor 类简单介绍 3.1 Thr…