一文快速了解Posix IO 缓冲

1. 背景知识

IO写入的过程是这样的:

用户数据 –> 进程IO缓冲区 –> 内核缓冲区 –> (磁盘缓冲区->磁盘)

通常我们认为一个写请求(注意我们讨论的粒度一定是一个request,在不同环节request可能会被拆分合并)落盘,则是在它从内核缓冲区(内存中的一块区域)刷到磁盘上(不关心磁盘缓冲区)。对于持久化存储磁盘,当数据落盘成功后,断电/宕机数据依然会在磁盘上。

缓冲区公共的作用是聚集小IO,提高性能。

  • 进程缓冲区。经常做IO写出的同学都知道,必要的时候我们会在代码里手动对outputstream等对象进行flush调用,这里的flush就是刷进程缓冲区。进程缓冲区可以减少内核态write的触发。
  • 内核缓冲区。如果应用的写很零碎,甚至是按字节写的,如果零碎不对齐小IO持续写入,会对写入性能、磁盘存储和寿命产生极大影响。内核缓冲区可以减少实际IO的触发。
  • 磁盘缓冲区。这里指的是硬盘上自己的一块容量固定的缓冲区,作用其实也是提高写入性能和保护磁盘。

2. IO类型:

  • 默认带缓冲IO: 应用写出数据到进程IO缓冲区中直接返回写成功。缓冲区会在写满或者文件句柄关闭时刷到下个环节。这种模式下,应用write接口成功并不能代表数据落盘成功。即此时宕机可能会丢失部分write返回成功的数据。
  • Sync IO:强制同步IO,即数据写入内核缓冲区后,强制立即将内核缓冲区数据刷出到磁盘。sync会让磁盘缓冲区也触发flush。
  • Direct IO:直写IO,不经过进程IO缓冲区和内核缓冲区。bypass OS cache, 但不会flush磁盘中的缓冲区。

在linux open()系统调用的时候可以指定flag来决定当前写出使用哪种类型IO。

  • 不指定:默认缓冲IO
  • O_DIRECT: 直写模式。
  • O_SYNC: 每次写出将数据和文件元信息一起更新落盘。等同于write() + fsync()
  • O_DSYNC: 每次写出仅更新数据,元信息只在必要的时候更新 (譬如不改变文件长度的写操作)。等同于 write() + fdatasync()
  • O_RSYNC: linux未实现该语义,早些版本的glibc把它等同于O_SYNC。大致理解是写出后不直接强制立即刷缓存,而是异步刷出。但他会保证当应用下一个read到来时,数据都已经从缓冲区刷出落盘。感觉是个有点为了性能delaying flushing 妥协的方案。

O_RSYNC: this flag, which only affects read operations, must be used in combination with either O_SYNC or O_DSYNC. It will cause a read() call to block until the data (and maybe metadata) being read has been flushed to disk (if necessary). This flag thus gives the kernel the option of delaying the flushing of data to disk; any number of writes can happen, but data need not be flushed until the application reads it back.

3. TroubleShooting:

  • 如何保证写出数据落盘?
    采用SYNC方式写出,或者采用DIRECT/默认方式写出后显式调用 sync/fsync/fdatasync等系统函数。
  • 平时写出数据应采用哪种方式?
    O_SYNC是最安全的,但是也是性能最低的。因此实际要从性能和安全两个角度去衡量。

原文地址:https://www.cnblogs.com/lhfcws/p/12202512.html

时间: 2024-08-06 22:49:24

一文快速了解Posix IO 缓冲的相关文章

一文看懂java io系统 (转)

出处:  一文看懂java io系统 学习java IO系统,重点是学会IO模型,了解了各种IO模型之后就可以更好的理解java IO Java IO 是一套Java用来读写数据(输入和输出)的API.大部分程序都要处理一些输入,并由输入产生一些输出.Java为此提供了java.io包 java中io系统可以分为Bio,Nio,Aio三种io模型 关于Bio,我们需要知道什么是同步阻塞IO模型,Bio操作的对象:流,以及如何使用Bio进行网络编程,使用Bio进行网络编程的问题 关于Nio,我们需

