Kafka【五】Buffer Cache (缓冲区缓存)、Page Cache (页缓存)和零拷贝技术

news2024/12/24 2:16:55

【1】Buffer Cache (缓冲区缓存)

在Linux操作系统中,Buffer Cache(缓冲区缓存)是内核用来优化对块设备(如磁盘)读写操作的一种机制(故而有一种说法叫做块缓存)。尽管在较新的Linux内核版本中,Buffer CachePage Cache已经被整合在一起,但在理解历史背景和功能时,了解Buffer Cache仍然很有帮助。

Buffer Cache 的历史和定义

传统的Buffer Cache主要用于缓存块设备上的数据块,包括文件系统的元数据和数据本身。它的主要目的是提高对块设备的读写性能,减少磁盘I/O操作,从而提升系统整体性能。

Buffer Cache 的用途

  1. 数据缓存

    • 当数据被读取或写入块设备时,Buffer Cache会将这些数据暂时存储在内存中,以备后续快速访问。
    • 这样做的好处是,当应用程序再次请求相同的数据时,可以直接从Buffer Cache中获取,而不需要重新从磁盘读取,从而节省了I/O操作的时间。
  2. 元数据缓存

    • Buffer Cache还会缓存文件系统的元数据,如节点(node),这些元数据包含了文件的基本信息,如文件大小、权限、时间戳等。
    • 缓存元数据可以加速文件系统的操作,因为文件系统的许多操作都需要访问这些元数据。

Buffer Cache 的实现

  1. 缓存管理

    • 内核通过一系列的数据结构和算法来管理Buffer Cache,确保高效地利用有限的内存资源。
    • 内核会根据内存使用情况和缓存策略自动决定哪些数据应该保留在缓存中,哪些数据应该被淘汰。
  2. 缓存替换策略

    • 内核使用了一定的缓存替换策略来决定何时将数据从Buffer Cache中移除。
    • 通常采用的是最近最少使用(LRU, Least Recently Used)算法或类似算法,以确保经常使用的数据能够被保留。

Buffer Cache 的示例

假设一个应用程序需要读取一个文件的内容:

  1. 首次读取

    • 应用程序请求读取文件的一部分。
    • 内核检查Buffer Cache中是否有请求的数据。
    • 如果没有找到,则从磁盘读取数据,并将其放入Buffer Cache中。
  2. 后续读取

    • 下次应用程序再次请求读取同一部分数据时,内核会直接从Buffer Cache中获取数据,而不需要访问磁盘。

现代Linux内核的变化

在较新的Linux内核版本中,Buffer CachePage Cache已经被整合为统一的缓存机制,称为Unified Buffer Cache。这种整合旨在更好地利用内存资源,并提高整体的缓存效率。

统一缓存机制的优点

  • 资源共享:统一后的缓存机制可以更好地共享内存资源,避免了传统缓存机制中可能出现的内存碎片问题。
  • 性能优化:统一缓存机制可以根据实际情况动态调整缓存策略,从而提高缓存的命中率和整体性能。
  • 简化管理:统一缓存机制简化了内核的缓存管理逻辑,使得内核更加简洁高效。

总结

尽管Buffer Cache作为一个单独的概念在较新的Linux内核版本中已经不再单独存在,但它所代表的缓存机制仍然是提高系统性能的重要手段之一。通过缓存块设备上的数据和元数据,Buffer Cache能够显著减少磁盘I/O操作,提高文件系统的读写性能。在现代Linux内核中,这种缓存机制已经被整合到统一的缓存机制中,以更好地适应现代计算环境的需求。

【2】Page Cache (页缓存)

页缓存是操作系统实现的一种主要的磁盘缓存,以此用来减少对磁盘I/O的操作。具体来说,就是把磁盘中的数据缓存到内存中,把对磁盘的访问变为对内存的访问。为了弥补性能上的差异 ,现代操作系统越来越多地将内存作为磁盘缓存,甚至会将所有可用的内存用于磁盘缓存,这样当内存回收时也几乎没有性能损失,所有对于磁盘的读写也将经由统一的缓存。

