Linux操作系统的存储子系统应该是Linux中最为复杂的子系统了。其实很多子系统都认为自己是最复杂的子系统,比如内存子系统和网络子系统也这么说。无论如何,存储子系统在Linux中是比较复杂的。今天我们就介绍一下Linux的存储子系统中的硬盘与RAID的相关内容,后面再写一篇关于LVM与文件系统的内容。

硬盘

在Linux的存储子系统中,最底层的就是硬盘了。这里的硬盘并不是指我们看到的硬盘硬件,而是指在Linux内部看到的硬盘设备,或者说是块设备。如果我们在/dev目录执行以下ls命令,就可以看到很多设备。在这些设备中以sd开头的就是基于SCSI协议的硬盘。

图1 Linux中的块设备

无论是基于SAS、iSCSI还是FC的磁盘设备,大概都是这个样子。形似dm-X的是Device Map块设备,也就是通过LVM进行管理的设备,这种设备是一种逻辑设备。

在Linux操作系统中块设备的种类很多,有本地磁盘设备、有SAN设备还有基于网络的块设备。在虚拟机中块设备又呈现为另外一种文件名,比如在Xen虚拟机中为xvdX。

虽然名称差异很大,但是在Linux操作系统内核中的实现却非常简单。在内核中任何磁盘块设备都是通过调用add_disk函数完成的。在《Linux设备驱动程序》这本书对块设备进行了详细的介绍,并且可以通过非常简单的代码实现一个自己的块设备。

图2 最简单的块设备驱动

这里面有2个函数,也就是alloc_disk和add_disk。前一个函数是分配一个通用块的结构体,后者则是将该块设备添加到内核,也就是在/dev目录下生成一个“文件”。以上述代码为例,执行后会生成如下块设备。

brw-rw---- 1 root disk 251, 0 Jun 16 09:13 /dev/sbulla

这里我们自定义了一个设备名称sbulla。其实我们看到的SCSI设备也是这样定义的,只不过其定义名称的时候是通过sd字符。

以上述代码为例,在块设备中比较重要的地方是初始化了一个队列处理函数(sbull_full_request)。所有从上层访问该块设备的请求都会转发到该处理函数进行处理。

所有块设备都要初始化这个队列,并且提供一个请求处理函数。不同的块设备的请求处理函数略有不同。比如常见的SCSI块设备,其处理函数初始化过程如下:

q = __scsi_alloc_queue(sdev->host, scsi_request_fn);

而nbd(网络块设备,通过网络的方式将服务端的文件映射为客户端的块设备)设备的初始化队列的代码如下所示:

disk->queue = blk_init_queue(do_nbd_request, &nbd_lock);

类似的例子还很多,本文不再一一介绍。这里我们需要理解一点,核心问题在于注册处理请求的回调函数,以及通过add_disk就可以在/dev目录下面创建一个块设备。

另外一点,对于任何类型的块设备,无论是本地硬盘,还是经过网络的NBD和iSCSI,还是FC设备,最后都是/dev目录下的一个文件,而这个文件其实就是块设备。我们可以通过对该文件的读写实现对块设备的访问。

RAID

作为普通用户使用单个硬盘是没有任何问题的,但是作为企业应用使用单个硬盘存在很大的风险。这时因为硬盘随时有可能损坏,因此我们需要一种机制来保证即使出现硬盘故障的情况下,数据不会丢失,且业务仍然可以正常工作。

RAID正是解决上述问题的技术。RAID的全称为廉价冗余磁盘阵列(Redundant Array of Inexpensive Disks),从字面可以看出其基本原理就是通过廉价的磁盘组成一组磁盘。RAID不仅仅可以通过冗余的方式解决数据可靠性的问题,还可以提高性能。其主要原理就是将请求拆分到多个物理硬盘来执行,性能自然比一个硬盘快了。

