首页 游戏 软件 资讯 排行榜 专题
首页
科技数码
内存管理都不会,还做架构师?这三点差距要认清

内存管理都不会,还做架构师?这三点差距要认清

热心网友
65
转载
2025-12-02

掌握内存管理是架构师必备的核心技能之一。要想真正精通这项基本功,最有效的方法就是深入研究开源项目的实现原理。其中,memcached的核心架构设计值得每位架构师认真借鉴。

只有透彻理解内存管理的本质,才能在系统设计中游刃有余。通过参与开源项目的实践,架构师能够快速提升对内存分配、回收和碎片处理的实战能力。

第一部分:知其然

关于memcached的基础特性,架构师必须了然于心:

它的核心职能是KV内存管理,单个value的最大存储限制为1MB,并且不支持复杂数据结构(如哈希表、列表、集合、有序集合等);memcached不支持数据持久化;支持key过期机制;在持续运行中几乎不会出现内存碎片,服务性能不会随着运行时间增长而下降;采用非阻塞IO复用的网络模型,配合监听线程与工作线程的多线程架构。

您是否已经将这些memcached特性牢记于心了?

第二部分:知其原理(why, what)

第一部分停留在使用层面,除此之外,架构师还必须深入理解其背后的实现机制。

(1) memcached为什么不支持复杂数据结构?为什么不支持持久化?

技术方案往往由业务需求决定。memcached的诞生,以“通过服务方式而非库方式管理KV内存”为设计目标,它要解决的是传统KV内存管理组件库的局限性。复杂数据结构与持久化并非它的初衷。

当然,用“颠覆”这个词可能不太恰当,库和服务各有其适用场景。只是在分布式环境下,服务的使用范围确实更加广泛。设计目标与诞生背景至关重要,这在很大程度上决定了实现方案,就像redis的出现,是为了提供更好用、功能更丰富的缓存服务。

(2) memcached使用什么技术实现key过期的?

采用惰性淘汰(lazy expiration)机制。

(3) memcached为什么能保证运行性能,且很少出现内存碎片?

采用预分配内存策略。

(4) memcached为什么要使用非阻塞IO复用网络模型,采用监听线程/工作线程的多线程模型,有什么优缺点?

目的在于提升系统吞吐量。多线程能够充分利用多核优势,但会带来一些锁冲突。

第三部分:知其所以然,知其内核(how)

一个对技术内核充满好奇心的架构师,必须深入了解实现细节,掌握其核心机制。

画外音:本文的探讨才刚刚开始。

(1) memcached如何实现内存管理以减少内存碎片?它是如何进行内存分配的?

正式开讲之前,先解释几个非常重要的概念:

chunk:它是内存分配给用户使用的最小单元。

item:用户要存储的数据,包含key和value,最终都存储在chunk里。

slab:它会管理一个固定chunk size的若干个chunk,而mc的内存管理,由若干个slab组成。

画外音:为了避免复杂性,本文暂不引入page的概念。

如上图所示,一系列slab分别管理128B、256B、512B等不同尺寸的chunk内存单元。

将上图中管理128B的slab0放大来看:

能够发现slab中的一些核心数据结构是:

chunk_size:该slab管理的是128B的chunk;

free_chunk_list:用于快速找到空闲的chunk;

chunk[]:已经预分配好,用于存放用户item数据的实际chunk空间;

画外音:其实还有lru_list。

(2) 假如用户要存储一个100B的item,是如何找到对应的可用chunk呢?

会从最接近item大小的slab的chunk[]中,通过free_chunk_list快速找到对应的chunk。如上图所示,与item大小最接近的chunk是128B。

(3) 为什么不会出现内存碎片呢?

拿到一个128B的chunk,去存储一个100B的item,剩下的28B不会被其他的item所使用,即:实际上浪费了存储空间,来减少内存碎片,保证访问的速度。

画外音:理论上,内存碎片几乎不存在。

(4) memcached通过slab、chunk、free_chunk_list来快速分配内存,存储用户的item,那它又是如何实现对key的快速查找呢?

没有采用什么特殊算法:

