(2021) 26 [持久化] 持久数据的可靠性:RAID和journaling

(2021) 26 [持久化] 持久数据的可靠性:RAID和journaling

南京大学操作系统课蒋炎岩老师网络课程笔记。

视频:https://www.bilibili.com/video/BV1HN41197Ko?p=26
讲义:http://jyywiki.cn/OS/2021/slides/16.slides#/

背景

回顾

文件系统 = 把设备抽象成目录树

  • mount - 文件系统管理
  • mkdir, rmkdir, link, symlink, unlink… - 目录管理
  • open, mmap, read, write, lseek… - 文件管理
    • 使用链表、索引、……实现

如何实现高可靠、高性能

本次课的内容和目标

  • RAID:Redundant Array of Inexpensive Disks,把多块磁盘虚拟化成一块性能更好、更可靠的磁盘。
  • 崩溃一致性:如何在硬件可能崩溃的情况下保证文件系统(数据结构)的一致性。

RAID:Redundant Array of Inexpensive Disks

RAID:Redundant Array of Idependent / Inexpensive Disks

持久数据的可靠性

任何物理存储介质都有失效的可能,你依然希望在存储设备失效的时候能保持数据的完整。

  • 极小概率事件:战争爆发/三体人进攻地球/世界毁灭
  • 小概率事件:硬盘损坏。但是当小概率时间大量重复,那就是必然发生。但我们还是希望系统能照常运转。

增加持久数据可靠性的方法

备胎:鸡蛋不能放在一个篮子里

  • 教务处:物理备份
    • 期末考试后会提交所有批阅的试卷、成绩表、成绩分布
    • 假设教务系统崩溃 v.s. 教务处崩溃是独立事件
      • 两个极小概率事件同时发生,那就认倒霉吧
  • 服务器:数据备份
    • 所有数据同时写入两块磁盘
    • 每日或每周备份
      • crontab (time-based job scheduler)

RAID: 存储设备的虚拟化

RAID (虚拟化) = 虚拟磁盘块到物理磁盘块的 “映射”。

Redundant Array of Inexpensive (Independent) Disks (RAID)

  • 把多个 (不可靠的) 磁盘虚拟成一块非常可靠的虚拟磁盘

类比我们见过的虚拟化

  • 进程:把一个 CPU 分时虚拟成多个虚拟 CPU
  • 虚存:把一份内存通过 MMU 虚拟成多个地址空间
  • 文件:把一个存储设备虚拟成多个虚拟磁盘

RAID 的虚拟化是 “反向” 的

  • (一个 → 多个) vs. (多个 → 一个)

RAID 所针对的 Fault Model: Fail-Stop

磁盘可能在某个时刻忽然彻底无法访问 (数据好像完全消失)。如机械故障、芯片故障等,磁盘好像就 “忽然消失” 了。假设磁盘能报告这个问题 (如何报告?)

你还敢用这个硬盘做 {教务系统, 支付宝, 银行, …} 吗?总有一天,一定有磁盘会坏掉的,坏事件一旦发生,就有数据会丢失,永远不丢失数据似乎是不可能的。我们还能构造可靠的 (单机) 存储系统吗?

RAID - 想法

假设我愿意在系统里多接入一块硬盘用于容灾。通过设备驱动程序抽象成 “一个磁盘” VVV (例如1TB)实际由 A,BA, BA,B 两块 1TB 的物理磁盘组成镜像

  • readb(VVV, blk),可以从 A 或 B 中的任意一个读取。
  • writeb(VVV, blk),将同样的数据写入 A, B 的同一位置。

假设内存带宽远高于磁盘带宽,那我们这样的做法

  • 1X write (浪费了 1/2 的总带宽)
  • 2X sequential read (tricky)
  • 2X random read (使用了 100% 的总带宽)
  • 抵抗任意一块盘的损坏

实际上,这种做法就是RAID-1。写的时候,写入两块实际的盘用于容灾;读的时候可以同时从两块盘读增加带宽。即我们可以用多块盘,来组成一块更快、更可靠的虚拟磁盘。

RAID - 0

RAID-0: 把多块盘 “交替拼接”