在Linux操作系统层面,其实就是将物理磁盘通过软件抽象为逻辑磁盘。以RAID1(两块磁盘存储相同的数据,在出现一块磁盘故障的情况下,数据不丢失)为例,通过Linux内核中的软件创建一个虚拟的块设备,而该块设备中记录了底层对应的物理设备及相关参数。

图3 RAID1 示意图

因此,从用户层面来看就是一块普通的磁盘设备,而在底层却是2个独立的物理硬盘。当用户向逻辑磁盘写数据的时候,其中的软件会通过参数进行计算,并将数据重新定向到底层的物理设备。通过这种方法可以保证即使出现某个物理磁盘损坏,用户的数据仍然完好无损。

除了上面说的RAID1外,还有很多RAID类型。不同的RAID类型实现不同的功能。比如RAID0实现条带化,主要是提升性能;RAID1则是实现数据的冗余,防止磁盘故障导致的数据丢失;由于上述RAID只能解决一方面的问题,因此有人讲两者结合,出现了RAID10和RAID01,这样既能保证数据的可靠性,又能提升性能。

由于RAID1是一份数据写到两个设备,因此只有50%的有效数据。为了提高有效数据率,于是发明了RAID5和RAID6等类型。其中RAID5通过增加一个校验数据来保证数据的可靠性,以5块盘的RAID5为例,其中有效数占4块盘的空间,有效数据80%。但是RAID5有个问题,就是一组磁盘中只能坏一块,如果损坏的磁盘超过1块就会导致数据丢失。RAID6的算法与RAID5类似,它的特点是可以容忍2块磁盘故障。

在实现层面,Linux的RAID实现在用户态和内核态都有涉及。其中用户态主要进行RAID的管理,而内核态一方面配合用户态进行RAID管理,另外一方面则实现对IO的处理,这部分才是RAID最为核心的内容。

图4 软件架构

对于基于SCSI物理磁盘的RAID来说,Linux环境下整个软件架构如图4所示。其中虚线以上的为用户态的软件模块,虚线以下的为内核态的软件模块。这里比较核心的是RAID公共层,在这里主要创建md设备,该设备是一个逻辑设备,也是用户可以看到的RAID设备。其下则是具体的RAID模块,用于实现不同的RAID级别(算法)。

再往下就是通用SCSI驱动层了,也就是图中的SCSI磁盘驱动这一层的内容。该层其实是SCSI系统的上层驱动(SCSI子系统分为上中下三层)。RAID模块通过调用该层的数据访问接口就可以实现物理磁盘数据读写了。

