基于SSD的Kafka应用层缓存架构设计与实现

Kafka出色的I/O优化以及多处异步化设计,相比其他消息队列系统具有更高的吞吐,同时能够保证不错的延迟,十分适合应用在整个大数据生态中。

目前在美团数据平台中,Kafka承担着数据缓冲和分发的角色。如下图所示,业务日志、接入层Nginx日志或线上DB数据通过数据采集层发送到Kafka,后续数据被用户的实时作业消费、计算,或经过数仓的ODS层用作数仓生产,还有一部分则会进入公司统一日志中心,帮助工程师排查线上问题。

目前美团线上Kafka规模:

当前Kafka支撑的实时作业数量众多,单机承载的Topic和Partition数量很大。这种场景下很容易出现的问题是:同一台机器上不同Partition间竞争PageCache资源,相互影响,导致整个Broker的处理延迟上升、吞吐下降。

接下来,我们将结合Kafka读写请求的处理流程以及线上统计的数据来分析一下Kafka在线上的痛点。

对于Produce请求:Server端的I/O线程统一将请求中的数据写入到操作系统的PageCache后立即返回,当消息条数到达一定阈值后,Kafka应用本身或操作系统内核会触发强制刷盘操作(如左侧流程图所示)。

对于Consume请求:主要利用了操作系统的ZeroCopy机制,当KafkaBroker接收到读数据请求时,会向操作系统发送sendfile系统调用,操作系统接收后,首先试图从PageCache中获取数据(如中间流程图所示);如果数据不存在,会触发缺页异常中断将数据从磁盘读入到临时缓冲区中(如右侧流程图所示),随后通过DMA操作直接将数据拷贝到网卡缓冲区中等待后续的TCP传输。

综上所述,Kafka对于单一读写请求均拥有很好的吞吐和延迟。处理写请求时,数据写入PageCache后立即返回,数据通过异步方式批量刷入磁盘,既保证了多数写请求都能有较低的延迟,同时批量顺序刷盘对磁盘更加友好。处理读请求时,实时消费的作业可以直接从PageCache读取到数据,请求延迟较小,同时ZeroCopy机制能够减少数据传输过程中用户态与内核态的切换,大幅提升了数据传输的效率。

但当同一个Broker上同时存在多个Consumer时,就可能会由于多个Consumer竞争PageCache资源导致它们同时产生延迟。下面我们以两个Consumer为例详细说明:

如上图所示,Producer将数据发送到Broker,PageCache会缓存这部分数据。当所有Consumer的消费能力充足时,所有的数据都会从PageCache读取,全部Consumer实例的延迟都较低。此时如果其中一个Consumer出现消费延迟(图中的ConsumerProcess2),根据读请求处理流程可知,此时会触发磁盘读取,在从磁盘读取数据的同时会预读部分数据到PageCache中。当PageCache空间不足时,会按照LRU策略开始淘汰数据,此时延迟消费的Consumer读取到的数据会替换PageCache中实时的缓存数据。后续当实时消费请求到达时,由于PageCache中的数据已被替换掉,会产生预期外的磁盘读取。这样会导致两个后果:

我们针对HDD的性能和读写并发的影响做了梯度测试,如下图所示:

可以看到,随着读并发的增加,HDD的IOPS和带宽均会明显下降,这会进一步影响整个Broker的吞吐以及处理延迟。

同时,我们统计了线上实时作业的消费延迟分布情况,延迟范围在0-8min(实时消费)的作业只占80%,说明目前存在线上存在20%的作业处于延迟消费的状态。

总结上述的原理分析以及线上数据统计,目前线上Kafka存在如下问题:

按目前的PageCache空间分配以及线上集群流量分析,Kafka无法对实时消费作业提供稳定的服务质量保障,该痛点亟待解决。

根据上述痛点分析,我们的预期目标为保证实时消费作业不会由于PageCache竞争而被延迟消费作业影响,保证Kafka对实时消费作业提供稳定的服务质量保障。

根据上述原因分析可知,解决目前痛点可从以下两个方向来考虑:

对于第一个方向,由于PageCache由操作系统管理,若修改其淘汰策略,那么实现难度较为复杂,同时会破坏内核本身对外的语义。另外,内存资源成本较高,无法进行无限制的扩展,因此需要考虑第二个方向。

SSD目前发展日益成熟,相较于HDD,SSD的IOPS与带宽拥有数量级级别的提升,很适合在上述场景中当PageCache出现竞争后承接部分读流量。我们对SSD的性能也进行了测试,结果如下图所示:

从图中可以发现,随着读取并发的增加,SSD的IOPS与带宽并不会显著降低。通过该结论可知,我们可以使用SSD作为PageCache与HDD间的缓存层。