当一个进程准备读取磁盘上的文件内容时,操作系统会先查看待读取的数据所在的页(page)是否在页缓存(page cache)中,如果存在(命中)则直接返回数据,从而避免了对物理磁盘I/O操作;如果没有命中,则操作系统会向磁盘发起读取请示并将读取的数据页写入页缓存,之后再将数据返回进程。

同样,如果一个进程需要将数据写入磁盘,那么操作系统也会检测数据对应的页是否在页缓存中,如果不存在,则会先在页缓存中添加相应的页,最后将数据写入对应的页。被修改过后的页也就变成了脏页,操作系统会在合适的时间把脏页中的数据写入磁盘,以操作数据的一致性。

对一个进程页言,它会在进程内部缓存处理所需的数据,然而这些数据有可能还缓存在操作系统的页缓存中,因此同一份数据有可能被缓存了2次。并且,除非使用Direct I/O的方式,否则页缓存很难被禁止。

Kafka中大量使用了页缓存,这是Kafka实现高吞吐的重要因此之一。虽然消息都是先被写入页缓存,然后由操作系统负责具体的刷盘任务,但在Kafka中同样提供了同步刷盘及间断性强制刷盘(fsync)的功能,这些功能可以通过log.flush.interval.message、log.flush.interval.ms等参数来控制。同步刷盘可以提高消息的可靠性,防止由于机器掉电等异常造成处于页缓存而没有及时写入磁盘的消息丢失。不过一般不建议这么做,刷盘任务就应交由操作系统去调配,消息的可靠性应该由多副本机制来保障,而不是由同步刷盘这种严重影响性能的行为来保障。

【3】page cache与buffer cache区别

在Linux操作系统中,page cachebuffer cache都是内核用来缓存数据的机制,但它们有不同的目的和工作原理。下面是这两种缓存的具体区别:

Page Cache (页缓存)

  • 定义:Page cache 是 Linux 内核用于缓存文件系统数据的一种机制。它主要用来缓存文件的内容,即文件中的数据块
  • 用途:Page cache 的主要目的是提高文件读写操作的性能。当一个文件被频繁访问时,它的数据会被缓存到内存中,这样后续对该文件的访问就可以直接从内存中读取,而不是每次都从磁盘读取,从而加快了访问速度。
  • 位置:Page cache 存储在内存中的页面(page)中,每个页面大小通常是 4KB 或者更大(取决于系统配置)。
  • 实现:Page cache 通过虚拟内存系统实现,当文件数据被读取时,内核会将数据映射到虚拟内存的页面上。
  • 示例:当应用程序读取一个文件时,内核会检查 page cache 中是否有该文件的数据;如果有,则直接从 page cache 中返回数据;如果没有,则从磁盘读取数据并放入 page cache。

Buffer Cache (缓冲区缓存)

  • 定义:Buffer cache 是 Linux 内核用于缓存块设备上的数据的一种机制。它主要用于缓存块设备(如磁盘)上的元数据(如节点)和数据块
  • 用途:Buffer cache 的主要目的是提高对块设备的读写性能。它不仅可以缓存文件的数据块,还可以缓存文件系统的元数据(如文件权限、大小等),从而加速文件系统的操作。
  • 位置:Buffer cache 存储在内存中的缓冲区中,每个缓冲区的大小通常是固定大小,通常是 512 字节到几 KB 不等。
  • 实现:Buffer cache 通过内核的缓冲区管理器实现,当数据被读取或写入块设备时,内核会将数据放入 buffer cache 中。
  • 示例:当应用程序需要访问一个文件的元数据时,内核会检查 buffer cache 中是否有该元数据;如果有,则直接从 buffer cache 中返回数据;如果没有,则从磁盘读取数据并放入 buffer cache。

区别总结

  • 缓存的对象

    • Page cache:主要用于缓存文件的内容。
    • Buffer cache:主要用于缓存块设备上的数据块和元数据。
  • 数据单位

    • Page cache:以页面(page)为单位,通常每个页面大小为 4KB。
    • Buffer cache:以缓冲区(buffer)为单位,每个缓冲区的大小较小,通常是 512 字节到几 KB。
  • 缓存范围

    • Page cache:专门针对文件系统的缓存,用于加速文件读写操作。
    • Buffer cache:不仅缓存文件数据,还缓存文件系统的元数据,用于加速文件系统操作。
  • 缓存策略

    • Page cache:侧重于文件数据的缓存。
    • Buffer cache:侧重于块设备上的数据缓存,包括文件系统的元数据。