操作系统读写者问题实验报告_Linux操作系统存储子系统核心技术之硬盘与RAID相关推荐

  1. 操作系统读写者问题实验报告_操作系统 37

    这里是操作系统自学笔记第37节 Hard Disk Drives 磁盘的最小单位是扇区(sector),每个sector 512 byte,是磁盘原子操作的单位:扇区编号0-n-1是address s ...

  2. 操作系统读写者问题实验报告_操作系统知识点总结

    用户态和内核态 用户态和内核态的区别? 明白这两个概念之前,我们得知道用户空间和内核空间. 用户空间:指的就是用户可以操作和访问的空间,这个空间通常存放我们用户自己写的数据等. 内核空间:是系统内核来 ...

  3. 操作系统读写者问题实验报告_基于S3C2410微处理器和操作系统实现光电测量仿真检测系统的设计...

    引言 动基座光电测量平台按载体的不同可分为车载.舰载.机载和星载四种.为了保证测量平台系统的可靠性和测量的准确性,平台在正式放到载体上运行之前需要进行仿真检测.目前的动基座光电测量仿真检测系统大多成本 ...

  4. 操作系统读写者问题实验报告_备战秋招——操作系统(2)

    请你讲述一下互斥锁(mutex)机制,以及互斥锁和读写锁的区别 参考回答: 1.互斥锁和读写锁区别: 互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象.当获取锁操作失败时,线程会进入 ...

  5. 操作系统读写者问题实验报告_什么是操作系统?

    什么是操作系统? 为什么说C / C++ 更底层 ? 电脑里只有一个CPU, 多线程是怎么实现的 ? 一些简单口胡, 也算对本学期的学习做一个总结 一言蔽之, 操作系统是管理下层硬件, 为上层软件提供 ...

  6. Linux进程的创建和父子进程同步,操作系统实验报告_Linux进程创建与通信.doc

    操作系统实验报告_Linux进程创建与通信 2011-2012学年第一学期 专 业: 班 级: 学 号: 姓 名:提交日期:2011年11月实验二 Linux进程创建与进程通信 [实验目的 1. 熟悉 ...

  7. 操作系统第6次实验报告:使用信号

    操作系统第6次实验报告:使用信号 一.实验目的 通过编程进一步了解信号. 二.实验内容 在服务器上用Vim编写程序,完成以下两个作业: 作业1:发送SIGTERM结束子进程 int kill(pid_ ...

  8. linux课程实验报告,Linux操作系统课程实验报告

    Linux操作系统课程实验报告 Linux操作系统 课程实验报告 班级: 姓名: 学号: 指导老师:田丽华 完成时间:2014年7月 目录 一.实验目的1 二.实验要求1 三.实验内容1 [第一题]1 ...

  9. 操作系统生产者消费者问题实验报告

    操作系统实验报告 进程通信 1. 问题描述及需求分析: 问题描述 本次实验实现生产者和消费者之间的通信,即生产者-消费者问题.生产者一次生成一个元素放入缓冲池中,消费者一次可以从缓冲池中取出一个元素. ...

  10. 实验报告Linux操作系统基本命令,linux操作系统实验报告全部.doc

    linux操作系统实验报告全部 计算机操作系统 实验报告 学 号:姓 名:提交日期:2014.12.15成 绩: 东北大学秦皇岛分校 [实验题目]熟悉Linux/UNIX操作系统[实验目的]1.熟悉L ...

最新文章

  1. QT绘制具有向下钻取效果的园饼图
  2. 码代码,到白头|专访SRS创始作者阿里云RTC服务器团队负责人杨成立
  3. C++题解-Leecode 375. 猜数字大小 II——Leecode每日一题系列
  4. 如何查看mysql8.0的默认密码_MySQL8.0安装之后查找默认密码
  5. c语言 为什么i%3cn 1,c语言中n+1个基础且容易出错的知识点
  6. python 两个数据框合并计算_一文掌握Excel、SQL、Python【数据合并】大法!
  7. 模数转换实验中断方式c语言,DSP实验报告--模拟信号的AD+FFT变换
  8. Spark生态之Spark Streaming
  9. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-3.在线教育站点需求分析和架构设计...
  10. android XMPP即时通讯客户端
  11. 表格中复制粘贴到其他位置的数据会携带引号等不可见字符,该怎么处理?
  12. echarts中国地图根据数据对省份渲染不同的颜色
  13. 2021-08-11BUU-CTF:[WUSTCTF2020]alison_likes_jojo
  14. conda create出现连接问题_处理conda安装工具的动态库缺失问题
  15. python数据分析:使用statsmodels构建价格需求弹性模型
  16. TensorFlow 显存占用率高 GPU利用率低
  17. 一起DIY四轴飞行器(三)添加实时操作系统--freeRTOS
  18. 《FFmpeg Basics》中文版-01-FFmpeg基本介绍
  19. HideToolz _隐藏进程工具
  20. 【论文阅读笔记1】:Pre-trained Language Models for Text Generation: A Survey

热门文章

  1. 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
  2. python机器学习库xgboost使用调参
  3. PCL中的点云分割算法
  4. VCS学习(2)debug simulation mismatches
  5. redis tutorail
  6. OrzFAng系列–树 解题报告
  7. JQuery插件iScroll实现下拉刷新,滚动翻页特效
  8. 学习document.location.href和document.location.replace 区别
  9. 创建型模式专题总结:Creational Pattern(转自Terrylee)
  10. 内文广告程序开发中遇到的一个问题