在引入SSD作为缓存层后,下一步要解决的关键问题包括PageCache、SSD、HDD三者间的数据同步以及读写请求的数据路由等问题,同时我们的新缓存架构需要充分匹配Kafka引擎读写请求的特征。本小节将介绍新架构如何在选型与设计上解决上述提到的问题。

Kafka引擎在读写行为上具有如下特性:

下文给出了两种备选方案,下面将对两种方案给出我们的选取依据与架构决策。

备选方案一:基于操作系统内核层实现

目前开源的缓存技术有FlashCache、BCache、DM-Cache、OpenCAS等,其中BCache和DM-Cache已经集成到Linux中,但对内核版本有要求,受限于内核版本,我们仅能选用FlashCache/OpenCAS。

如下图所示,FlashCache以及OpenCAS二者的核心设计思路类似,两种架构的核心理论依据为“数据局部性”原理,将SSD与HDD按照相同的粒度拆成固定的管理单元,之后将SSD上的空间映射到多块HDD层的设备上(逻辑映射or物理映射)。在访问流程上,与CPU访问高速缓存和主存的流程类似,首先尝试访问Cache层,如果出现CacheMiss,则会访问HDD层,同时根据数据局部性原理,这部分数据将回写到Cache层。如果Cache空间已满,会通过LRU策略替换部分数据。

FlashCache/OpenCAS提供了四种缓存策略:WriteThrough、WriteBack、WriteAround、WriteOnly。由于第四种不做读缓存,这里我们只看前三种。

写入:

读取:

更多详细实现细节,极大可参见这二者的官方文档:

备选方案二:Kafka应用内部实现

上文提到的第一类备选方案中,核心的理论依据“数据局部性”原理与Kafka的读写特性并不能完全吻合,“数据回刷”这一特性依然会引入缓存空间污染问题。同时,上述架构基于LRU的淘汰策略也与Kafka读写特性存在矛盾,在多Consumer并发消费时,LRU淘汰策略可能会误淘汰掉一些近实时数据,导致实时消费作业出现性能抖动。

当消费请求到达KafkaBroker时,KafkaBroker直接根据其维护的消息偏移量(Offset)和设备的关系从对应的设备中获取数据并返回,并且在读请求中并不会将HDD中读取的数据回刷到SSD,防止出现缓存污染。同时访问路径明确,不会由于CacheMiss而产生的额外访问开销。

下表对不同候选方案进行了更加详细的对比:

最终,结合与Kafka读写特性的匹配度,整体工作量等因素综合考虑,我们采用Kafka应用层实现这一方案,因为该方案更贴近Kafka本身读写特性,能更加彻底地解决Kafka的痛点。

根据上文对Kafka读写特性的分析,我们给出应用层基于SSD的缓存架构的设计目标:

依据上述目标,我们给出应用层基于SSD的Kafka缓存架构实现:

对于写请求而言,写入请求依然首先将数据写入到PageCache中,满足阈值条件后将会刷入SSD。对于读请求(当PageCache未获取到数据时),如果读取的offset对应的LogSegment的状态为Cached或OnlyCache,则数据从SSD返回(图中LC2-LC1以及RC1),如果状态为WithoutCache,则从HDD返回(图中LC1)。

对于Follower副本的数据同步,可根据Topic对延迟以及稳定性的要求,通过配置决定写入到SSD还是HDD。

LogSegment同步

LogSegment同步是指将SSD上的数据同步到HDD上的过程,该机制在设计时主要有以下两个关键点:

同步方式

关于LogSegment的同步方式,我们给出了三种备选方案,下表列举了三种方案的介绍以及各自的优缺点:

最终,我们对一致性维护代价、实现复杂度等因素综合考虑,选择了后台同步Inactive的LogSegment的方式。

同步限速

LogSegment同步行为本质上是设备间的数据传输,会同时在两个设备上产生额外的读写流量,占用对应设备的读写带宽。同时,由于我们选择了同步Inactive部分的数据,需要进行整段的同步。如果在同步过程中不加以限制会对服务整体延迟造成较大的影响,主要表现在下面两个方面:

基于上述两点,我们需要在LogSegment同步过程中增加限速机制,总体的限速原则为在不影响正常读写请求延迟的情况下尽可能快速地进行同步。因为同步速度过慢会导致SSD数据无法被及时清理而最终被写满。同时为了可以灵活调整,该配置也被设置为单Broker粒度的配置参数。

日志追加刷盘策略优化

除了同步问题,数据写入过程中的刷盘机制同样影响服务的读写延迟。该机制的设计不仅会影响新架构的性能,对原生Kafka同样会产生影响。

下图展示了单次写入请求的处理流程:

在Produce请求处理流程中,首先根据当前LogSegment的位置与请求中的数据信息确定是否需要滚动日志段,随后将请求中的数据写入到PageCache中,更新LEO以及统计信息,最后根据统计信息确定是否需要触发刷盘操作,如果需要则通过fileChannel.force强制刷盘,否则请求直接返回。