通过哈希表实现快速查找;通过链表来解决冲突;用最朴素的方式实现key的快速查找。

(5) 随着item个数不断增多,哈希冲突越来越大,哈希表如何保证查询效率呢?

当item总数达到哈希表长度的1.5倍时,哈希表会动态扩容,rehash重新分布数据,以保证查找效率不会不断降低。

(6) 扩展哈希表之后,同一个key在新旧哈希表内的位置会发生变化,如何保证数据的一致性,以及如何保证迁移过程中服务的可用性呢(肯定不能加一把大锁,迁移完成数据,再重新服务吧)?

哈希表扩展,数据迁移是一个耗时的操作,会有一个专门的线程来实施。为了避免大锁,采用的是“分段迁移”的策略。

当item数量达到阈值时,迁移线程会分段迁移,对哈希表中的一部分桶进行加锁,迁移数据,解锁:

一来,保证不会有长时间的阻塞,影响服务的可用性;

二来,保证item不会在新旧哈希表里不一致;

(7) 新的问题来了,对于已经存在于旧哈希表中的item,可以通过上述方式进行迁移,那么在item迁移的过程中,如果有新的item插入,是应该插入旧哈希表还是新哈希表呢?

memcached的做法是:判断旧哈希表中,item应该插入的桶,是否已经迁移至新表中:

如果已经迁移,则item直接插入新哈希表;如果还没有被迁移,则直接插入旧哈希表,未来等待迁移线程来迁移至新哈希表;

(8) 为什么要这么做呢,不能直接插入新哈希表吗?

memcached没有给出解释,楼主揣测,这种方法能够保证一个桶内的数据,只在一个哈希表中(要么新表,要么旧表),任何情况下都不会出现,新旧表查询两次,以提升查询速度。

(9) memcached是怎么实现key过期的,惰性淘汰(lazy expiration)具体是怎么玩的?

实现“超时”和“过期”,最常见的两种方法是:

启动一个超时线程,对所有item进行扫描,如果发现超时,则进行超时回调处理;给每个item设置一个超时信号通知,通知触发超时回调处理;

这两种方法,都需要有额外的资源消耗。

mc的查询业务非常简单,只会返回cache hit与cache miss两种结果。这种场景下,非常适合使用惰性淘汰的方式。

惰性淘汰的核心是:

item不会被主动淘汰,即没有超时线程,也没有信号通知来主动检查;item每次被查询(get)时,检查一下时间戳,如果已经过期,被被动淘汰,并返回cache miss;

举个个例子,假如set了一个key,有效期为100秒:

在第50秒的时候,有用户查询(get)了这个key,判断未过期,返回对应的value值;在第200秒的时候,又有用户查询(get)了这个key,判断已过期,将item所在的chunk释放,返回cache miss;

这种方式的实现代价很小,资源消耗非常低:

在item里,加入一个过期时间属性;在get时,加入一个时间判断;

内存总是有限的,chunk数量有限的情况下,能够存储的item个数是有限的,假如chunk被用完了,该怎么办?

(10) 仍然是上面的例子,假如128B的chunk都用完了,用户又set了一个100B的item,要不要挤掉已有的item?

要。

这里的启示是:

即使将item的有效期设置为“永久”,也可能被淘汰;如果要做全量数据缓存,cache的内存大小,必须大于全量数据的总大小,否则很容易踩坑;

(11) 挤掉哪一个item?怎么挤?

这里涉及LRU淘汰机制。

如果操作系统的内存管理,最常见的淘汰算法是FIFO和LRU:

FIFO(first in first out):最先被set的item,最先被淘汰;LRU(least recently used):最近最少被使用(get/set)的item,最优先被淘汰;

使用LRU算法挤掉item,需要增加两个属性:

最近item访问计数;最近item访问时间;

并增加一个LRU链表,就能够快速实现。

画外音:所以,管理chunk的每个slab,除了free_chunk_list,还有lru_list。

内存管理,你学废了吗?

知其然,知其所以然。

思路比结论更重要。

来源:https://www.51cto.com/article/828323.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