性能分析

RAID-0: 把多块盘 “交替拼接”

  • V0→A0,V1→B0,V2i→Ai,V2i+1→BiV_0→A_0, V_1→B_0, V_{2i}→A_i, V_{2i+1}→B_iV0A0,V1B0,V2iAi,V2i+1Bi
  • 完美扩展的高性能虚拟磁盘,100% 顺序/随机读写总带宽
  • 但完全不能容错

对比RAID-1 (镜像):

  • V0→(A,B)V0→(A,B)V0(A,B)
  • 读带宽100%
  • 容忍一块盘 fail

RAID - 4

RAID: 允许 “多对多” 的映射 (一组映射称为 “条带”, stripe)。(V0,V1)→(A,B,C,D)(V_0,V_1)→(A,B,C,D)(V0,V1)(A,B,C,D),其中A=B=V0,C=D=V1A=B=V_0, C=D=V_1A=B=V0,C=D=V1

另一种可能的方式:(V0,V1,V2)→(A,B,C,D)(V_0,V_1,V_2)→(A,B,C,D)(V0,V1,V2)(A,B,C,D)“三块映射到四块”

不妨假设所有的条带 Vi,A,B,C,DV_i,A,B,C,DVi,A,B,C,D 的每个块都只有 1-bit。

问题:如何用 4 个 bit 存储 3-bit 信息,使得 4 个 bit 中的任何一个丢失,都能恢复出存储的 3-bit 的信息?

异或!奇偶校验!

对于 bits ,a1,a2,…,ana_1,a_2,…,a_na1,a2,,an

  • 存储时,an+1=a1⊕a2⊕…⊕ana_{n+1}=a_1⊕a_2⊕…⊕a_nan+1=a1a2an,移项得 a1⊕a2⊕…⊕an⊕an+1=0a_1⊕a_2⊕…⊕a_n⊕a_{n+1}=0a1a2anan+1=0
  • 任何一个 bit 丢失 (对应A,B,C,DA,B,C,DA,B,C,D 中某块硬盘不能启动),可以根据 ai=a1⊕a2⊕…⊕ai−1⊕ai+1⋯⊕ana_i=a_1⊕a_2⊕…⊕a_{i-1}⊕a_{i+1}\dots⊕a_nai=a1a2ai1ai+1an,来计算出丢失的位。

举个例子,如下图:

在这里插入图片描述

我们共有四块盘A、B、C、PA、B、C、PABCP,其中A、B、CA、B、CABC存储数据,PPP盘做奇偶校验。我们假设一开始数据盘存储的数据为:(A,B,C)n=(0,1,0)(A,B,C)_n=(0,1,0)(A,B,C)n=(0,1,0)(A,B,C)m=(1,0,1)(A,B,C)_m=(1,0,1)(A,B,C)m=(1,0,1)。则由此我们可以根据 Pn=An⊕Bn⊕CnP_n=A_n⊕B_n⊕C_nPn=AnBnCn,算出Pn=1P_n=1Pn=1Pm=0P_m=0Pm=0。这时我们假设 AAA盘不幸挂掉了,我们就可以根据B、C、PB、C、PBCP盘恢复出AAA盘的数据:An=Pn⊕Bn⊕CnA_n=P_n⊕B_n⊕C_nAn=PnBnCn,从而计算出An=0A_n=0An=0Am=1A_m=1Am=1

RAID-4: Parity Disk,专门留一块磁盘作为奇偶校验盘。

  • (V0,V1,V2)→(A,B,C,P)(V0,V1,V2)→(A,B,C,P)(V0,V1,V2)(A,B,C,P)
    • A=V0,B=V1,C=V2A=V_0, B=V_1, C=V_2A=V0,B=V1,C=V2
    • P=V0⊕V1⊕V2P=V_0⊕V_1⊕V_2P=V0V1V2 (奇偶校验)