在整个流程中,除日志滚动与刷盘操作外,其他操作均为内存操作,不会带来性能问题。日志滚动涉及文件系统的操作,目前,Kafka中提供了日志滚动的扰动参数,防止多个Segment同时触发滚动操作给文件系统带来压力。针对日志刷盘操作,目前Kafka给出的机制是以固定消息条数触发强制刷盘(目前线上为50000),该机制只能保证在入流量一定时,消息会以相同的频率刷盘,但无法限制每次刷入磁盘的数据量,对磁盘的负载无法提供有效的限制。

对于SSD新缓存架构,同样存在上述问题,因此在新架构中,在刷盘操作中同样对刷盘速率进行了限制。

从单Broker请求延迟角度看:

在刷盘机制优化前,SSD新缓存架构在所有场景下,较其他方案都具有明显优势。

刷盘机制优化后,其余方案在延迟上服务质量有提升,在较小流量下由于flush机制的优化,新架构与其他方案的优势变小。当单节点写入流量较大时(大于170MB)优势明显。

从延迟作业对实时作业的影响方面看:

新缓存架构在测试所涉及的所有场景中,延迟作业都不会对实时作业产生影响,符合预期。

Kafka在美团数据平台承担统一的数据缓存和分发的角色,针对目前由于PageCache互相污染、进而引发PageCache竞争导致实时作业被延迟作业影响的痛点,我们基于SSD自研了Kafka的应用层缓存架构。本文主要介绍Kafka新架构的设计思路以及与其他开源方案的对比。与普通集群相比,新缓存架构具备非常明显的优势:

目前,这套缓存架构优已经验证完成,正在灰度阶段,未来也优先部署到高优集群。其中涉及的代码也将提交给Kafka社区,作为对社区的回馈,也欢迎大家跟我们一起交流。

