网络io和磁盘io_在磁盘IO上,第1部分:IO的风味

网络io和磁盘io

10月,我将在纽约参加O'Reilly Velocity会议,并发表“当我们谈论磁盘IO时我们谈论的话题”的演讲 。 我决定将我的一些准备笔记发布为一系列博客文章。

了解IO的工作原理,使用哪种算法以及在什么情况下可以改善开发人员和操作员的生活:他们将能够预先做出更好的选择(基于他们所评估的数据库所使用的内容),进行故障排除数据库行为不当(通过将其工作负载与打算使用数据库堆栈的工作负载进行比较)并调整其堆栈(通过分散负载,切换到不同的磁盘类型,文件或操作系统或仅选择文件)时的性能问题不同的索引类型)。

根据Wikipedia的IO风味

尽管经常讨论和讨论网络IO,但文件系统IO却很少受到关注。 当然,在现代系统中,人们通常将数据库用作存储手段,因此应用程序通过网络上的驱动程序与它们进行通信。 我认为了解数据如何写入磁盘并从磁盘读回仍然很重要。 此外,网络IO还有更多的要讨论的内容以及实现不同事物的方式,这在一个操作系统与另一个操作系统之间是非常不同的,而文件系统IO的工具集要少得多。

IO有多种“特色”(为简洁起见,一些功能被省略):

今天,我们将讨论标准IO与一系列“用户态”优化的结合。 在大多数情况下,应用程序开发人员都在使用它,并在此之上加上几个不同的标志。 让我们开始吧。

缓冲IO

在谈论stdio.h函数时,在“缓冲”方面存在一些混乱,因为它们自己进行一些缓冲。 使用标准IO时,可以在全缓冲和行缓冲之间进行选择,也可以从任何缓冲中退出 。 这种“用户空间”缓冲与内核后面的缓冲无关。 您还可以考虑将“缓冲”和“缓存”区分开来,这应该使概念不同且直观。

磁盘(HDD,SSD)称为块设备 ,其上最小的可寻址单元称为扇区:不可能传输小于扇区大小的数据量。 同样,文件系统的最小可寻址单元是一个 (通常大于扇区)。 块大小通常小于(或等于) 页面大小 (概念来自虚拟内存)。

我们试图在磁盘上处理的所有内容最终都被加载到RAM中,最有可能由操作系统在两者之间进行缓存。

页面缓存

页面缓存 (以前是完全分开的,缓冲区缓存和页面缓存在2.4 Linux内核中是统一的 帮助保持缓存更可能在最近的时间访问的缓冲区。 时间局部性原则意味着读取的页面将在短时间内访问多次,而空间局部性则意味着相关元素很可能彼此靠近,因此保存数据以进行摊销是有意义的。 IO成本。 为了提高IO性能,内核通过延迟写入和合并相邻的读取在内部缓冲数据。

页面缓存不一定包含整个文件(尽管肯定会发生)。 根据文件大小和访问模式,仅最近访问的块。 由于所有IO操作都是通过Cache发生的,因此诸如读写操作之类的操作序列可以完全从内存中获取,而无需访问磁盘上的(同时过时的)数据。

执行读取操作时,将首先查询页面缓存。 如果数据已经可以在页面缓存中找到,则将其复制给用户。 否则,它将从磁盘加载并存储在页面缓存中以供进一步访问。 执行操作时,页面将首先写入高速缓存,并在高速缓存中标记为脏。

标记为脏的页面(由于其缓存的表示形式现在与持久的页面不同)将被刷新到磁盘。 此过程称为writeback 。 当然,回写有其自身的潜在弊端,例如排队过多的IO请求,因此值得了解使用回写时使用的阈值和比率,并检查队列深度以确保可以避免节流和高延迟。

延迟错误

在执行由内核和/或库缓冲区支持的写操作时,确保数据实际到达磁盘非常重要,因为它可能会缓存或缓存在某处。 当数据刷新到磁盘时(可能是在同步或关闭文件时),将出现错误。

直接IO

O_DIRECT是打开文件时可以传递的标志。 它指示操作系统绕过页面缓存。 这一切都意味着对于使用Direct IO的“传统”应用程序,很可能会导致性能下降而不是加速。

内核开发人员常常不赞成使用Direct IO,而且到目前为止,Linux手册页还引用了Linus Torwalds:“ 关于O_DIRECT一直困扰我的是整个接口都是愚蠢的 ”。

但是,诸如PostgreSQLMySQL之类的数据库使用Direct IO是有原因的。 开发人员可以使用自定义IO调度程序和特定于应用程序的缓冲区缓存来确保对数据访问模式进行更细粒度的控制。 例如,PostgreSQL使用Direct IO进行WAL (预写日志),因为他们必须在确保持久性的同时尽可能快地执行写入操作,并且可以使用此优化方法,因为他们知道不会立即重用数据,因此绕过内核页面缓存编写它不会导致性能下降。

即使数据最近被访问并且可能位于缓存中,直接读取也将直接从磁盘进行读取。 这有助于避免创建额外的数据副本。 写操作也是如此:执行写操作时,直接从用户空间缓冲区进行写操作。

块对齐

因为DMA(直接内存访问)使请求直接绕过中间内核缓冲区而直接发送到后备存储,所以要求所有操作都按扇区对齐(对齐512B边界)。 换句话说,每个操作的起始偏移量必须为512的倍数,缓冲区大小也必须为512的倍数。

例如,RocksDB 通过预先检查操作来确保操作是按块对齐 (较旧的版本通过在后台对齐来允许不对齐的访问)。

无论是否使用O_DIRECT标志,始终确保读写块对齐是一个好主意:进行未对齐的访问将导致从磁盘加载多个扇区(或写回磁盘)。

使用块大小或恰好适合块内部的值可以保证块对齐的I / O请求,并防止内核内部的多余工作。

非阻塞文件系统IO

我在这里添加此部分是因为我经常在文件系统IO的上下文中听到“非阻塞”的声音。 这是很正常的,因为网络和文件系统IO的大多数编程接口都是相同的。 但是值得一提的是, 没有真正的“非阻塞” IO可以用同样的方式理解。

对于常规文件(在磁盘上),通常会忽略O_NONBLOCK,因为块设备操作通常被认为是非阻塞的(例如,与套接字不同)。 系统不考虑文件系统IO延迟。 之所以做出此决定,是因为数据到达的时间或多或少受到限制。

出于相同的原因,通常会使用诸如selectepoll之类的内容禁止监视和/或检查常规文件的状态。

结束语

考虑到要覆盖的材料太多,很难找到最佳的帖子大小,但是在移动到mmap和矢量IO之前,对标准IO有所了解是正确的。

如果您发现任何要添加的内容或我的帖子中有错误,请随时与我联系,我们将很乐意进行相应的更新。

翻译自: https://hackernoon.com/on-disk-io-part-1-flavours-of-io-8e1ace1de017

网络io和磁盘io

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值