Raid1的源码的读、写、同步,在本系列博客中都已经分析完成。除了barrier机制要专门拿出来分析(下一篇会写)以外,有一些问题值得思考和注意,分析如下。

1、freeze_array是如何做的?

通过barrier挡住上层用户io请求,并且nr_waiting++计数。nr_pending表示未完成的请求数,nr_queue表示retrylist的r1_bio数量。conf->nr_pending == conf->nr_queued+1表示没有正常的处理请求了,满足这个条件的时候就进行read error的处理;不满足的话,就进行后面的两个处理,之后wait。后面的两个处理是:flush_pending_writes(conf);  raid1_unplug(conf->mddev->queue);第一句的意思是下发raid1层中未下发的所有写请求,第二句的意思是通知下层赶紧unplug下发请求。这里需要注意的是,读请求是在make_request中下发的,是用户上下文,并且nr_pending++也是在make_request中做的;而这里是daemon的上下文,所以只需要通知下层赶紧unplug就可以了。而写请求本来就是需要挂在pending list中由deamon来进行处理的,所以需要第一句下发raid1中还未下发的写请求。

假设一种情景,如果这时又有另外一个或者多个读出错,那么就是将其r1_bio挂到retry list上等待处理,deamon处理retry list链上的r1_bio是逐个进行处理,处理完一个之后才处理下一个,不会有并发产生。也就是说如果有两个读出错,那么需要等待前一个读出错处理流程完全做完之后,才可以做下一个。

另外需要说明的是,这里如果读出错的同一个磁盘位置,正好raid1有写请求还未下发,通知raid1层下发,那么就写了这个位置,当修复读出错位置完成之后,重发这个读请求,那么这次读请求其实是想读旧值,而其实这次读到的是新值,出现一致性问题。Raid1没有保证短时间内对同一个数据块同时读写的一致性,通常这是由上层文件系统层来保证的。

2、读均衡为什么能达到均衡,读均衡算法还有哪些缺陷?

因为当多个读并发的时候,可以尽可能均衡到各个盘中,提高并发读性能,即可以同时读,这样既利用每个盘的带宽提高了整体带宽,又均衡了每个盘的IO负载;而如果多个读是连续的,那么这几个读都落在一块盘上,因为不会发生磁头抖动,进而提高读性能。

但是缺陷还是有的:如果一个读IO很大,也只能选出一个盘作为读盘;更糟糕的是,如果连续多个读IO是顺序读,那么仍然落在一块盘上,导致顺序读性能受限于单盘性能;

解决办法我目前有两种思路:1、条带化,raid0就是这么干;2、bio切分,将大bio切分成小bio,并且限制每个盘的读IO的pending个数。

3in_sync的作用?

       在raid1中有两种in_sync,一种是mddev->in_sync,一种是rdev->flags的In_sync标志位。

mddev->In_sync标志位的作用,超级块中设计一个in_sync标志, 没有IO时,in_sync设置为1,并写回磁盘。 写操作遇到in_sync=1时,则先修改in_sync=0并写回 磁盘之后才执行。

rdev->flag的In_sync位为0,表示该盘不是active disk,不能工作,不可对其操作;In_sync位为1,表示该盘是active disk。

4R1BIO_Returned标志位的作用?

bio_endio之前要进行test_and_set_bit(R1BIO_Returned, &r1_bio->state)来判断是否已经endio了,如果已经endio了,就不再进行bio_endio。R1BIO_Returned标志位的作用就在于此,当设置了延迟写的时候,存在还没有真正将所有盘的写操作完成的时候endio的,所以在真正将所有盘都返回的时候调用raid_end_bio_io(),会出现已经设置R1BIO_Returned的情景,则不需要再endio了。

5IO_BLOCKED标志位的作用?

如果之前读失败的盘为只读状态,在守护进程处理读失败的时候,将r1_bio的该盘bio标记为IO_BLOCKED;接着调用read_balance函数,如果重新指定读盘成功,那么就重发read请求;如果重发的这次read请求还是失败了,同样还是会唤醒守护进程来处理读出错流程,这时又会调用到read_balance函数,而将之前的IO_BLOCKED传入进来,参与到这些流程中。也就是在只读盘上读失败之后,重发读请求,再次读失败的场景会使用到。

6make_request函数中的do_barriersdo_sync变量的作用?

  do_barriers标志接收到的bio的BIO_RW_BARRIER是否置位。如果接收到的上层bio->bi_rw的BIO_RW_BARRIER置位,则为1;BIO_RW_BARRIER不置位,则为0。

  do_barriers有两个用途:

    1、根据do_barriers来设置r1_bio->state的R1BIO_Barrier位;

    2、根据do_barriers来设置要下发的bio的BIO_RW_BARRIER位。

7r1_bioconf结构中都有retry_list,但是r1_bio中没有pending_bio_list,这是为什么?

因为retry_list是由list_head组织起来的链表,其中的每个元素是r1_bio,对于这种组织方式,需要在每个r1_bio中都有一个list_head的结构从而可以找到上一项和下一项,这是一个双向链表;

  而pending_bio_list是由bio组织起来的链表,其中的每个元素直接就是bio,直接用bio->bi_next就可以找到下一项了,这是一个单向链表。