近期变化

值得注意的是,在较新的 Linux 内核版本中,buffer cache 和 page cache 已经合并到了一起,统一称为 generic buffer cache 或者 unified buffer cache。这意味着现在这两种缓存机制已经整合在一起,共享内存资源,从而更好地利用内存并提高整体性能。

总的来说,page cache 和 buffer cache 虽然在早期有明显的区分,但在现代 Linux 内核中,这两者已经趋于整合,共同服务于提高文件系统和块设备的读写性能。

块设备上的数据块与文件内容
.
在块设备上的数据块确实包含了文件的内容。因此,从某种意义上说,Buffer Cache确实缓存了文件的内容。然而,在传统意义上,Buffer Cache更侧重于缓存元数据,而Page Cache更侧重于缓存文件的内容。

【4】零拷贝

“零拷贝”(Zero-copy)是一种计算机编程技术,旨在减少数据从一个位置传输到另一个位置时的数据复制次数,从而提高性能。零拷贝技术的核心思想是尽可能减少数据在不同内存区域之间的复制操作,尤其是减少数据在用户空间和内核空间之间的复制。这种方法可以显著提高数据传输的效率,尤其是在涉及大量数据传输的应用中。

零拷贝的背景

在传统的数据传输过程中,数据通常需要在用户空间(应用程序所在的内存区域)和内核空间(操作系统内核所在的内存区域)之间多次复制。例如,当应用程序读取磁盘上的数据并通过网络发送时,数据可能会经历以下过程:

  1. 从磁盘读取数据到内核空间的缓冲区。
  2. 将数据从内核空间复制到用户空间的缓冲区。
  3. 将数据从用户空间的缓冲区复制回内核空间的网络发送缓冲区。
  4. 最终通过网络发送出去。

这种多次复制不仅消耗CPU资源,还增加了系统的延迟。

零拷贝的技术实现

零拷贝技术通过减少这些不必要的复制操作来提高性能。以下是几种常见的零拷贝技术实现:

1. 直接 I/O

  • 定义:直接 I/O(Direct I/O)允许应用程序直接从磁盘读取数据到用户空间,绕过内核缓冲区。
  • 系统调用:Linux 中的 open() 函数可以使用 O_DIRECT 标志打开文件,然后通过 read()write() 系统调用直接读写数据。
  • 优点:减少数据在内核缓冲区和用户空间之间的复制。

2. mmap

  • 定义:mmap(memory-mapped file)允许应用程序直接映射文件到内存地址空间,从而可以直接访问文件内容。
  • 系统调用:使用 mmap() 系统调用来映射文件到内存。
  • 优点:数据可以直接在内存中访问,无需复制到用户空间。

3. sendfile

  • 定义:sendfile 系统调用允许数据直接从一个文件描述符传输到另一个文件描述符,而不需要复制到用户空间。
  • 系统调用:Linux 中的 sendfile() 系统调用可以将数据从一个文件描述符(如磁盘文件)传输到另一个文件描述符(如网络套接字)。
  • 优点:数据可以直接从内核缓冲区传输到网络缓冲区,减少数据复制。

4. splice

  • 定义:splice 系统调用允许数据在两个文件描述符之间直接传输,而不需要经过用户空间。
  • 系统调用:使用 splice() 系统调用可以将数据从一个文件描述符传输到另一个文件描述符。
  • 优点:适用于 Linux 2.6 及以上版本,可以实现高效的数据传输。

零拷贝的应用场景

零拷贝技术广泛应用于需要高效数据传输的应用场景中,包括但不限于:

  • 网络服务器:Web 服务器、数据库服务器等需要高效处理大量数据传输的场景。
  • 高性能计算:科学计算、大数据处理等需要高速数据传输的应用。
  • 嵌入式系统:资源受限的设备中,零拷贝技术可以显著提高数据处理能力。

总结