THE END
1.《操作系统设计与实现:基于LoongArch架构》:带领学生全面剖析操作经过几年的实践,周庆国教授及带领的教学团队在基于LoongArch架构的教学版操作系统MaQueOS为主线进行的教学成果及经验上,成功编著了《操作系统设计与实现:基于LoongArch架构》一书。该书能带领学生全面剖析一个具备基本功能的操作系统内核的设计与https://mp.weixin.qq.com/s?__biz=MzA4MjU5NzkyNA==&mid=2688790552&idx=8&sn=3e6f2ee51c56d8d72aef14f611f5f8c9&chksm=bb97284ffe769772df2fec001ae5a84f65c59ec440b9583b1296ec6fe7c335eefc2edc50ed51&scene=27
2.操作系统设计与实现(豆瓣)大学计算机教育国外著名教材系列(影印版)(共42册), 这套丛书还有 《UNIX网络编程卷2》《计算复杂性》《自动机理论语言和计算导论(第2版影印版)》《数据结构》《分布式系统原理与范型》 等。 喜欢读"操作系统设计与实现"的人也喜欢的电子书· ··· 支持Webhttps://book.douban.com/subject/3108799/
3.操作系统设计与实现(第3版下册)中文PDF版21.8MB电子书下载《操作系统设计与实现(第3版 下册)》是关于操作系统的权威教材,详细探讨了操作系统的基本原理,包括进程、进程间通信、信号量、管程、消息传递、调度算法、输入/输出、死锁、设备驱动程序、存储管理、调页算法、文件系统设计、安全和保护机制等。大多数关于操作系统的图书均重理论而轻实践,而《操作系统设计与实现(第3https://www.jb51.net/books/483826.html
4.操作系统设计与实现第二版中文.pdf操作系统设计与实现(Minix系统中文版).7z 浏览:2 本书是一本操作系统教程,主要写了minix系统的设计和实现以及编译方法 ESP8266 官方全部开发文档资料打包下载 2021最新版 浏览:33 5星 · 资源好评率100% 10. **20b-esp8266_rtos_sdk_api_reference.pdf**:ESP8266实时操作系统(RTOS) SDK API参考文档,包含了EShttps://download.csdn.net/detail/zhilin_tang/7700045
5.《操作系统设计与实现(第三版)(上册)》(AndrewS.Tanenbaum(美当当网图书频道在线销售正版《操作系统设计与实现(第三版)(上册)》,作者:Andrew S. Tanenbaum(美)安德鲁 S. 塔嫩鲍姆 等著,出版社:电子工业出版社。最新《操作系统设计与实现(第三版)(上册)》简介、书评、试读、价格、图片等相关信息,尽在DangDang.com,网购http://product.dangdang.com/23727594.html
6.操作系统设计与实现(第一章引论操作系统概念)《Operating Systems: Design andImplementation Second Edition操作系统设计与实现 (第二版)安德鲁.坦尼鲍姆(Andrew S. Tanenbaum)阿尔伯特.伍德豪尔(Albert S. Woodhull)》 典型的操作系统由四部分构成:进程管理,I/O设备管理,存储器管理和文件管理。 第一章 引论 https://www.jianshu.com/p/3d270296e576
7.操作系统设计与实现:第3版操作系统设计与实现 作者:陈文智 ISBN:9787040467529 出版社:高等教育出版社 出版年:2017 现代操作系统(原书第3版) 作者:(荷)塔嫩鲍姆(Tanenbaum,A.S.)著 出版社:机械工业出版社 出版年:2009 Operating Systems:Design and Implementation 3rd = 操作系统:设计与实现 第三版(影印版) 作者:S.Tanenbaum,Andrehttps://www.las.ac.cn/front/book/detail?id=f5d81099a262db34c86eb97b5587da07
8.操作系统原理实现与实践作者似乎要表达一个意思:一个操作系统,是由它的设计者和用户共同决定的,之前和深信服面试官聊,说到为什么深信服是以用户为中心,面试官说,设计者们只能设计一个框架,细节还需要由用户来填充,这本书就体现了这一点。 作者似乎还想表达一点,操作系统,是附着在计算机硬件上的,所以操作系统的任务是更好地利用硬件,所以https://zhuanlan.zhihu.com/p/658808396
9.操作系统的设计与实现20240406002241.pdf操作系统的设计与实现.pdf,操作系统的设计与实现 一、引言 操作系统是计算机系统的核心部分,负责管理和控制计算机系统的硬 件和软件资源。它负责分配任务、管理内存、处理文件系统、控制设 备驱动程序等。本文将介绍操作系统的设计和实现。 二、操作系统设计 1、需求分析:https://max.book118.com/html/2024/0406/5111140131011134.shtm
10.一个64位操作系统的设计与实现至于软件方面,只要熟练运用汇编语言和C语言就足够编写操作系统了。 汇编语言主要用于控制和配置处理器,例如引导启动处理器、配置处理器运行状态、进程切换、中断和异常处理程序、设备I/O端口操作等必须操作寄存器的工作,或者是对性能要求极为苛刻的场景,这些工作C语言几乎无法实现。 https://www.ituring.com.cn/book/tupubarticle/26322
11.操作系统设计与实现pdf下载操作系统设计与实现第三版p软件介绍软件截图相关文章网友评论下载地址 小编为您推荐:操作系统设计与实现操作系统操作系统设计与实现第三版pdf高清版是计算机科学届非常有名的教材,在这里用户可以通过这本辅导教材,学习详细的操作系统基础知识,以及作者对于操作系统的不同见解,计算机专业的学生必备教材,欢迎有需要的用户来IT猫扑下载! 作者介绍 Andrewhttps://www.itmop.com/downinfo/340861.html
12.操作系统底层架构与内核设计及实现原理51CTO博客这是一段进行相加的操作,程序启动,在经过编译解析后会由操作系统把硬盘中的程序复制到内存中,示例中的程序是将123和456执行相加操作,并将结果输出到显示器上。由于使用机器语言难以描述,所以这是经过翻译后的结果,实际上每个指令和数据都可能分布在不同的地址上,但为了方便说明,把组成一条指令的内存和数据放在了一https://blog.51cto.com/u_11837698/6237152
13.基于Linux操作系统和ARM926EJ系统以CMOS图像通道为诊断网像的传输通道,将采集的超声图像信息送人系统总线,在嵌入式Linux操作系统平台上,实现了诊断图像的实时显示和静态图像的大容量非易失性存储,所实现的诊断系统不仅功能强大、扩展容易,而且还兼顾了小型化的需求。 2、 系统构架 本文设计的便携式超声诊断仪系统结构如图l所示。用户通过输入设备https://m.elecfans.com/article/1179009.html
14.基于Petalinux的Socket网络通信系统设计与实现AET基于Petalinux的Socket网络通信系统设计与实现 摘要:介绍了一款针对MicroBlaze软核处理器特别开发的嵌入式操作系统Petalinux,成功地实现了其在ML402开发板上的移植,并且在该系统上实现了基于TCP/IP协议的套接字接口Socket的网络通信。 关键词:FPGA;MicroBlaze软核处理器;Petalinux移植;Socket网络通信http://www.chinaaet.com/article/188921
15.网络工程专业人才培养方案(2022)3. 工程基础知识。掌握从事网络工程专业所需的数字电路与逻辑设计、计算机组成原理、程序设计、算法与数据结构、软件工程概论、数据库原理与技术等基础知识。 4. 网络工程专业知识。掌握从事网络工程专业所需的计算机网络原理与技术、操作系统、信息安全导论、物联网技术基础、网络安全技术、网络互连技术、无线网络技术、网https://www.csust.edu.cn/jtxy/info/1148/20900.htm