性能分析

  • sequential/random read: 3x (75% 总带宽)
  • sequential write: 3x (75% 总带宽)
  • random write (tricky)
    • D=V0⊕V1⊕V2D=V_0⊕V_1⊕V_2D=V0V1V2
    • 写入任意V0,V1,V2V_0,V_1,V_2V0,V1,V2都需要更新DDD,更新 V0V_0V0 需要 readb({A,PA,PA,P}), writeb({A,PA,PA,P})。奇偶校验盘成为了写瓶颈: 0.5x

RAID - 5:Rotating Parity

RAID - 5:交错排列 parity block

在这里插入图片描述

性能分析

交错排列 parity block,让每一块盘都有均等的机会存储 parity

  • sequential read/write: 3x (75% 总带宽)

  • random read (tricky),(read 足够大,所有磁盘都可以提供数据) 4x (100% 总带宽)

  • random write (tricky),D=V0⊕V1⊕V2D=V_0⊕V_1⊕V_2D=V0V1V2; 写入任意 V0,V1,V2 都需要更新 D0

    奇偶校验依然严重拖慢了随机写入,但至少 n 块盘可以获得 n/4 的随机写性能 (能够 scale)

RAID - 更多地讨论

更快、更可靠、近乎免费的大容量磁盘已经成为今天服务器的标准配置。

RAID 的可靠性

  • RAID 系统发生断电?例子:RAID-1 镜像盘出现不一致的数据
  • 检测到磁盘坏?自动重组

崩溃一致性

另一种 Fault Model

我们的硬件的可靠性可以由RAID做到一定程度的保证,而我们的文件系统,是在磁盘驱动上做的虚拟化,是一棵目录树,它的可靠性我们需要单独分析。

磁盘并没有故障,但操作系统内核可能 crash,系统可能断电。在内存中读写时,我们不会考虑到一致性的问题。因为内存掉电数据全部丢失,我们回来重新跑程序就是了。但是在磁盘读写时,由于我们的磁盘时持久化的存储设备,就会涉及到崩溃一致性的问题。比如,以ext2文件系统为例,即使只是向文件的末尾append一个字节的数据,也涉及到bitmap、inode和实际data三部分的写入,那假如在我们刚刚写完bitmap时,系统断电了,后面两部分都没有写完,我们这时的文件系统还是正确的吗?有点像我们并发程序设计中的原子性,即崩溃的时候,写磁盘的原子性被打破了。

崩溃一致性 (Crash Consistency)

Crash Consistency: Move the file system from one consistent state (e.g., before the file got appended to) to another atomically (e.g., after the inode, bitmap, and new data block have been written to disk).

导致崩溃一致性的原因就如同我们上面介绍的那样,源自于原子性的丧失:

  • RAID: write(V0V_0V0) → write(AAA), write(BBB)
  • ext2 (文件追加写入一块): write(inode); write(bitmap); write(data);
    • 但是存储设备的多次写入没有原子性保证
    • 有些磁盘在设计时,甚至为了性能,没有顺序保证
    • (类似我们之前讲的 并发编程:从入门到放弃)

原子性丧失:后果

考虑追加写入一个数据块,磁盘上数据结构的更新,包括我们之前说过的b(bit), i, d三个部分的写:

在这里插入图片描述

我们接下来分别分析,只写了三个部分中的某一部分时的后果:

  • {b} - dead block,如果只写了bitmap,而inodes和data blocks都没有写的话,就相当于一块block被标记为了已用,虽然实际上时还没有写过的,可用的block,但是再也不能被用到了,成为了一块dead block。有点类似于malloc了当时没有free的内存泄漏。(磁盘泄漏?)
  • {i} - dangling pointe, 如果只写了inode,但是没写bitmap和data blocks的话,问题就大了。试想这样一种情况,某个高权限的人写入了自己的私密信息(如密码等)到某个文件,但在这个写入过程中断电了,只写了inode,但是没写bitmap和data blocks。那这一块就会被认为是还未写的,如果有人试图分配这块block,就可以获得它的读写权限,可能会访问到上述私密信息。如果被别有用心之人构造大量的workload,来获取大量的磁盘上写了 i 但是没写 b 和 d 的块的读写权限,后果不堪设想,相当于本磁盘的数据安全性已经得不到保证。
  • {d} - random writes (没有一致性问题)
  • {b,i} - incorrect data
  • {i,d} - dangling pointer
  • {b,d} - dead block