零拷贝技术通过减少数据在用户空间和内核空间之间的复制次数,提高了数据传输的效率,减少了CPU资源的消耗。在现代操作系统中,通过各种系统调用和技术实现了零拷贝,使得数据传输更为高效。了解和使用零拷贝技术对于提高应用程序的性能具有重要意义。

【5】kafka中的零拷贝

kafka的高性能是多方面协同的结果,包括宏观架构、分布式partition存储、ISR数据同步、以及“无所不用其极”的高效利用磁盘/操作系统特性。其中零拷贝并不是不需要拷贝,通常是说在IO读写过程中减少不必要的拷贝次数。
在这里插入图片描述

这里我们要说明是,内核在执行操作时同一时间点只会做一件事,比如Java写文件这个操作,为了提高效率,这个操作是分为3步:

  • 第一步java将数据写入自己的缓冲区,
  • 第二步java需要写入数据的磁盘页可能就在当前的页缓存(Page Cache)中,所以java需要将自己的缓冲区的数据写入操作系统的页缓存(Page Cache)中。
  • 第三步操作系统会在页缓存数据满了后,将数据实际刷写到磁盘文件中。

在这个过程,Java Application数据的写入和页缓存的数据刷写对于操作系统来讲是不一样的,可以简单理解为,页缓存的数据刷写属于内核的内部操作,而用于启动的应用程序的数据操作属于内核的外部操作,权限会受到一定的限制。

所以内核在执行不同操作时,就需要将不同的操作环境加载到执行空间中,

  • 也就是说,当java想要将数据写入页缓存时,就需要调用用户应用程序的操作,这就是用户态操作。
  • 当需要将页缓存数据写入文件时,就需要中断用户用用程序操作,而重新加载内部操作的运行环境,这就是内核态操作。

可以想象,如果存在大量的用户态和内核态的切换操作,IO性能就会急剧下降。所以就存在零拷贝操作,减少用户态和内核态的切换,提高效率。Kafka消费者消费数据以及Follower副本同步数据就采用的是零拷贝技术。

在这里插入图片描述

【6】补充:Linux中用户态、内核态、用户空间、内核空间、用户缓冲区、内核缓冲区

在Linux操作系统中,用户态(User Mode)和内核态(Kernel Mode)以及用户空间(User Space)和内核空间(Kernel Space)是操作系统中非常重要的概念。这些概念区分了操作系统中的不同执行环境和内存区域。下面详细解释这些概念及其相互关系:

1. 用户态(User Mode) vs 内核态(Kernel Mode)

  • 用户态(User Mode)

    • 定义:用户态是指应用程序运行的模式。在这种模式下,程序只能访问受限制的系统资源,并且只能执行一部分系统调用。
    • 安全:用户态的设计是为了保护系统的稳定性和安全性,防止应用程序直接访问硬件或执行潜在危险的操作。
    • 权限:用户态下的程序没有直接访问硬件的权限,也不能执行敏感的系统调用。
  • 内核态(Kernel Mode)

    • 定义:内核态是指操作系统内核运行的模式。在这种模式下,内核可以访问所有系统资源,并执行任何操作。
    • 权限:内核态下的代码拥有最高权限,可以直接访问硬件、修改内存等。
    • 切换:应用程序通过系统调用(如readwriteopen等)从用户态切换到内核态,执行完相应的操作后再切换回用户态。

2. 用户空间(User Space) vs 内核空间(Kernel Space)

  • 用户空间(User Space)

    • 定义:用户空间是指应用程序运行所在的内存区域。在这个区域内,应用程序只能访问自己分配的内存和其他受保护的资源。
    • 权限:用户空间内的程序不能直接访问内核空间的内存或其他资源。
    • 隔离:用户空间提供了应用程序之间的隔离,防止一个应用程序错误影响其他应用程序。
  • 内核空间(Kernel Space)

    • 定义:内核空间是指操作系统内核运行所在的内存区域。在这个区域内,内核可以访问所有的内存资源和硬件。
    • 权限:内核空间内的代码拥有最高权限,可以直接访问硬件、修改内存等。
    • 资源管理:内核空间负责管理系统的资源,如内存、进程、文件系统等。