一文快速入门Docker

Docker提供一种安全.可重复的环境中自动部署软件的方式,拉开了基于与计算平台发展方式的变革序幕.如今Docker在互联网公司使用已经非常普遍.本文用十分钟时间,带你快速入门Docker. Docker是什么 Docker是什么? 官网首页的介绍: Enterprise Container Platform for High-Velocity Innovation. Securely build, share and run any application, anywhere 百度百科告诉我们

一文快速入门 MySQL 索引

本文首发于 https://antoniopeng.com 什么是索引 MySQL 官方对索引的定义:索引(Index)是帮助 MySQL高效获取数据的数据结构.因此 索引的本质就是数据结构.索引的目的在于提高查询效率,可类比字典.书籍的目录等这种形式. 可简单理解为 排好序的快速查找数据结构.在数据之外,数据库系统还维护着 满足特定算法查询的数据结构,这些数据结构以某种方式指向数据.这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引. 一般来说,索引比较大,不可能全部存储在内存中

Java文件与io——缓冲流

对文件或其它目标频繁的读写操作,效率低,性能差. 使用缓冲流的好处,能够更高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来. BufferedInputStream:为另一个输入流添加一些功能,在创建时,会创建一个内部缓冲区数组,用于缓冲数据 BufferedOutputStream:通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统 BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符.数组和行的高效读取

java Vamei快速教程15 IO基础

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 计算机最重要的功能是处理数据.一个有用的计算机语言需要拥有良好的IO功能,以便让未处理的数据流入程序,让已处理的数据流出. 与其他语言相比,Java的IO功能显得复杂.在其他语言中,许多IO功能(比如读取文件),是被封装好的,可以用一两行程序实现.在Java中,程序员往往需要多个层次的装饰(decoration),才能实现文件读取. 相对的复杂性带来的好处是IO的灵活性.在Jav

一文快速搞懂MySQL InnoDB事务ACID实现原理

[51CTO.com原创稿件]说到数据库事务,想到的就是要么都做修改,要么都不做,或者是 ACID 的概念.其实事务的本质就是锁.并发和重做日志的结合体. 这一篇主要讲一下 InnoDB 中的事务到底是如何实现 ACID 的: 原子性(atomicity) 一致性(consistency) 隔离性(isolation) 持久性(durability)隔离性隔离性的实现原理就是锁,因而隔离性也可以称为并发控制.锁等.事务的隔离性要求每个读写事务的对象对其他事务的操作对象能互相分离.再者,比如操作缓

文快速伪原创章提升排名方法

http://passport.baidu.com/?business&un=%E6%89%BE%E7%94%B5%E8%AF%9D%E7%94%B0%E4%B8%9C%E5%B0%8F%E5%A7%90http://passport.baidu.com/?business&un=%E6%89%BE%E7%94%B5%E8%AF%9D%E5%B9%B3%E6%9E%9C%E5%B0%8F%E5%A7%90http://passport.baidu.com/?business&un=

15、IO (转换流、缓冲流)

转换流概述 * A: 转换流概述 * a: 转换流概述 * OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节 * 将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去 ? 转换流_字符转字节的过程 * A: 转换流_字符转字节的过程 * a.图解 * 详见day24_source/转换流.JPG图片 ? OutputStreamWriter写文本文件 * A: OutputStreamWriter写文本文件 * a:

ANSI C & POSIX 文件 IO

ANSI C C语言标准库函数:用户态 Windows和Linux平台通用 文件流指针:FILE* fopen.fclose.fwrite.fread... POSIX Linux系统调用函数:内核态 仅能在Linux系统中使用 文件描述符:file 结构体 open.close.write.read... ANSI C 库 IO 函数其实是对 POSIX IO 函数的封装,在其基础上加上了流的概念,并在用户空间申请了流资源(FILE)