崩溃恢复:FSCK(File System Checking)

大家可能会有印象,早年间的Windows XP系统在不正常关机之后,会在再次开机蓝屏时问你要不要检测磁盘,如果要检测,就会是一个很漫长的等待时间,这就是在做FSCK(File System Checking)。

根据磁盘上已有的信息,恢复出 “最可能” 的数据结构

  • 检查 inode 标记的数据块是否 bitmap 都标记为 “1”
  • 检查 inode 数据是否 “看起来合法”,否则删除
  • 检查是否存在 dangling link,没有链接的 inode 被移到 lost+found 目录中,lost+found目录大家应该都在Linux系统中见到过,就在完成FSCK检测时创建的

刚才的哪些情况可以由 fsck 修复?

  • {b,i} - incorrect data
  • {i,d} - dangling pointer
  • {b,d} - dead block

FSCK的难题

到底谁是对的?

在发生不一致时,“到底什么是对的”?在发生不一致时,可能会有多种情况导致现有的情况,那么到底应该按哪一种来恢复呢?
在这里插入图片描述

如果 fsck 的时候发生崩溃

fsck 也是程序,fsck 也要访问文件系统。如果 fsck 时发生崩溃,由于 fsck 完成的工作比一般的磁盘读写更加危险,文件系统可能进入彻底无法恢复的状态!

因此fsck 更多用于磁盘发生部分损坏时的数据抢救

针对 crash,我们需要更可靠的方法我们需要一个更可靠的方法,文件系统不一致的根本原因是存储设备无法提供多次写入的原子性

崩溃恢复:journaling

日志 (Journaling)

能否在磁盘 API 上实现可靠的 multi-write 原子性?

  • readb (读一块), writeb (写一块), sync (等待所有过去的写入落盘)

数据结构的两种实现方法

我们前面说到要将文件系统理解为磁盘上的数据结构

  1. 存储实际数据结构,这是我们学习数据结构时常见的表示形式
    • 文件系统的 “直观” 表示
    • crash unsafe
  2. append-only 记录所有历史操作,这种形式不常见,听起来也很离谱,但是在维护崩溃一致性时却有关键作用
    • “重做” 所有操作得到数据结构的当前状态
    • 容易实现崩溃一致性

append-only 的数据结构也是实现分布式系统的关键技术。

实现 Atomic Append

在这里插入图片描述

  1. 定位到 journal 的末尾 (使用 readb)

  2. 在 journal 末尾 append TXBegin,并记录所有操作

    记录文件系统操作 v.s. 记录磁盘块操作

  3. sync,等待数据落盘

  4. append TXEnd

  5. sync,等待 TXEnd 落盘

    sync 返回后持久化完成 (“committed”)

实现 Crash Consistency

小孩子才做选择,我文件系统全都要! — 两种数据结构的便是形式都维持

主要维护文件系统的结构,但预留一定的 journal 区域,journal commit 后,可以将 journal 中的操作直接应用到文件系统上 (checkpoint)。

  • redo logging (write-ahead logging): journal 记录 “做什么”
    • 先写 journal,再写文件系统
    • 崩溃恢复时,重做 journal 中的操作
  • undo logging: 记录如何 “撤销” 操作 (即块中的数值)
    • 先写文件系统,再写 journal
    • 崩溃恢复时,撤销文件系统中的

Journaling: 优化

现在为了做journaling,磁盘需要写入双份的数据,性能会大幅下降,我们需要再性能和可靠性之间做一个trade-off。下面是集中常见的文件系统的实现方式:

  • 批处理 (xv6; jbd)
    • 多次系统调用的 Tx 合并成一个,减少 log 的大小
    • jbd: 定期 write back
  • Checksum (ext4)
    • 不再标记 TxBegin/TxEnd
    • 直接标记 Tx 的长度和 checksum
  • Metadata journaling (ext4 default)
    • 数据占磁盘写入的绝大部分,只对 inode 和 bitmap 这些关键信息做 journaling 可以提高性能
    • 保证文件系统的目录结构是一致的;但数据可能丢失

