dm-cache 与 bcache
- See more at: http://wangxu.me/blog/#sthash.smQmCr76.dpuf
文章来源:http://blog.csdn/cybertan/article/details/9475767
Linux块设备加速缓存之bcache
bcache是linux内核块层cache。它使用类似SSD来作为HDD硬盘的cache,从而起到加速作用。 HDD硬盘便宜并且空间更大,SSD速度快但更贵。如果能两者兼得,岂不快哉?bcache能做到。 bcache使用SSD作为其他块设备cache。类似ZFS的L2Arc,但bcache还增加了写回策略,并且是与文件系统无关的。bcache被设计成只需要最小的代价,无需配置就能在所有环境中工作。默认状态下bcache不缓存顺序IO,只缓存随机读写。bcache适用于桌面、服务器,高级存储阵列,甚至是嵌入式环境。
设计bcache目标是让被缓存设备与SSD一样快(包括缓存命中、缓存不命中、透写和回写)。现在还未达到初衷,特别是顺序写。同时测试结果表明离目标很接近,甚至有些情况下表现更好,例如随机写。 bcache是数据安全的。对于写回策略缓存来说,可靠性是非常重要的,出错就意味着丢失数据。bcache是用电池备份阵列控制器的替代选择,同时也要求bcache在异常掉电时也是数据安全的。对于写而言,必须在所有数据写到可靠介质之后才能向上层返回写成功,在异常掉电情况下,写不能是部分完成的。大量工作已经投入到这部分数据安全的工作中。
bcache性能设计目标是等同于SSD。最大程度上去最小化写放大,并避免随机写。bcache将随机写转换为顺序写,首先写到SSD,然后回写缓存使用SSD缓存大量的写,最后将写有序写到磁盘或者阵列上。对于RAID6阵列,随机写性能很差,还要花费不菲的价格购买带有电池保护的阵列控制器。现在有了bcache,你就可以直接使用linux自带的优秀软RAID,甚至可以在更廉价的硬件上获取更高的随机写性能。
特性 1、一个缓存设备可以作为多个设备的缓存,并且可以在设备运行时动态添加和删除缓存。 2、异常关机恢复,只有当写到磁盘后缓存才会确认写完成。 3、正确处理写阻塞和刷缓存 4、支持writethrough, writeback和writearound 5、检测并避开顺序IO(可配置关闭该选项) 6、当检测到SSD延迟超过配置边界值,减少到SSD流量(当一个SSD作为多个磁盘缓存时使用) 7、缓存不命中时预读(默认关闭) 8、高性能的writeback实现:脏数据都是排序后再回写。如果设置了writeback水位线,PD控制器会根据脏数据比例来平滑处理到后台writeback流量。 9、使用高效率了B+树,bcache随机读可以达到1M IOPS 10、稳定,已经有产品应用
性能
7/25/12 随机测试 在我的测试机上,我将SSD盘划分为两个相同大小的分区,一个分区用于测试SSD裸盘,另一个作为硬盘缓存。 bcache配置修改:cache_mode设置为writeback,writeback_percent设置为40。(如果writeback_percent不为0,bcache使用PD控制器根据缓存的脏数据块来平滑处理下发到磁盘的流量)。同时还关闭了拥塞阀值,因为当SSD延迟达到极限时,如果bcache切换到writethrough将会影响结果。
SSD盘为Intel 160G MLC SSD,也就是Intel SSDSA2M160。 FIO作为性能测试,测试脚本如下: [global] randrepeat=1 ioengine=libaio bs=4k ba=4k size=8G direct=1 gtod_reduce=1 norandommap iodepth=64 FIO运行在SSD裸设备上,但对于这类性能测试软件来说应该没有影响。
裸SSD设备上随机写测试结果如下:
root@utumno:~# fio ~/rw4k
randwrite: (g=0): rw=randwrite, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=64
fio 1.59
Starting 1 process
Jobs: 1 (f=1): [w] [100.0% done] [0K/49885K /s] [0 /12.2K iops] [eta 00m:00s]
randwrite: (groupid=0, jobs=1): err= 0: pid=1770
write: io=8192.3MB, bw=47666KB/s, iops=11916 , runt=175991msec
cpu : usr=4.33%, sys=14.28%, ctx=2071968, majf=0, minf=19
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
issued r/w/d: total=0/2097215/0, short=0/0/0
Run status group 0 (all jobs):
WRITE: io=8192.3MB, aggrb=47666KB/s, minb=48810KB/s, maxb=48810KB/s, mint=175991msec, maxt=175991msec
Disk stats (read/write):
sdb: ios=69/2097888, merge=0/3569, ticks=0/11243992, in_queue=11245600, util=99.99%
添加了bcache:
root@utumno:~# fio ~/rw4k
randwrite: (g=0): rw=randwrite, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=64
fio 1.59
Starting 1 process
Jobs: 1 (f=1): [w] [100.0% done] [0K/75776K /s] [0 /18.5K iops] [eta 00m:00s]
randwrite: (groupid=0, jobs=1): err= 0: pid=1914
write: io=8192.3MB, bw=83069KB/s, iops=20767 , runt=100987msec
cpu : usr=3.17%, sys=13.27%, ctx=456026, majf=0, minf=19
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
issued r/w/d: total=0/2097215/0, short=0/0/0
Run status group 0 (all jobs):
WRITE: io=8192.3MB, aggrb=83068KB/s, minb=85062KB/s, maxb=85062KB/s, mint=100987msec, maxt=100987msec
Disk stats (read/write):
bcache0: ios=0/0, merge=0/0, ticks=0/0, in_queue=0, util=0.00%
添加了bcache之后IOPS为18.5K,裸SSD设备为12.2K。bcache表现更佳是因为bcache按顺序将写请求发送到SSD,但额外加入了更新索引的开销。bcache对随机写做了优化,bcache还从高IO深度(64)获益,因为在高IO深度的情况下就可以将多次下标更新合并为一次写请求。 高IO深度就代表着高系统负载,当IO深度下调时IOPS也出现变化:
IO depth of 32: bcache 20.3k iops, raw ssd 19.8k iops
IO depth of 16: bcache 16.7k iops, raw ssd 23.5k iops
IO depth of 8: bcache 8.7k iops, raw ssd 14.9k iops
IO depth of 4: bcache 8.9k iops, raw ssd 19.7k iops
SSD性能在不同IO深度时出现了波动。对于不同的写模型会有不同的结果,我们只关注两者的相对数值。当测试随机4K写,IO深度为1时,bcache写次数是裸SSD设备的两倍:每一次写都需要再更新一次索引。
随机读
IO depth of 64: bcache 29.5k iops, raw ssd 25.4k iops
IO depth of 16: bcache 28.2k iops, raw ssd 27.6k iops
bcache略胜一筹,可能跟要读的数据相关。这里的结论是随机读时bcache与裸SSD读性能是相同的。 这里要注意的是,读4K随机写下去的数据,这样的测试模型对于bcache是不好的。这意味btree都是4K大小,btree将比通常时候大得多。在实际应用中,平均大小是100K。btree变大就意味着索引占用更大的内存空间,并且有一部分是在二级索引。根据个人经验这些开销在大型机器IOPS超过500K时才会有实际影响。 如果大家有其他的测试方法或者我的测试方法中有什么问题请通知邮件告诉我。常见问题 关机、设备移除 系统关机时cache仍然是脏的,就是说后端磁盘的数据并不可靠。如果要保证后端磁盘数据是安全的,就需要手动移动cache或者将cache设置为writethrough模式。
自动挂载 bcache会自动匹配cache和后端设备。匹配过程与设备对系统可用的次序没有关系。 带bcache的根目录分区 为了让根分区能够使用bcache,需要添加rootdelay=3到启动参数,这样才能让udev规则在系统mount根文件系统之前运行。 已格式化过的磁盘或分区 如果一个分区或者磁盘设备启动时没有创建bcache,可能是因为超级块发生错误。为了让bcache能够正确检测到之前的设备,udev规则会首先检查是否符合bcache规则和blkid检查。udev规则检查设备超级块从而识别文件系统类型,如果该超级块不符合bcache文件系统类型那么就不会添加bcache。
# cat /usr/lib/udev/rules.d/61-bcache.rules
....
# Backing devices: scan, symlink, register
IMPORT{program}="/sbin/blkid -o udev $tempnode"
# blkid and probe-bcache can disagree, in which case don't register
ENV{ID_FS_TYPE}=="?*", ENV{ID_FS_TYPE}!="bcache", GOTO="bcache_backing_end"
...
# lsblk -o NAME,MAJ:MIN,RM,SIZE,TYPE,FSTYPE,MOUNTPOINT,UUID,PARTUUID
NAME MAJ:MIN RM SIZE TYPE FSTYPE MOUNTPOINT UUID PARTUUID
sda 8:0 0 111.8G disk
├─sda1 8:1 0 3G part vfat /esp 7E67-C0BB d39828e8-4880-4c85-9ec0-4255777aa35b
└─sda2 8:2 0 108.8G part ext2 93d22899-cd86-4815-b6d0-d72006201e75 baf812f4-9b80-42c4-b7ac-5ed0ed19be65
sdb 8:16 0 931.5G disk
└─sdb1 8:17 0 931.5G part ntfs FAD2B75FD2B71EB7 90c80e9d-f31a-41b4-9d4d-9b02029402b2
sdc 8:32 0 2.7T disk bcache 4bd63488-e1d7-4858-8c70-a35a5ba2c452
└─bcache1 254:1 0 2.7T disk btrfs 2ff19aaf-852e-4c58-9eee-3daecbc6a5a1
sdd 8:48 0 2.7T disk bcache ce6de517-7538-45d6-b8c4-8546f13f76c1
└─bcache0 254:0 0 2.7T disk btrfs 2ff19aaf-852e-4c58-9eee-3daecbc6a5a1
sde 8:64 1 14.9G disk
└─sde1 8:65 1 14.9G part ext4 / d07321b2-b67d-4daf-8022-f3307b605430 5d0a4d76-115f-4081-91ed-fb09aa2318d
在上面的例子中有一个分区之前是ext2文件系统。bcache将通过以下指令自动构建:
# make-bcache -B /dev/sdc /dev/sdd -C /dev/sda2
因为设备/dev/sdc和/dev/sdd标识了bcache文件系统,因此会在系统启动时自动添加,而/dev/sda2则需要手动添加。在/dev/sda2偏移1024处仍残留有之前文件系统的超级块信息,而bcache信息是从4096偏移开始记录,修复的方法是:
# dd if=/dev/zero count=1 bs=1024 seek=1 of=/dev/sda2
在系统重启之后所有磁盘被正确识别:
# lsblk -o NAME,MAJ:MIN,RM,SIZE,TYPE,FSTYPE,MOUNTPOINT,UUID,PARTUUID
NAME MAJ:MIN RM SIZE TYPE FSTYPE MOUNTPOINT UUID PARTUUID
sda 8:0 0 111.8G disk
├─sda1 8:1 0 3G part vfat /esp 7E67-C0BB d39828e8-4880-4c85-9ec0-4255777aa35b
└─sda2 8:2 0 108.8G part bcache 93d22899-cd86-4815-b6d0-d72006201e75 baf812f4-9b80-42c4-b7ac-5ed0ed19be65
├─bcache0 254:0 0 2.7T disk btrfs 2ff19aaf-852e-4c58-9eee-3daecbc6a5a1
└─bcache1 254:1 0 2.7T disk btrfs 2ff19aaf-852e-4c58-9eee-3daecbc6a5a1
sdb 8:16 0 931.5G disk
└─sdb1 8:17 0 931.5G part ntfs FAD2B75FD2B71EB7 90c80e9d-f31a-41b4-9d4d-9b02029402b2
sdc 8:32 0 2.7T disk bcache 4bd63488-e1d7-4858-8c70-a35a5ba2c452
└─bcache1 254:1 0 2.7T disk btrfs 2ff19aaf-852e-4c58-9eee-3daecbc6a5a1
sdd 8:48 0 2.7T disk bcache ce6de517-7538-45d6-b8c4-8546f13f76c1
└─bcache0 254:0 0 2.7T disk btrfs 2ff19aaf-852e-4c58-9eee-3daecbc6a5a1
sde 8:64 1 14.9G disk
└─sde1 8:65 1 14.9G part ext4 / d07321b2-b67d-4daf-8022-f3307b605430 5d0a4d76-115f-4081-91ed-fb09aa2318dd
同样地,残留超级块还会引起类似的其他错误。
英文地址: http://bcache.evilpiepirate/
文章来源:http://blog.csdn/liumangxiong/article/details/17839797
Linux内核之bcache简介
- make-bcache -B /dev/sdb
- make-bcache -C /dev/sdc
make-bcache提供了同时初始化多个设备的功能,并自动绑定缓存设备和后端磁盘: [html] view plain copy
- make-bcache -B /dev/sda /dev/sdb -C /dev/sdc
bcache-tools现在已经包含了udev规则文件,bcache设备可以立即被内核感知。如果没有udev规则,需要手动注册设备: [html] view plain copy
- echo /dev/sdb > /sys/fs/bcache/register
- echo /dev/sdc > /sys/fs/bcache/register
注册了后端磁盘后,bcache设备会出现在/dev/目录下,现在就可以格式化然后使用了。bcache设备默认是透传模式,因此需要绑定缓存。 bcache显示如下: [html] view plain copy
- /dev/bcache<N>
还有(有udev规则文件时): [html] view plain copy
- /dev/bcache/by-uuid/<uuid>
- /dev/bcache/by-label/<label>
如果要开始使用: [html] view plain copy
- mkfs.ext4 /dev/bcache0
- mount /dev/bcache0 /mnt
bcache的sysfs控制项在/sys/block/bcache<N>/bcache。 bcache设备是按集合来管理的,但目前一个集合只支持一个bcache设备,将来会支持多个设备、元数据和脏数据镜像。新cache设备显示为/sys/fs/bcache/<UUID>
cache绑定: 在缓存设备和后端设备都注册之后,还要将缓存设备绑定到后端设备从而使用缓存。绑定操作如下: echo <CSET-UUID> > /sys/block/bcache0/bcache/attach 这个操作只需要做一次就可以了。下一次系统重启时,只需要重新注册所有bcache设备。如果后端设备还有未定回的缓存数据,那么就不会创建/dev/bcache<N>,直到缓存设备回来,尤其在写回策略时特别重要。 如果需要在没有缓存设备的时候强制使用设备: [html] view plain copy
- echo 1 > /sys/block/sdb/bcache/running
注意这里参数是后端设备,而不是bcache设备,何况此时bcache设备还没有创建。如果是使用分区创建的bcache设备,例如sdb2对应的目录是/sys/block/sdb/sdb2/bcache。 在强制使用bcache设备后,缓存设备添加到系统,这个缓存设备的所有缓存数据将会设置为无效。缓存设备的脏数据是不会继续,因为这些脏数据将有可能使现在文件系统崩溃。
错误处理 bcache尝试处理IO错误而不影响正常操作,但如果错误数超过阀值(默认是0,可配置)会关闭缓存并切换到透传模式。 -如果是读错误则尝试直接从后端设备读 -如果是写直达写错误,将缓存对应数据块设置为无效 -去绑定时,刷回脏数据。脏数据写回失败目前是没有处理的。
性能相关问题 bcache有很多配置选项和可调参数。默认值适合于典型配置,如果想要更好性能则需要调整相关参数。 -写性能差 如果写性能不理想,那么建议调到写回策略 [html] view plain copy
- #echo writeback > /sys/block/bcache0/cache_mode
-性能差,或者流量并没有缓存到SSD 默认情况下,bcache不会缓存顺序IO和大文件。 打开顺序IO缓存: [html] view plain copy
- #echo 0 > /sys/block/bcache0/bcache/sequential_cutoff
设置回默认值: [html] view plain copy
- #echo 4M > /sys/block/bcache0/bcache/sequential_cutoff
-流量小,缓存不命中 现实生活中,并不是所有SSD都能提供足够快的速度作为磁盘的缓存,特别一个SSD作为多块磁盘的缓存,或者顺序IO时。所以需要避免SSD成为系统瓶颈。 为了避免bcache设备因为SSD变慢,当延迟超过阀值时逐渐减少流量。需要关闭拥塞控制项: [html] view plain copy
- #echo 0 > /sys/fs/bcache/<cache set>/congested_read_threshold_us
- #echo 0 > /sys/fs/bcache/<cache set>/congested_write_threshold_us
对于读,默认值是2000us(2ms),对于写是20000.
SYSFS - 后端设备 /sys/block/<bdev>/bcache, /sys/block/bcache*/bcache, /sys/fs/bcache/<cset-uuid>/bdev*
SYSFS - 缓存集合 /sys/fs/bcache/<cset-uuid>
SYSFS - 缓存设备 /sys/block/<cdev>/bcache
英文:Documentation/bcache.txt
文章来源:http://blog.csdn/liumangxiong/article/details/18090043
使用 LVM (基于dm-cache) 新的缓存特性
如果你有一台带有慢速硬盘和快速SSD的电脑,你想使用SSD作为快速持久缓存用来提升访问硬盘的速度。然而直到最近,你有三个选择:bcache和dm-cache都upstream,或者Flashcache/EnhanceIO。Flashcache不是upstream。dm-cache要求你首先坐下来,使用计算器计算块的偏移。bcache是三个选择中最全面的。
但是最近LVM已经增减了缓存的支持(构建在dm-cache之上),因此在理论上,你能让已存在的逻辑卷转换到已缓存的设备。
安装
为了在实践中了解是怎样工作的,我在以前的无盘虚拟群集中添加了3块硬盘。
在镜像配置中有两个2TB的WD硬盘。通过蓝色(冷)线连接。在左侧是三星EVO 250GB SSD,作为缓存的红色(热)盘。
另一个新闻:哦,现在品牌制造商的SSD是真的便宜!
lsblk输出如下,sda和sdb是WD硬盘,sdc是三星SSD:
?1 2 3 4 5 6 7 8 9 |
# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
└─sda1 8:1 0 1.8T 0 part
└─md127 9:127 0 1.8T 0 raid1
sdb 8:16 0 1.8T 0 disk
└─sdb1 8:17 0 1.8T 0 part
└─md127 9:127 0 1.8T 0 raid1
sdc 8:32 0 232.9G 0 disk
└─sdc1 8:33 0 232.9G 0 part
|
性能
在创建 缓存之前,先看看硬盘的速率如何. 以下数据包含了 ext4 和 LVM overhead (ie. 体现在文件系统里,并非块存储). 我还用了 O_DIRECT.
HDD writes: 114 MBytes/sec
HDD reads: 138 MBytes/sec
SSD writes: 157 MBytes/sec
SSD reads: 197 MBytes/sec
这些数字并没有体现出SSDs的好处 — 就是随机访问硬盘时,性能没有什么区别.
Terminology
lvmcache(7) [没有什么能拷贝的地方] 文档指出了一些用到的术语:
?1 2 3 4 5 |
origin LV OriginLV large slow LV
cache data LV CacheDataLV small fast LV
for
cache pool data
cache metadata LV CacheMetaLV small fast LV
for
cache pool metadata
cache pool LV CachePoolLV CacheDataLV + CacheMetaLV
cache LV CacheLV OriginLV + CachePoolLV
|
创建 LVs
文档中很夸张的提到,移除错误的 LV 将会完全颠覆之前的 OriginLV, 为了测试这一特性我 在有几个镜像文件的慢速HDDs上创建了一个 OriginLV:
?1 2 3 |
# lvcreate -L 100G -n testoriginlv vg_guests
Logical volume
"testoriginlv"
created
# mkfs -t ext4 /dev/vg_guests/testoriginlv
|
需要注意的是resizing cached LVs功能目前并未提供 (可能以后出来 — 现在只能先移除缓存,从新分配大小再重新创建缓存).
创建缓存层
从文件的角度来说,这并不明确,但是一切都必须在一个简单的卷组中. 也就是说,你必须创建一个既包括慢速和快速的磁盘卷组 - 它并不是简单工作。
因此,我的第一个步骤是扩大我现有的VG ,包括快盘:
?1 2 |
# vgextend vg_guests /dev/sdc1
Volume group
"vg_guests"
successfully extended
|
我创建了快速的SSD两个LVs 。一个是CacheDataLV ,这就是缓存发生。另一个是用于存储被高速缓存在CacheDataLV的数据块的索引的CacheMetaLV 。该文件说, CacheMetaLV应该是千分之一的CacheDataLV的大小,但最少为8MB 。由于我的总可用空间快是232GB ,而我希望有一个1000:1的分裂,我大方的选择一个1GB的CacheMetaLV , 229G的CacheDataLV ,而且会留下一些遗留下来的空间(我最终的分割结果是229:1 ) 。
?1 2 3 4 5 6 7 8 9 10 11 12 13 |
# lvcreate -L 1G -n lv_cache_meta vg_guests /dev/sdc1
Logical volume
"lv_cache_meta"
created
# lvcreate -L 229G -n lv_cache vg_guests /dev/sdc1
Logical volume
"lv_cache"
created
# lvs
LV VG Attr LSize
lv_cache vg_guests -wi-a----- 229.00g
lv_cache_meta vg_guests -wi-a----- 1.00g
testoriginlv vg_guests -wi-a----- 100.00g
# pvs
PV VG Fmt Attr PSize PFree
/dev/md127
vg_guests lvm2 a-- 1.82t 932.89g
/dev/sdc1
vg_guests lvm2 a-- 232.88g 2.88g
|
(你会发现,我的缓存大于我的测试OriginLV ,但是这很好,因为一旦我已经制定了所有的陷阱,我真正的OriginLV将超过1 TB).
为什么要在PV上留下2.88GB的空间?我也不太清楚,只是第一次使用时,我并没有预留空间,结果执行 lvconvert命令后 [如下] 提示需要1GB的扩展空间。
把 CacheDataLV和CacheMetaLV 放到“缓存池”里 :
?1 2 3 |
# lvconvert --type cache-pool --poolmetadata vg_guests/lv_cache_meta vg_guests/lv_cache
Logical volume
"lvol0"
created
Converted vg_guests
/lv_cache
to cache pool.
|
接着把缓存池连到OriginLV来创建最终的缓存工程:
?1 2 |
# lvconvert --type cache --cachepool vg_guests/lv_cache vg_guests/testoriginlv
vg_guests
/testoriginlv
is now cached.
|
结果
看起来还不错? 在使用缓存 LV后,得到的数据如下:
LV-cache writes: 114 MBytes/sec
LV-cache reads: 138 MBytes/sec
和原来硬盘的结果一致.
还好没出什么岔子. MikeSnitzer说明了我的dd测试在dm-cache中无效的原因 Mike Snitzer gave me an explanation of why my test usingddisn’t a useful test of dm-cache.
接下来我会创建一些请求,然后看看他们的性能如何 (就是刚才我提到的问题).
英文原文:Using LVM’s new cache feature
文章来源:http://www.oschina/translate/using-lvms-new-cache-feature
更多推荐
[转]Linux块设备加速缓存bcache和dm-cache:使用SSD来加速服务器
发布评论