8、为什么用户的read io是在make_request中下发的,而write io是在raid1d中下发的?

因为写io需要修改bitmap,在make_request中先标记一下DRITY位表示需要下刷,而放在deamon中,可以攒集一些write bio用来批量下刷。为了保证正确性,这些write bio在下刷之前要保证bitmap已经下刷到磁盘,所以在批量下刷写之前可以做到bitmap达到批量同步下刷,节省开销。

转载请注明出处:http://www.cnblogs.com/fangpei/

Raid1源代码分析--一些补充的更多相关文章

  1. Raid1源代码分析--开篇总述

    前段时间由于一些事情耽搁了,最近将raid1方面的各流程整理了一遍.网上和书上,能找到关于MD下的raid1的文档资料比较少.决定开始写一个系列的关于raid1的博客,之前写过的一篇读流程也会在之后加 ...

  2. Raid1源代码分析--同步流程

    同步的大流程是先读,后写.所以是分两个阶段,sync_request完成第一个阶段,sync_request_write完成第二个阶段.第一个阶段由MD发起(md_do_sync),第二个阶段由守护进 ...

  3. Raid1源代码分析--Barrier机制

    本想就此结束Raid1的专题博客,但是觉得Raid1中自己构建的一套barrier机制的设计非常巧妙,值得单独拿出来分析.它保证了同步流程和正常读写流程的并发性,也为设备冻结/解冻(freeze/un ...

  4. Raid1源代码分析--写流程

    正确写流程的总体步骤是,raid1接收上层的写bio,申请一个r1_bio结构,将其中的所有bios[]指向该bio.假设盘阵中有N块盘.然后克隆N份上层的bio结构,并分别将每个bios[]指向克隆 ...

  5. Raid1源代码分析--读流程(重新整理)

    五.Raid1读流程分析 两个月前,刚刚接触raid1,就阅读了raid1读流程的代码,那个时候写了一篇博客.现在回过头看看,那篇的错误很多,并且很多地方没有表述清楚.所以还是决定重新写一篇以更正之前 ...

  6. Raid1源代码分析--初始化流程

    初始化流程代码量比较少,也比较简单.主要是run函数.(我阅读的代码的linux内核版本是2.6.32.61) 四.初始化流程分析 run函数顾名思义,很简单这就是在RAID1开始运行时调用,进行一些 ...

  7. Raid1源代码分析--读流程

    这篇博文不足之处较多,重新整理了一下,链接:http://www.cnblogs.com/fangpei/p/3890873.html 我阅读的代码的linux内核版本是2.6.32.61.刚进实验室 ...

  8. 转:SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...

  9. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

随机推荐

  1. linux下mysql5.5的安装

    #rpm –qa|grep –i mysql查看已安装的mysql版本 如果有已存在的mysql版本则删除 安装服务端和客户端,去Oracle官网下载: # rpm -ivh MySQL-serve ...

  2. 【转】解决警告 warning: directory not found for option

    转:http://blog.sina.com.cn/s/blog_6f72ff900101es6x.html 解决方法: 选择项目名称----->Targets----->Build Se ...

  3. Java数据库连接之配置ODBC数据源

    java使用JDBC-ODBC桥接连接SQLServer数据库需要配置ODBC数据源,配置步骤如下: 1.进入控制面板,找到管理工具 2.看到ODBC数据源,有64位和32位的,如果你的数据库是64位 ...

  4. C#总结项目《影院售票系统》编写总结完结篇

    回顾:昨天总结了影院售票系统核心部分-售票,整个项目也就完成了2/3了,需求中也要求了对销售信息的保存,今天就继续总结销售信息的保存以及加载销售信息. 分析:退出程序时将已售出票集合中的对象循环写入到 ...

  5. 网页JavaScript4

    表单验证:一.非空验证:1.内容是不是空的.判断值的长度是不是0.length属性.压缩空格的函数. 2.内容是不是改变了. 二.对比验证:1.验证两个控件值的关系(相同,大小) 2.验证控件的值与某 ...

  6. js数组的操作及数组与字符串的相互转化

    数组与字符串的相互转化 <script type="text/javascript">var obj="new1abcdefg".replace(/ ...

  7. 基于jQuery仿uploadify的HTML5图片上传控件jquery.html5uploader

    (function($){ var methods = { init:function(options){ return this.each(function(){ var $this = $(thi ...

  8. 显示推送数据到mq成功,但是mq管理器中消息数量没增长

    看服务器上的mq配置,看看mq_log,是不是存储满了?

  9. tomcat startup.sh提示java.lang.OutOfMemoryError: PermGen space

    JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m"if [ -z "$LOGGING_MANAGER& ...

  10. 基于脚本的动画的计时控制(“requestAnimationFrame”)(转)

    requestAnimationFrame 方法的支持,该方法通过在系统准备好绘制动画帧时调用该帧,从而为创建动画网页提供了一种更平滑更高效的方法.在此 API 之前,使用 setTimeout 和  ...