为应用程序提供 Multi-Write 的一致性?

在未来,可能会有TxOS, 提供三个新的系统调用

  • xbegin, xend, xabort
  • 实现多个系统调用的原子性
    • 应用场景:数据更新、软件更新、check-use……
  • D. E. Porter, et al. Operating systems transactions. In Proc. of SOSP, 2009.

总结

本次课内容与目标

持久数据的可靠性

  • fail-stop: RAID
  • 随机损坏:fsck
  • 崩溃:journaling

Takeaway messages

  • 把磁盘理解成 “数据结构”

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

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

相关文章

win10无法检验服务器出示的ssl证书,win10系统网站启用ssL安全证书的操作方法

win10系统网站启用ssL安全证书的操作方法?很多win10用户在使用电脑的时候,会发现win10系统网站启用ssL安全证书的的现象,根据小编的调查并不是所有的朋友都知道win10系统网站启用ssL安全证书的的问题怎么解决,不会的朋友也不用担心&#xff…

Nplayer本地文件拷到服务器,手把手教你简易NAS构建,手机/平板/智能电视随意调取,家庭存储云共享,有了自己的网络云盘后再也不用担心容量不够了!...

之前嫌键盘侠烦,写这些也没意义所以把账号注销了文章删除了,现在想了想我抗吧12级老蛆还喷不过这帮小兔崽子?换了skt.ruo秽土转生,求喷子和我在各评论对线。特别是匿名dog见一个怼死一个。下面是之前号写的内容原文 -#简介NAS全称…

gdb 入门

gdb 入门 简介 gdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。 一般来说,GDB主要帮助你完成下面四个方面的功能: 1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 2、可让被调试的程序在你所指定的调置的断点…

Linux下的CUDA多版本管理

Linux下的CUDA多版本管理 关于CUDA、cuDNN等的简介和安装可参考:显卡、显卡驱动、CUDA、CUDA Toolkit、cuDNN 梳理。 CUDA多版本 有时我们会在一台机器上同时看到多个版本的CUDA,比如nvcc -V和nvidia-smi的输出就可能会不同: 在我们实验室…

ONNX初探

ONNX初探 转载自:https://blog.csdn.net/just_sort/article/details/112912272 0x0. 背景 最近看了一些ONNX的资料,一个最大的感受就是这些资料太凌乱了。大多数都是在介绍ONNX模型转换中碰到的坑点以及解决办法。很少有文章可以系统的介绍ONNX的背景…

服务器修改地址,服务器修改管理地址

服务器修改管理地址 内容精选换一换在弹性云服务器上安装完成后输入公网IP,无法连接目的虚拟机,端口无法访问工具。源端网络未连通目的端。目的端安全组未开放8084端口。目的端网络ACL禁用了8084端口。登录源端服务器后,在源端服务器中ping 目…

ONNX再探

ONNX再探 本文转自:https://blog.csdn.net/just_sort/article/details/113802330 这篇文章从多个角度探索了ONNX,从ONNX的导出到ONNX和Caffe的对比,以及使用ONNX遭遇的困难以及一些解决办法,另外还介绍了ONNXRuntime以及如何基于…

图解自监督学习(CV)

图解自监督学习(CV) 译自:https://amitness.com/2020/02/illustrated-self-supervised-learning/ 作者:Amit Chaudhary 注:译者在某些地方对原文的表述做了调整,使其适合汉语的阅读习惯,并在…

机器学习中的归纳偏置

机器学习中的归纳偏置 带着偏见看世界,否则你根本没有看待世界的方式。 本文主要参考整理自知乎问题:如何理解Inductive bias? No-Free-Lunch(NLF)定理指出学习是不可能的,除非有先验知识。通常情况下&…

【c语言数据结构笔记】1.2 数据结构

1.2数据结构 数据元素并独立 结构实体关系 形式定义&#xff08;D&#xff0c;S&#xff09; 其中D是数据元素的有限集&#xff0c;S是D上关系的有限集 eg&#xff1a;12位数&#xff1a;132423451233 分成三组四位数 次序关系<a1,a2><a2,a3> 遵守次序关系 eg&…

