MD中bitmap源代码分析--数据结构
本篇分析bitmap的数据结构的设计,并基于此分析bitmap的工作机制。
为了后面更清楚的理解,先有个总体印象,给出整体的结构图:
在下面的描述中涉及到的内容可以对照到上图中相应部分,便于理解。
首先,我们从宏观的角度来分析整体结构。bitmap file存在于磁盘,内部存放着很多个bit,每个bit对应于磁盘数据中的一个chunk。在内存空间中也存在一个区域存放bitmap file缓存,与磁盘bitmap file的每个bit一一对应。内存空间中还存在一个区域存放filemap_attr,用来管理bitmap file缓存中每个page的页属性。内存空间中还存在一个区域存放和管理*bmc,用来管理对应bitmap file中的bit是否置位和未完成的最大请求数。而这些内存区域的操作都由bitmap这个大结构体关联起来。如下图所示。
1. bitmap的结构体有比较多的字段,这里关注几个重要的字段。
struct bitmap {
struct bitmap_page *bp; /*指向内存bitmap页的结构*/
……
unsigned long chunks; /*阵列总的chunk数*/
……
struct file *file; /*bitmap文件*/
……
struct page **filemap; /*bitmap文件的缓存页*/
unsigned long *filemap_attr; /*bitmap文件缓存页的属性*/
unsigned long file_pages; /* 1、初始化时当做page号累加,
2、初始化完成之后,为bitmap file中的page数
*/
……
};
这里filemap是指向一系列page结构缓存页的指针构成的数组,所以是page**类型。其在内存中的结构和与bitmap file缓存的关系如下图所示。
2. 其中struct bitmap_page结构如下:
struct bitmap_page {
char *map; /*指向实际分配的内存页*/
unsigned int hijacked:1; /* 表示是否被劫持。
置1的时候说明,内存空间不够的时候使用,
这时直接将map指针作为两个*bmc
*/
unsigned int count:31; /*该页上有多少脏的chunk */
};
bp的整体结构如下如所示:
在正常情况下(内存充足),bitmap的bp字段指向一片内存区域,该内存区域就是逐一存放的bitmap_page结构体,也就是结构体数组。而每个这样一个结构体中存在一个map指针,在需要的时候就会在内存中开辟一个page的空间,用来存放逐一存放*bmc。这里map指针指向的page是动态分配的,在需要的时候才会分配page并设置使用相应的*bmc。
对于bp指针指向的bitmap_page结构,内部分为3个字段。其中的hijacked字段大多数情况下都是置为0的,这也就是内存空间足够分配page的正常情况。这种情况下一个*bmc管理1个bitmap file缓存中的1个bit,一个*map指针管理一个page,而一个page可以存放2048个*bmc(一个*bmc为16位,后面会介绍到),也就是一个map指针管理2048个bitmap file缓存中的bit,count用来作为该map指针管理下的这2048个*bmc对应有多少脏的chunk计数。如下图所示。
hijacked字段置为1的情况十分少见,只有在内存空间不够分配page的时候才会将hijacked字段置为1。在这种情况内存不足,分配不了page空间,那么就退而求其次,将*bmc的管理粒度变大,具体方法如下。bitmap_page结构中的3个字段, map指针本来是要指向page的,但是page没有空间分配,所以就直接将map指针另作它用。指针的大小不论是32位还是64位,其大小至少能容纳下32位,即2个*bmc。那么就直接将map指针的前32位看作是2个*bmc,一个*bmc管理1024个bitmap file缓存中的bit,这样两个*bmc管理2048个bit,正好与正常情况下一个bitmap_page结构管理的bit数目一致,只是管理bit的粒度变大了;而count字段仍然来统计这2048个bit对应有多少脏的chunk的计数。如下图所示。
3. 实际动态分配的每个内存页,每16bit管理对应bitmap文件的一个bit,一个bit对应一个chunk(数据块)。这16bit在代码中记作*bmc,它的作用如下:
NEEDED_MASK——表示该bit对应的chunk是否需要同步;
RESYNC_MASK——表示该bit对应的chunk是否正在同步;
NEEDED_MASK和RESYNC_MASK标志是不会同时存在的,盘阵需要同步时,会先设置NEEDED_MASK标志,当下次检查到有NEEDED_MASK标志时,表示需要同步,此时清除该标志,设置RESYNC_MASK标志,进行同步。如果同步出错,则清除RESYNC_MASK标志,设置NEEDED_MASK标志。内存bitmap的另一个作用是在精准恢复或者同步时判断一个bitmap-chunk是否需要恢复或者同步,即NEEDED_MASK和RESYNC_MASK的作用。
低14位是counter,用来统计对应的chunk尚未完成的写请求的计数。真正的计数值是从2开始累加,表示有写操作(比如有2个未完成写操作,则值为4)。counter的值为0、1、2均为没有写操作,是特殊状态:
*bmc=0——该bit位需要下刷;
*bmc=1——该bit位需要清零;
*bmc=2——该bit对应的chunk上的写操作全部完成,表示该bit可以被清除并下刷。从2开始计数。
*bmc与bitmap file缓存的对应关系如下如所示:
4. Bp数组中的map字段是一个指针,指向一个page页,该page页中顺序存放*bmc,一个page可以存放2048个*bmc。一个*bmc对应bitmap file中的一个bit,也就是对应数据中的一个chunk。也就是说bp数组的第二项的map指针指向的page页的第一个*bmc,是整体的第2049个*bmc(下标为0称为第1个)。
*bmc实际作用是控制bitmap的置位与复位,并且也控制一个chunk上的请求不能超过最大值(14bit表示的最大整数),达到最大值的时候会进行IO schedule。
当内存空间不足够分配*bmc的时候,那么hijacked置位,将map指针本身当做两个*bmc,此时一个*bmc就不再只是对应bitmap file中的一个bit,而是半个page的bit,两个*bmc可以管理正好一个page的bit。也就是说如果空间不够的话,*bmc的管理粒度就增大了。
数据chunk、bp、*map page和attr都是顺序排列的,可以使用顺序寻找,一一对应的方法将他们关联起来。
5. filemap_attr表示bitmap文件缓存页的属性,使用4bit来表示:
BITMAP_PAGE_DIRTY——表示内存bitmap有bit被置位,但是bitmap file对应的位没有被置位,因此该page需要同步刷到磁盘,写磁盘完成才能继续;
BITMAP_PAGE_CLEAN——这是一个过渡状态,表示内存bitmap有可以清除的bit,则需要清除该bit,然后过渡到BITMAP_PAGE_NEEDWRITE状态;
BITMAP_PAGE_NEEDWRITE——表示内存bitmap有bit被清除,但是bitmap file对应的位没有被清除,因此该page需要刷到磁盘,但是异步进行的,因为即使写失败,最多带来额外的同步,不带来数据的危害。
其在内存中的结构和与bitmap file缓存的关系如下如所示:
6. 分析bitmap整体结构关系:
bitmap在内存中相关结构的关系如下如所示:
Bitmap对于内存和磁盘的交互关系如下如所示:
为了便于理解,下面给出一个计算实例,以3个page的bit为例。计算过程在红字中标出,如下图所示:
将上述结构串联起来,得到一个bitmap的整体结构,如下图所示:
上图中,实线代表的是对象关系,虚线代表的是控制关系。
重新回顾一次“概要”一章中的故事。首先当没有bitmap的时候,就只有磁盘中存在有Data而没有其他结构,如图中右下角;当引入bitmap之后,则在磁盘中还存在了一种“数据”叫做bitmap file,bitmap file的一个bit对应盘阵的一个chunk,在盘阵数据写入前,设置该chunk对应的bit,盘阵写入完成,则清除该bit。要进行同步时,参照bitmap,只有置位的bit对应的chunk才需要进行同步,这样缩短了同步的时间,提高了效率。
bitmap原理很明了,按照这个原理直接进行实施也是可以的,但直接这样实施的话,由于一次数据块的写入多了两次磁盘访问(bitmap的设置和清除),写入效率会受到较大影响,所以还需要考虑一些优化。优化主要是两方面的:
1、bitmap设置后批量写入;
2、bitmap延时清除。
这两方面的优化,需要在内存中构建和磁盘bitmap文件对应的数据bitmap file缓存,bitmap操作首先在缓存中进行,必要时才进行真正的磁盘操作。内存中bitmap file缓存与磁盘上的bitmap file每个bit一一对应,所以内存bitmap file缓存中的一个bit也与对应的磁盘bitmap file中的bit一样对应于Data中的一个chunk。对于bitmap file缓存自身的每一个page都有filemap_attr来管理页状态,并且bitmap file缓存中的每一个bit在内存中都有16个bit的结构*bmc来进行管理。
bitmap结构体下,**filemap指向bitmap file缓存的一个page,filemap_attr字段管理一个bitmap file缓存page的页状态,bp->map指向一个page(需要时才分配page空间),其中存放的都是*bmc,一个*bmc有16位,每个*bmc用来管理对应的bitmap file缓存的1个bit,bitmap file缓存与磁盘上的bitmap file互相对应,其中每个bit对应了Data中的相应chunk的数据写入状态,就将整个bitmap框架连接了起来。
转载请注明出处:http://www.cnblogs.com/fangpei
MD中bitmap源代码分析--数据结构的更多相关文章
- MD中bitmap源代码分析--入题概述
在MD模块中,各级raid都使用的一份bitmap的源码,也就是说共用一种bitmap的流程,下面以raid1的使用为例来分析bitmap的工作原理. 在使用raid1磁盘阵列的时候,对于数据的可靠性 ...
- MD中bitmap源代码分析--SYNC IO和RAID5的补充
最近在做bwraid的R6的设计工作,需要调研一下bitmap下刷磁盘的IO属性(是否为SYNC IO),还有raid5中bitmap的存储和工作方式. 1.bitmap刷磁盘是否为 SYNC IO? ...
- MD中bitmap源代码分析--清除流程
bitmap的清零是由bitmap_daemon_work()来实现的.Raid1守护进程定期执行时调用md_check_recovery,然后md_check_recovery会调用bitmap_d ...
- MD中bitmap源代码分析--状态机实例
1. page_attrs的状态转换关系 之前说过,bitmap的优化核心是:bitmap设置后批量写入:bitmap延时清除.写bit用bitmap_statrwrite() + bitmap_un ...
- MD中bitmap源代码分析--设置流程
1. 同步/异步刷磁盘 Bitmap文件写磁盘分同步和异步两种: 1) 同步置位:当盘阵有写请求时,对应的bitmap文件相应bit被置位,bitmap内存页被设置了DIRTY标志.而在下发写请求给磁 ...
- Memcached源代码分析 - Memcached源代码分析之消息回应(3)
文章列表: <Memcached源代码分析 - Memcached源代码分析之基于Libevent的网络模型(1)> <Memcached源代码分析 - Memcached源代码分析 ...
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6633311 在上一篇文章中,我 们分析了And ...
- Java中arraylist和linkedlist源代码分析与性能比較
Java中arraylist和linkedlist源代码分析与性能比較 1,简单介绍 在java开发中比較经常使用的数据结构是arraylist和linkedlist,本文主要从源代码角度分析arra ...
- FreeBSD 5.0中强制访问控制机制的使用与源代码分析【转】
本文主要讲述FreeBSD 5.0操作系统中新增的重要安全机制,即强制访问控制机制(MAC)的使用与源代码分析,主要包括强制访问控制框架及多级安全(MLS)策略两部分内容.这一部分讲述要将MAC框架与 ...
随机推荐
- [AngularJS] angular-md-table for Angular material design
Download from npm:https://www.npmjs.com/package/angular-md-table +: Responsive: Has both Mobile view ...
- Linux 磁盘挂载和mount共享
针对Linux服务器的磁盘挂载mount和共享做简单操作说明: 1. 查看已使用的磁盘情况 df –h 2. 查看所有磁盘 fdisk –l 3. 查看指定磁盘“/dev/xvde”的分区情 ...
- SQL 使用Cursor(游标)遍历结果集
使用Cursor(游标)可以在存储过程中遍历select 结果集,对其进行相关的操作. Cursor(游标)语法格式 DECLARE 游标名称 CURSOR FOR SELECT 字段1,字段2,字段 ...
- Ubuntu apt-get 错误 -11 -system error
错误图片 上述错误是dns解析错误,不能解析域名了,所以也访问不了 解决办法,添加dns,命令如下 sudo vim /etc/resolv.conf 添加 nameserver (此外填写域名服务器 ...
- Android系统更改状态栏字体颜色
随着时代的发展,Android的状态栏都不是乌黑一片了,在Android4.4之后我们可以修改状态栏的颜色或者让我们自己的View延伸到状态栏下面.我们可以进行更多的定制化了,然而有的时候我们使用的是 ...
- CentOS 7 修改hostname
centOS 7 里面修改hostname的方式有所改变,修改/etc/hosts和/etc/sysconfig/network两个文件已经不能生效.使用的新命令是 : hostnamectl set ...
- 为什么不使用frame框架的原因
框架的优点 重载页面时不需要重载整个页面,只需要重载页面中的一个框架页(减少了数据的传输,增加了网页下载速度) 方便制作导航栏 框架的缺点 会产生很多页面,不容易管理 不容易打印 浏览器的后退按钮无效 ...
- MS SQL Sever数据库还原
一.右键 数据库 二.点击 [还原文件和文件组(E)...],弹出下图的窗口界面 1.在 目标数据库 的输入框填写你的数据库名(注意这是新建一个数据库供还原使用,不能还原到已有的数据库) 三.点击[源 ...
- Arcgis android - Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE
报错: Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE Please check logcat output for more deta ...
- web项目环境搭建(1):建立一个maven项目
一.maven简介以及常用概念 1.Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使 ...