3. 用户缓冲区(User Buffer) vs 内核缓冲区(Kernel Buffer)

  • 用户缓冲区(User Buffer)

    • 定义:用户缓冲区是指应用程序在用户空间中分配的缓冲区,用于临时存储数据。
    • 用途:用户缓冲区通常用于应用程序读取或写入数据时的临时存储。
    • 访问:内核不能直接访问用户缓冲区中的数据,必须通过特定的机制(如系统调用)进行数据交换。
  • 内核缓冲区(Kernel Buffer)

    • 定义:内核缓冲区是指内核在内核空间中分配的缓冲区,用于临时存储数据。
    • 用途:内核缓冲区通常用于内核内部的数据处理,如文件系统的缓存、网络数据包的处理等。
    • 访问:内核可以直接访问内核缓冲区中的数据,而应用程序则不能直接访问内核缓冲区。

总结

  • 用户态内核态区分了程序运行的不同模式,前者受到限制,后者拥有最高权限。
  • 用户空间内核空间区分了内存的不同区域,前者应用程序运行所在,后者内核运行所在。
  • 用户缓冲区内核缓冲区区分了数据存储的不同区域,前者位于用户空间,后者位于内核空间。

通过这些区分,Linux操作系统能够有效地管理资源,保证系统的稳定性和安全性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud全解析:熔断之Hystrix服务监控

Hystrix服务监控 Hystrix除了熔断降级之外,还提供了准实时的调用监控,持续的记录所有通过Hystrix发起的请求的执行信息,并以统计报表的形式展示出来,包括有每秒执行多少请求,多少成功,多少失败等&#xff…

【C++】vector类:模拟实现(适合新手手撕vector)

在实现本文的vector模拟前,建议先了解关于vector的必要知识:【C】容器vector常用接口详解-CSDN博客https://blog.csdn.net/2301_80555259/article/details/141529230?spm1001.2014.3001.5501 目录 一.基本结构 二.构造函数(constructor&…

【算法】位运算

【ps】本篇有 10 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1)位1的个数 .1- 题目解析 .2- 代码编写 2)比特位计数 .1- 题目解析 .2- 代码编写 3)汉明距离 .1- 题目解析 .2- 代码编写 4)只出现一次的数字 .…

3000字带你了解SD提示词用法,一点就通,小白轻松上手(附提示词生成器)(1.4 SD提示词运用)

提示词是什么 提示词是我们向AI模型发出的指令。正确的提示词能让AI准确反馈所需的输出,而优质的提示词则能使AI生成的内容更优质、更符合你的期望。这与编写程序代码颇为相似,准确的代码逻辑是程序正常运行的前提,而优秀的代码则能减少运行…

知识付费小程序源码轻松实现一站式运营,开启知识变现之旅