使用Apex进行混合精度训练

使用Apex进行混合精度训练 转自&#xff1a;https://fyubang.com/2019/08/26/fp16/ 你想获得双倍训练速度的快感吗&#xff1f; 你想让你的显存空间瞬间翻倍吗&#xff1f; 如果我告诉你只需要三行代码即可实现&#xff0c;你信不&#xff1f; 在这篇博客里&#xff0c;瓦砾…

【数据结构1.3笔记】研究内容

1.3研究内容 数据结构&#xff08;D&#xff0c;S&#xff09; {逻辑结构&#xff1a; {物理结构&#xff08;存储结构&#xff09; {数据的运算 1.逻辑结构 1 集合&#xff1a;集合&#xff0c;没有逻辑关系 2 线性结构 “一对一” 3树形结构 层次关系 4图形结构 练习&…

2019年蓝桥杯第一题

第一题 标题&#xff1a;组队&#xff08;本题总分&#xff1a;5 分&#xff09; 作为篮球队教练&#xff0c;你需要从以下名单中选出 1 号位至 5 号位各一名球员&#xff0c; 组成球队的首发阵容。 每位球员担任 1 号位至 5 号位时的评分如下表所示。请你计算首发阵容 1 号位…

深度学习编译:MLIR初步

深度学习编译MLIR初步 深度模型的推理引擎 目前深度模型的推理引擎按照实现方式大体分为两类&#xff1a;解释型推理引擎和编译型推理引擎。 解释型推理引擎 一般包含模型解析器&#xff0c;模型解释器&#xff0c;模型优化器。 模型解析器负责读取和解析模型文件&#xff…

深入浅出LLVM

深入浅出LLVM 转自&#xff1a;https://www.jianshu.com/p/1367dad95445 什么是LLVM&#xff1f; LLVM项目是模块化、可重用的编译器以及工具链技术的集合。 美国计算机协会 (ACM) 将其2012 年软件系统奖项颁给了LLVM&#xff0c;之前曾经获得此奖项的软件和技术包括:Java、A…

一分钟系列:什么是虚拟内存?

一分钟系列&#xff1a;什么是虚拟内存&#xff1f; 转自&#xff1a;https://mp.weixin.qq.com/s/opMgZrXV-lfgOWrNUMKweg 注&#xff1a;一分钟系列的篇幅都不长&#xff0c;适合吃饭蹲坑、地铁公交上食用&#xff5e; 内存对于用户来说就是一个字节数组&#xff0c;我们可…

11-Kafka

1 Kafka Kafka是一个分布式流式数据平台&#xff0c;它具有三个关键特性 Message System: Pub-Sub消息系统Availability & Reliability&#xff1a;以容错及持久化的方式存储数据记录流Scalable & Real time 1.1 Kafka架构体系 Kafka系统中存在5个关键组件 Producer…

虚拟内存精粹

虚拟内存精粹 标题&#xff1a;虚拟内存精粹 作者&#xff1a;潘建锋 原文&#xff1a;HTTPS://strikefreedom.top/memory-management–virtual-memory 导言 虚拟内存是当今计算机系统中最重要的抽象概念之一&#xff0c;它的提出是为了更加有效地管理内存并且降低内存出错的概…

深度学习自动编译和优化技术调研

深度学习自动编译和优化技术调研 转自&#xff1a;https://moqi.com.cn/blog/deeplearning/ 作者&#xff1a;墨奇科技全栈开发 在墨奇科技&#xff0c;我们需要将一些包含深度神经网络&#xff08;DNN&#xff09;的 AI 算法移植到边缘端的设备&#xff0c; 这些设备往往使用 …

Copy-On-Write COW机制

Copy-On-Write COW机制 转自&#xff1a;https://zhuanlan.zhihu.com/p/48147304 作者&#xff1a;Java3y 前言 只有光头才能变强 在读《Redis设计与实现》关于哈希表扩容的时候&#xff0c;发现这么一段话&#xff1a; 执行BGSAVE命令或者BGREWRITEAOF命令的过程中&#xff0c…