前文简单的介绍了block device,别急,虽然这个系列的主要目的是介绍Flashcache,这一篇还是不会切入正题,因为我们还需要先了解下什么是device mapper。
假如一台主机插入了多块硬盘,单块硬盘的容量和性能都是有限的,如果能将多块硬盘组合一个逻辑的整体,对于这台主机来讲,就实现了最简单意义上的“云存储”。有很多方法可以实现这个目的,比如Raid卡硬件,比如现在很流行的分布式文件系统的replica机制,等等。Linux内核也看到了这个需求,于是2.6有了device mapper,当然device mapper不只是满足这一个需求,对于多路径IO也做了支持。
3. Device Mapper
简单来讲,Device Mapper是一种组合多个块设备变成一个逻辑块设备的机制。
Device Mapper的设计实现主要分为三层:
- Mapped Device: 映射出的逻辑设备
- Mapping Table: 映射规则表
- Taget Device: 底层的实际设备(可以是物理的块设备,也可以是Device Mapper映射出的逻辑设备),根据组合规则的不同,实际设备的使用方式不一样,区分为不同的类型。
(图片出处:参考[1])
Target device的类型,内核自带的几种包括(linux/include/linux/device-mapper.h):
- linear: 线性,顺序使用target
- mirror: 镜像,类似于Raid 1
- stripped: 条带,类似Raid 0
- snapshot: 快照,LVM2的快照基于此实现
- multipath: 多路径IO
- crypt: 加密,可以实现加密存储
- delay: 延时IO
- …
Target type是一种模块化的插件接口,允许自定义。Flashcache就是利用这个接口定义了一种新的target type,将SSD和普通磁盘定义为两种新的target device,设计了缓存的映射规则,逻辑组合成一种新的块设备。
3.1 mapped_device
mapped_device定义了逻辑设备,对内核来说,可以把逻辑设备当作一种普通的block_device。
struct mapped_device { struct request_queue *queue; struct gendisk *disk; char name[16]; void *interface_ptr; struct workqueue_struct *wq; struct dm_table *map; struct bio_set *bs; struct block_device *bdev; make_request_fn *saved_make_request_fn; ... };
3.2 dm_table
dm_table描述了逻辑设备和物理设备之间的映射关系。
struct dm_table { struct mapped_device *md; atomic_t holders; unsigned type; unsigned int num_targets; struct dm_target *targets; struct list_head devices; fmode_t mode; ... };
3.3 dm_target
dm_target定义了一个具体的target device。
struct dm_target { struct dm_table *table; struct target_type *type; void *private; ... };
3.4 target_type
target_type定义一种target device的类型。其中有几个比较重要的函数:
- map: io映射规则函数
- ctr: 设备构造函数
- dtr: 设备析构函数
- end_io: IO操作完成后调用
- status: 获取设备状态信息
- ioctl:ioctl接口
struct target_type { uint64_t features; const char *name; struct module *module; unsigned version[3]; dm_ctr_fn ctr; dm_dtr_fn dtr; dm_map_fn map; dm_map_request_fn map_rq; dm_endio_fn end_io; dm_request_endio_fn rq_end_io; dm_flush_fn flush; dm_presuspend_fn presuspend; dm_postsuspend_fn postsuspend; dm_preresume_fn preresume; dm_resume_fn resume; dm_status_fn status; dm_message_fn message; dm_ioctl_fn ioctl; dm_merge_fn merge; dm_busy_fn busy; dm_iterate_devices_fn iterate_devices; dm_io_hints_fn io_hints; /* For internal device-mapper use. */ struct list_head list; };
3.5 dm_register_target
dm_register_target函数用于注册 一个新的target type。
int dm_register_target(struct target_type *tt) { ... list_add(&tt->list, &_targets); ... }
4. Device Mapper工具
操作系统提供了一些管理device mapper的工具,需要确认相关的包已经安装。
$rpm -qa | grep device-mapper device-mapper-libs-1.02.62-3.el6.x86_64 device-mapper-1.02.62-3.el6.x86_64 device-mapper-event-libs-1.02.62-3.el6.x86_64 device-mapper-event-1.02.62-3.el6.x86_64
4.1 dmsetup
Device Mapper的工具主要是dmsetup,可以用来创建/修改/删除/查看DM设备,Flashcache的创建和装载工具flashcache_create/flashcache_load都是调用的dmsetup,只是自己包装了一层。
创建一个新的dm设备的语法为:
dmsetup create dm_device start_sector nr_sectors target argument
不同的target type,带的argument不一样,ctl函数定义了如何根据参数来构建dm设备的逻辑。如果组合的参数规则复杂,也可以将参数写入到文件中,然后通过文件参数来执行创建。
dmsetup create dm_device file_name
以下是一个已经创建好的Flashcache设备的信息:
$sudo dmsetup info Name: cachedev State: ACTIVE Read Ahead: 256 Tables present: LIVE Open count: 1 Event number: 0 Major, minor: 253, 0 Number of targets: 1 $sudo dmsetup status cachedev: 0 3093559296 flashcache stats: reads(731952), writes(554131825) read hits(663370), read hit percent(90) write hits(429687559) write hit percent(77) dirty write hits(185872576) dirty write hit percent(33) replacement(31918), write replacement(13045343) write invalidates(0), read invalidates(1) pending enqueues(13604453), pending inval(13604453) metadata dirties(347477454), metadata cleans(347477257) metadata batch(665458755) metadata ssd writes(29495864) cleanings(347468476) fallow cleanings(536679) no room(7246713) front merge(286174542) back merge(57729678) disk reads(68585), disk writes(368002849) ssd reads(347815066) ssd writes(562902592) uncached reads(1098), uncached writes(20849965), uncached IO requeue(0) uncached sequential reads(0), uncached sequential writes(0) pid_adds(2), pid_dels(2), pid_drops(0) pid_expiry(0) $sudo dmsetup table cachedev: 0 3093559296 flashcache conf: ssd dev (/dev/fioa), disk dev (/dev/sdb1) cache mode(WRITE_BACK) capacity(306408M), associativity(512), data block size(4K) metadata block size(4096b) skip sequential thresh(0K) total blocks(78440448), cached blocks(77048243), cache percent(98) dirty blocks(102), dirty percent(0) nr_queued(0) Size Hist: 1024:2 4096:555006431
未完待续
参考:
[1].Understanding Device-mapper in Linux 2.6 Kernel [Oracle Support ID 456239.1]
[2].Linux 内核中的 Device Mapper 机制
[3].Device-mapper Resource Page
原文链接: http://www.ningoo.net/html/2011/all_things_about_flashcache_2.html