技术栈: 以下是一个简单的知识付费小程序的示例代码: app.js:小程序的入口文件 App({onLaunch: function () {// 在小程序启动时执行的代码},globalData: {// 存储全局数据userInfo: null // 用户信息} })pages/index/index.js&#xff1…

【学术会议征稿】第四届智能电网与能源互联网国际会议(SGEI 2024)

第四届智能电网与能源互联网国际会议(SGEI 2024) 2024 4th International Conference on Smart Grid and Energy Internet 为交流近年来国内外在智能电网和能源互联网领域的理论、技术和应用的最新进展,展示最新成果,由沈阳工业…

Visual Studio 2022 下载和安装

文章目录 概述一,下载步骤二,安装过程 概述 Visual Studio 提供 AI 增强功能,例如用于上下文感知代码补全的 IntelliSense 和可利用开源代码中的 AI 模式的 IntelliCode。 集成的 GitHub Copilot 提供 AI 支持的代码补全、聊天辅助、调试建议…

ElasticSearch学习笔记(三)RestClient操作文档、DSL查询文档、搜索结果排序

文章目录 前言5 RestClient操作文档5.4 删除文档5.4 修改文档5.5 批量导入文档 6 DSL查询文档6.1 准备工作6.2 全文检索查询6.3 精准查询6.4 地理坐标查询6.5 复合查询6.5.1 相关性算分6.5.2 布尔查询 7 搜索结果处理7.1 排序7.1.1 普通字段排序7.1.2 地理坐标排序 前言 Elast…

qmt量化交易策略小白学习笔记第59期【qmt编程之期权数据--获取指定期权品种的详细信息--原生Python】

qmt编程之获取期权数据 qmt更加详细的教程方法,会持续慢慢梳理。 也可找寻博主的历史文章,搜索关键词查看解决方案 ! 基于BS模型计算欧式期权理论价格 基于Black-Scholes-Merton模型,输入期权标的价格、期权行权价、无风险利率…

Mac 安装Hadoop教程(HomeBrew安装)

1. 引言 本教程旨在介绍在Mac 电脑上安装Hadoop,便于编程开发人员对大数据技术的熟悉和掌握。 2.前提条件 2.1 安装JDK 想要在你的Mac电脑上安装Hadoop,你必须首先安装JDK。具体安装步骤这里就不详细描述了。你可参考Mac 安装JDK8。 2.2 配置ssh环境…

从腰子的营养成分来分析腰子能否“壮阳”,健康地吃腰子。

文章目录 引言I 腰子的营养优点缺点吃腰子无“壮阳”效果II 健康地吃腰子食用前充分清洗浸泡高尿酸及痛风群体慎吃适量吃引言 很多人认为动物内脏有着“以形补形”的好处,如吃动物腰子,能补肾、壮阳,这让很多人对“腰子”非常热爱。 腰子的营养到底如何?经常吃腰子对身体…

优思学院:FMEA与FTA故障树方法对比:工程师必须知道的关键点!

故障树分析(Fault Tree Analysis, FTA)以某个不希望发生的产品故障事件或严重的系统风险(即顶事件)为分析对象,通过自上而下的分层次因果逻辑分析,逐步找出导致故障事件的必要且充分的直接原因,…

日程安排组件DHTMLX Scheduler v7.1 - 支持RFC-5545格式

DHTMLX Scheduler是一个类似于Google日历的JavaScript日程安排控件,日历事件通过Ajax动态加载,支持通过拖放功能调整事件日期和时间,事件可以按天、周、月三个种视图显示。 此版本包括几个备受期待的特性,可以帮助用户增强DHTMLX…

基于php+vue+uniapp的医院预约挂号系统小程序

开发语言:PHP框架:phpuniapp数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:PhpStorm 系统展示 后台登录界面 管理员功能界面 用户管理 医生管理 科室分类管理 医生信息管理 预…

30s到0.8s,记录一次接口优化成功案例!

大家好,我是沐子,推荐一个程序员免费学习的编程网站 我爱编程网(www.love-coding.com) ** 场景** 在高并发的数据处理场景中,接口响应时间的优化显得尤为重要。本文将分享一个真实案例,其中一个数据量达到…

(5) 归并排序

归并排序 归并排序是一种分治策略的排序算法。它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列。 归并排序首先由著名的现代计算机之父 John_von_Neumann 在 1945 年发明,被用在了 E…

【Python】Python 读取Excel、DataFrame对比并选出差异数据,重新写入Excel

背景:我在2个系统下载出了两个Excel,现在通过对下载的2个Excel数据,并选出差异数据 从新写入一个新的Excel中 differences_url rC:\Users\LENOVO\Downloads\differences.xlsx; //要生成的差异Excel的位置及名称 df1_url rC:\Users\LENOVO\Dow…

终于知道如何简化时间序列的特征工程了!

在处理时间序列数据时,时间特征往往是最基础且独特的要素,我们的目标通常是预测某种未来的响应或结果。 不过在很多情况下,除了时间特征之外,我们还能获取到一系列其他相关的特征或变量。 时间序列数据中的特征工程涉及从原始时…

进程、线程、时间片

1、操作系统中的程序(如微信)在运行时,系统会产生一个或多个进程,往往是一个 2、进程内可以包含多个线程,有一个主线程,主线程结束时,进程结束,进而程序结束 3、线程是cpu调度执行…

sql日期函数

目录 sql日期函数 1.获取日期时间函数 1.1 获取当前日期时间 1.2 获取当前日期 1.3 获取当前时间 2.datetime数据类型格式化 3.字符串数据类型转换成datetime数据类型 4.增加和减少时间间隔 5. 日期相差天数(天) 6. 相差时间(小时&am…