图解 Linux 内存管理:虚拟内存、malloc、缺页中断,一次搞懂
业界动态
图解 Linux 内存管理:虚拟内存、malloc、缺页中断,一次搞懂

Linux 内存管理:一场由“懒惰”驱动的效率革命 Linux 内存管理的精妙之处,在于它巧妙地将几种“懒惰”哲学叠加在一起。正是这套组合拳,让系统能够在有限的内存资源上,高效地运行成百上千个进程,同时还能牢牢守住进程间的隔离墙。 上一期我们探讨文件系统时,提到了Page Cache如何占用内存,以

热心网友
04.22
内存管理都不会,还做架构师?这三点差距要认清
科技数码
内存管理都不会,还做架构师?这三点差距要认清

内存管理,是架构师的基本功之一。如何掌握这项基本功,最好的方法是和开源的项目学习。memcache的内核设计,值得每一个架构师借鉴。 内存管理,是架构师的基本功之一。如何掌握这项基本功,最好的方法是

热心网友
12.02
内存优化实战:堆分配与GC压力降低85%的5个策略
科技数码
内存优化实战:堆分配与GC压力降低85%的5个策略

在 Go 中有效的内存管理涉及对象池、逃逸分析和精心的数据结构设计的结合。通过重用资源、最小化堆分配和监控 GC 行为,我们可以构建能够高效处理高负载的系统。 在 Go 中,内存管理常常感觉像是应用

热心网友
10.31

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

面壁智能开源全双工全模态模型MiniCPM-o 4.5详解
AI资讯
面壁智能开源全双工全模态模型MiniCPM-o 4.5详解

MiniCPM-o 4 5是什么 在探索更自然、更智能的人机交互道路上,我们始终在期待一个“全能型选手”的到来。如今,这个角色或许已经登场。面壁智能最新开源的MiniCPM-o 4 5,一个仅拥有90亿参数的全模态大模型,正致力于重新划定“智能对话”的边界。 它彻底颠覆了传统一问一答的“对讲机”式交

热心网友
05.23
2025欧易OKX官网正版APP下载入口及安全获取教程
web3.0
2025欧易OKX官网正版APP下载入口及安全获取教程

Binance币安 欧易OKX ️ Huobi火币️ 想在2025年安全获取欧易OKX的正版APP?其实秘诀就一个:认准官方网站,避开所有仿冒和可疑的下载渠道。要知道,欧易现已统一更名为欧易OKX,其核心业务始终围绕数字资产交易及相关服务展开。 确认官方网站地址 第一步,打开浏览器,手动输入欧易OK

热心网友
05.23
国产AI社交平台SecondMe:真人发帖与智能互动体验
AI资讯
国产AI社交平台SecondMe:真人发帖与智能互动体验

SecondMe Book是什么 在AI社交这一前沿赛道,一款国产平台正带来独特的解决方案。SecondMe Book,本质上是一个能够让你构建个人AI数字分身的创新平台。它允许用户创建一个能够代表真实自我风格与思维的AI数字身份,并让这个“第二自我”在一个专属的AI社交网络中自主运行——包括主动发

热心网友
05.23
阶跃星辰开源Step 3.5 Flash基座模型详解
AI资讯
阶跃星辰开源Step 3.5 Flash基座模型详解

在AI大模型技术快速发展的今天,如何在卓越性能与高效推理成本之间取得最佳平衡,已成为行业关注的核心焦点。近期,由阶跃星辰推出的开源模型Step 3 5 Flash引发了广泛热议。该模型专为智能体(AI Agent)应用场景深度优化,旨在顶尖能力与亲民部署成本之间,构建一个极具竞争力的技术支点。 简而

热心网友
05.23
美团开源LongCat大语言模型Flash Lite版本详解
AI资讯
美团开源LongCat大语言模型Flash Lite版本详解

LongCat-Flash-Lite是什么 在探索大语言模型性能与效率的最佳平衡点时,美团近期推出的LongCat-Flash-Lite提供了一个极具创新性的解决方案。作为新一代高效大语言模型,它凭借其突破性的架构设计,在人工智能领域获得了广泛关注。 简而言之,该模型创新性地融合了“混合专家系统(M

热心网友
05.23