深入拆解消息队列 47 讲
许文强
前腾讯云 Kafka 技术负责人
5385 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
深入拆解消息队列 47 讲
15
15
1.0x
00:00/00:00
登录|注册

06|存储:如何提升存储模块的性能和可靠性?

你好,我是文强。
上一节我们讲了消息队列存储模块的功能实现,今天我们来讲存储模块的性能优化。
存储模块的性能优化,核心要解决的其实就是两个问题:“写得快”和“读得快”。这两个问题如何解决呢?我们从四点和存储性能优化有关的基础理论讲起。
内存读写的效率高于硬盘读写
批量读写的效率高于单条读写
顺序读写的效率高于随机读写
数据复制次数越多,效率越低

提升写入操作的性能

上一节我们讲到,消息队列的数据最终是存储在文件中的,数据写入需要经过内存,最终才到硬盘,所以写入优化就得围绕内存和硬盘展开。写入性能的提高主要有缓存写、批量写、顺序写三个思路,这里对比来讲。

1. 缓存写和批量写

在计算机理论基础中,计算机多级存储模型的层级越高,代表速度越快(同时容量也越小,价格也越贵),也就是说写入速度从快到慢分别是:寄存器 > 缓存 > 主存 > 本地存储 > 远程存储。
所以基于理论 1 和 2:
内存读写的效率高于硬盘读写
批量读写的效率高于单条读写
写入优化的主要思路之一是:将数据写入到速度更快的内存中,等积攒了一批数据,再批量刷到硬盘中。
平时我们在一些技术文章看到的“数据先写入 PageCache,再批量刷到硬盘”,说的就是这个思路。PageCache 指操作系统的页缓存,简单理解就是内存,通过缓存读写数据可以避免直接对硬盘进行操作,从而提高性能。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了存储模块的性能优化和可靠性提升的关键理论和实践方法。在存储模块的性能优化方面,主要涉及写入操作和读取操作的优化策略。针对写入操作,文章介绍了缓存写、批量写和顺序写等策略,以及同步刷盘、WAL预写日志和多副本备份等手段,以提升写入性能和可靠性。对于读取操作,文章提到了读热数据、顺序读、批量读和零拷贝等思路,通过内存缓存和预读机制来提高读取性能。此外,还探讨了硬件和系统优化对性能提升的影响。总的来看,本文全面探讨了存储模块性能优化和可靠性提升的关键方法,对于存储系统的设计和性能优化具有重要的参考意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解消息队列 47 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(10)

  • 最新
  • 精选
  • 张申傲
    本篇的内容是可以复用到大多数系统中的通用优化方案,包括缓存、顺序I/O、WAL机制、Batch机制等等。 请教下强哥: 1. WAL日志一般也需要一些清理机制吧,不然日志逐渐膨胀可能也会影响磁盘IO。比如MySQL的redo log是类似Ring Buffer结构的固定大小的文件,写满后会直接覆盖;而Redis的aof日志是用的rewrite机制来做compact。那么Pulsar是如何处理WAL日志过大的问题呢? 2. 热读的缓存命中率一般会有监控吗?如果有是怎么做的呢?

    作者回复: 1. 是的,需要清理机制,不然数据会一直膨胀。从清理机制上来看,可以是按照时间删除的机制。因为在当前消息队列场景中,WAL的一个作用就是用来做数据丢失的recover。需要recover的数据是写入PageCache,但是还没有写入到硬盘的数据。这部分数据一般不大,而且持续的时间也很短。比如我们配置了异步刷盘,每秒刷一次,理论上我们WAL的数据只需要保留最近1s。 但是一般wal还会用来将随机写转为顺序写的功能。 所以,时间一般是根据自己的架构来设置的。 2. 可以监控的。热读的监控主要是监控pageCache的使用。 所以,你可以用linux 的sar命令来监控PageCache。

    2023-07-04归属地:北京
    4
  • Geek_0710c9
    WAL 的 讲解感觉不太对,WAL 主要的作用是把随机写转为顺序写,主要用在采用 b+树作为存储结构的数据库中,比如 mysql 。 现代的 mq(例如 kafka) 和数据库 (例如 tidb,底层数据 rocksdb ),采用 LSM SSTable 结构进行数据存储,本身就是采用追加的形式,顺序写能力强劲,不需要 WAL

    作者回复: 在我看来,WAL主要有两个功能: 1. 随机写转为顺序写,提高写入效率。 2. 防止数据丢失,在系统异常的时候用来恢复数据,当checkpoint用的。 因为MQ本身是顺序写的,所以1作用不是特别大。 文章是在可靠性部分讲到了WAL,是为了保证数据的不丢失,可恢复的。

    2023-07-04归属地:河北
    2
    3
  • Geek_3a2d3a
    有没有实战的案例,光讲不实战感觉有点生疏

    编辑回复: 这门课的定位实战偏少,主要是从消息队列的底层原理和设计思路出发的,哪里觉得收获感不足可以进一步向讲师提问哦~感谢建议!

    2023-07-17归属地:湖北
    1
  • 康伯德
    老师,请教一下问题,为什么Linux的普通拷贝不用零拷贝,比如sendfile,如果mmap我还理解,毕竟需要建立映射,但sendfile呢?总比普通拷贝要好吧

    作者回复: 你好啊,这个问题我说一下我自己的理解。 在我看来,零拷贝指的是数据在内核空间和用户空间之间的拷贝次数为0。所以在我看来它是一个概念,不是一门具体的技术。 sendfile 作用是在两个文件描述符中直接传递数据,数据传递全部在内核完成,不经过内核空间。所以严格意义上来说它就是零拷贝的一种实现。 从业务的角度,如果要通过零拷贝的概念来提高性能,还得配合dma技术,来实现直接把数据从readbuffer发送到网卡设备,从而提高性能。 所以,sendfile 可以理解就是零拷贝。

    2023-07-24归属地:北京
  • 3.0的A7
    WAL的方式,如果WAL写入就失败的话,是不是这个消息算生产失败了?

    作者回复: 是的,所以这里在编码层面需要考虑这个问题。通过编码技巧来解决这个问题。正常的思路是先WAL,再写数据。 如果为了提升并发度,那么就得在编码层面做很多recover的措施。比如wal写入失败,消息数据写入成功时,如何处理。

    2023-07-05归属地:北京
  • 文敦复
    1. 对于零拷贝而言,这里的零指的应该是内核态到用户态之间的零次吧? 实际上还是有2次的,硬盘 -> 内核 -> 网卡 2. DMA,sendfile,MMAP 都是实现零拷贝的手段? 这样理解对不对?

    作者回复: 1. 是的,就是指内核态到用户态之间的拷贝次数是零次。 2. 是的,零拷贝只是一个概念。DMA,sendfile,MMAP 都是实现零拷贝的手段。

    2023-07-03归属地:四川
  • 文敦复
    对于统一的日志文件和每个分区各自的日志文件对比而言。 1.统一的日志文件,写强(顺序写),读弱(不同分区可能存在在文件不同的位置,为随机读) 2.每个分区独立的日志文件,读强(可以顺序预读),但是写弱(文件分散随机写) 大概是这个意思吧?

    作者回复: 第一点没问题。 第二点的准确描述是,在大部分情况下,是读强 + 写强。 只有在某些极端场景,分区数很多 + 每个分区都同时在读写的时候,就会降低读和写的性能。因为在硬盘层面,大量的多个文件的读写,就会造成随机读写。 这种极端场景,在业务中遇到的概率相对较低一些。

    2023-07-03归属地:四川
  • shan
    总结 写入操作性能提升方式 1. 缓存写和批量写 将数据先写入操作系统页缓存PageCache中(缓存写),积攒一批数据后刷到硬盘中,一般消息队列会提供是否同步刷盘、刷盘的时间周期、刷盘的空间比例三个配置项,根据配置来决定何时刷盘。 2. 顺序写 对于单文件顺序写比较简单,多文件写入硬盘,硬盘控制器需要同时控制多个数据的写入,从硬盘角度看是随机写。所以随机写还是顺序写依赖消息队列的存储结构设计,比如RocketMQ将每个消息队列的数据都存储到一个CommitLog文件就可以实现顺序写。 读取操作性能提升方式 1. 热读:数据进行预热,将数据先从硬盘读取到内存中; 2. 顺序读、随机读、批量读:还是依赖于数据预读,分为硬盘层面预读和应用程序的预读。 硬盘层面预读依赖数据的存储结构设计。 应用程序的预读,提前通过调度去硬盘读取数据(可能是连续的也可能是不连续的)。 3. 零拷贝:通过减少数据的拷贝次数、减小上下文切换来提升读取性能,比如RocketMQ使用mmap方式来提高CommitLog的读写性能; 硬件和系统优化提升性能 1. 提升硬件配置:比如配备更大的机器内存; 2. 配置多盘读写:通过在机器上挂多块硬盘提升单机的硬盘吞吐能力; 3. 配置RAID和LVM硬盘阵列,串联多块盘提升硬盘的性能和吞吐能力; 数据可靠性保证 (1)同步刷盘:数据写入后立刻调用force()操作完成数据刷盘,效率会比较低。 (2)WAL(预写日志):写数据之前先写日志,当出现数据丢失时通过日志来恢复数据,避免数据丢失。 (3)多副本备份:将数据拷贝到多台节点,通过分布式的多副本存储来保证数据的高可靠。 方案一所有产品都会支持,方案二和方案三一般会选一种支持,Kakfa、RabbitMQ、RocketMQ 用的是第三种,Pulsar 用的是第二种。
    2023-09-15归属地:河南
  • takumi
    多副本备份是写入到内存,但是内存一般都是易失性存储,如果当节点重启的时候,数据就没了,是否可以通过写入到磁盘上保证可靠性?
    2023-08-10归属地:上海
  • cykuo
    mmp使用了内存映射,在read的时候减少了一次内存拷贝,但是最后write的时候不还是拷贝了一次么?
    2023-07-06归属地:北京
    1
收起评论
显示
设置
留言
10
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部