IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 文件close后就一定持久化到硬盘了吗 -> 正文阅读

[系统运维]文件close后就一定持久化到硬盘了吗

文件close后就一定持久化到硬盘了吗

背景

关于文件操作的api是我们工作中经常使用到的.

同时, 我们工作中的一些编程语言都提供了库函数方便我们直接调用.
经常被提到的一个 best practice 就是文件不再使用后, 一定要close.

例如下面的ruby代码:

f = File.new("out", "w")
f.write("1234567890")     #=> 10
f.close                   #=> nil

但是, 文件被close掉后, 就一定在硬盘中持久化了吗?

答案是: 不一定!

操作系统的page cache

想要了解答案的缘由, 需要先介绍一下操作系统(linux)的page cache.

我们知道:

  • 访问内存的速度是远高于访问硬盘的速度的
  • 操作系统是按照分页来管理数据的

为了加快程序的处理速度,
操作系统往往会有page cache将硬盘中的内容读取到内存中. 直接操作内存的数据.

但是, 这样也会带来弊端. 就是缓存到内存的page, 如果有内容修改. 则内存的page数据与硬盘的数据不一致.
不一致的page称为dirty page 脏页.

为了解决数据不一致的问题, 操作系统会在下面的特定的情况下将脏页写到硬盘中.

  • 调用 fsync 等系统调用
  • 操作系统定时将page cache写到硬盘. (默认是: 每5秒检测一次, 超过30秒的page cache写入硬盘)
  • page cache 在内存中的比例超过10% (或设置特定的字节数)时开始后台处理, 达到30%时(或设置特定的字节数)需要block住其它进程.
# 查看linux配置的dirty page项目的参数
sysctl -a | grep dirty
# 具体的说明: https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 30
vm.dirty_writeback_centisecs = 500
# You can also see statistics on the page cache in /proc/vmstat:
cat /proc/vmstat | egrep "dirty|writeback"
cat /proc/meminfo | grep Dirty

顺便提一下: 数据库缓存一般是自己实现的, 没有使用操作系统的page cache.

应用程序缓存

了解到为了加快IO速度, 操作系统有page cache将硬盘的数据读取到内存中.

那么, 应用程序是否有类似的机制加快IO速度呢?

答案是肯定的. 一般的编程语言都有内部的缓存, 用于优化IO速度.

我们可以设想以下场景:

# 执行完 new一个文件对象, 会先创建文件 out
f = File.new("out", "w")
100.times do |_t|
  f.write(_t)
end
# 文件直到被close, 数据才会写到文件中
f.close

为什么ruby语言要这么做呢?

如果每次ruby执行write方法都真地去往文件中写, 那势必会影响性能.
在close时再写入, 会更高效.

但是, 这样也会有问题, 就是突然断电的话, 会导致文件没有持久化.

回顾close

File#new, IO#close, linux man2 close

我们可以看到, 当ruby执行close方法后, ruby会关闭IO Stream 并把 Ruby 的 buffer flush.
同时, 释放文件的的file descriptor给操作系统.

但是, 我们在上文中也讲到: 由于操作系统的page cache.
ruby close文件后, 只是将应用层的缓存flush了. 操作系统层面的page cache还存在脏页.

因此, 如果此时断电的话, 文件有可能没有持久化到硬盘上.

那么, 如何解决呢?

可以执行

f.fsync
f.close

IO.close: Closes the Ruby IO and writes pending data to the OS. Note that this does not imply fsync(). The POSIX documentation on close() says that it does NOT guarantee data is physically written to the file. So you need to use an explicit fsync() call for that.

参考文章

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:51:11  更:2022-04-04 12:53:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:41:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码