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. Sorting File Contents and Output with sort

     Sorting File Contents and Output with sort   Another very useful command to use on text file is  so ...

  2. 快速优化yum (for centos5.5)

    定义yum超时时间:vi /etc/yum.conftimeout=120 修改源:(全部复制粘贴即可)cd /etc/yum.repos.d/mv rhel-debuginfo.repo rhel- ...

  3. 反编译 APKTool 逆向助手

    最佳实践--Android逆向助手 1.点击"反编译apk,完成后res下的所有资源就都可以正常使用了,相当于apktool的功能------目前已失效,但是直接用rar解压是可以的!2.点 ...

  4. The requested page cannot be accessed because the related configuration data for the page is invalid

    当在VS2013下开发web site时,调试时都是在IIS Express中进行的,没有问题.当部署到IIS中,出现:The requested page cannot be accessed be ...

  5. asp.net微信开发第九篇----模板消息的使用

    微信平台的模板消息,使用起来非常好,效果如下: 和平时我们微信中关注信用卡官方微信,如果消费了,信用卡官方微信就返回一个模板消息给我们告知,余额还有多少,消费了多少. 使用的步骤,我只简单介绍了怎么使 ...

  6. CSS3中的transform变形

    在CSS3中,用Transform功能可以实现文字或图像的旋转.缩放.倾斜.移动这四种类型的变形,这四种变形分别使用rotate.scale.skew和translate这四种方法来实现.将这四种变形 ...

  7. (转)SQL流程控制语句学习(一):变量及控制语句种类

    1.局部变量 用户自己定义的,称局部变量,以@标识. 作用范围:定义局部变量的批处理.存储过程.触发器和语句块 局部变量的定义: declare @局部变量名 数据类型 注意:变量的类型不能是text ...

  8. Arcgis server - ' packaging failed '

    我在使用ARCCatalog发布地图服务时,报这个错:packaging failed 然后我从头试,发现它提示说我的目录'C:\Users\Administrator\AppData\Local\E ...

  9. jQuery--jqChart折线图使用eval处理返回数据无效的解决方法

    jquery初学者 查了很多帖子,jqchart插件做折线图时,处理返回数据时全都是eval,但我怎么也弄不出来,后来发现: 1.根本不需要eval处理,直接截取字符串即可(返回值要拼接好): 2.处 ...

  10. HTML5 canvas中的转换方法

    转换方法 scale(scalewidth,scaleheight)                缩放当前绘图至更大或更小 scalewidth         缩放当前绘图的宽度 (1=100%, ...