使用dm-cache组合SSD与HDD实现高性价比存储

前言:

  先有业务场景与需求,后有解决方案,从上家公司离职已经快三个月了,最近比较闲,整理下困扰上家公司的一个业务场景与解决办法,快忘了都:

业务场景:公司的IDC与阿里云的CDN平台合作,给优酷做CDN缓存,计费方式是根据流量来算,什么概念呢,就是在下午6:00到凌晨12:00,这段时间属于CDN的使用高峰期,在这段时间内所占用的带宽和流量会被CDN平台计算,然后结算付款。问题是,IDC机房的高带宽下,很难将流量跑起来,而且在zabbix的流量图上,中间还会有断层,说明了两个问题:1.流量跑的不稳定。2.有原因限制了流量的速度,可能是带宽,可能是CDN的进程,可能是磁盘的读写速度。

解决办法:既然有了具体的矛盾点,那么就需要逐一排查,具体的排查方法不再赘述,最终的结果是在磁盘的读写上动刀,解决了这个问题,让公司的IDC资源获得了更高的收益。具体怎么解决的呢,基于公司的硬件条件,大部分磁盘为300G的ssd与2T的hdd,在flashcache,b-cache,dm-cache上斟酌了一下,最终选择了dm-cache。

dm-cache是什么呢?

答:在存储系统中,硬盘因其存储介质访问需要寻道操作的缘故,速度缓慢。新生的永久性内存(Persistent RAM或者称之为非易失性内存,固态存储设备(SSD)通常被用作硬盘的高速缓存设备,以提高存储系统的吞吐率。这种架构采用分层存储管理(Hierarchy Storage Management)的思想,结合了PRAM,SSD高速度与HDD的低成本大容量的特性。另外,这种解决方案也可用于提高SAN(Storage Area Network)的性能,并能减轻其负荷。简单的来说,就是将ssd作为hdd的缓存,来提高hdd写的速度。

理论架构如下:

dm-cache设计成由3个物理存储设备来混合成一个逻辑卷的形式。操作模式和缓存策略决定了缓存数据的性能。这三个物理设备分别为:
  • 原始设备:提供主要的慢速存储(通常是一个硬盘或者SAN)
  • 缓存设备:提供高速原始设备数据的缓存(通常是一个SSD)
  • 元数据设备:记录硬盘块在缓存中的位置,脏标志以及执行缓存策略所需的内部数据。通常采用能够随机访问的PRAM作为其载体。现有的PRAM有BBU-DIMM,PCM,MRAM。NVDIMM比起其他PRAM,速度快,容量高,是现今的最佳选择。
块大小值缓存的最小单位,在创建混合卷的时候配置。推荐大小为256到1024KB,但必须是64的倍数。采用块大小大于硬盘扇区是综合考虑了元数据大小和缓存空间浪费两方面的因素。过小的块会极具增加元数据在内核空间和元数据设备中占据的空间。太大的块又会造成缓存空间的浪费,因为大的数据块往往只有一部分有较高的缓存命中率。
dm-cache支持写回,写通和旁路三种模式。在写回模式中,写操作仅仅将数据写入缓存,并将其标记为脏数据,然后在适当的时机由后台的内核线程写入硬盘。写通模式则将更新的数据写入硬盘才结束本次I/O操作。旁路模式将所有读写操作不经过缓存设备,直接作用于原始设备。该模式允许混合卷在缓存设备与原始设备状态不一致的情况下被激活,适用于执行第三方快照功能的情形。 [2]
dm-cache的做法:
1.计算metadata所需block的大小:
metadata的大小为
4MB+(16B * nr_blocks) 计算方法(nr_blocks是cache设备的block的数量。)
root@xxxx:~$ sudo blockdev --getsize64 /dev/sdb  ###我的ssd卡为sdb   #fdisk  -l 查询
239444426752
将其转换为block数,并计算metadata所需分配的空间大小。
4MB+(16B * nr_blocks) 套用方法
4194304 + (16 * 239444426752 / 262144)
=18808832
18808832 / 512
=36736
因此要给metadata分配36736个block。(注意,如果计算结果不是整数,应该向上取整。)

2.建立ssd-metadata dm设备并清空:

root@xxxx:~$ dmsetup create ssd-metadata --table '0 36736 linear /dev/sdb 0'

root@xxxx:~$ sudo dd if=/dev/zero of=/dev/mapper/ssd-metadata

3.计算剩余的块数分配给ssd-cache:

239444426752 / 512
=467664896
467664896 - 36736
=467628160

4.建立ssd-cache:

root@xxxx:~$ dmsetup create ssd-cache --table '0 467628160 linear /dev/sdb 36736'

5.获得origin设备的扇区数:

root@xxxx:~$ blockdev --getsz /dev/sdb
 467664896

6.建立origin设备(256kB):

root@xxxx:~$ dmsetup create hdd-origin --table '0 467664896 cache /dev/mapper/ssd-metadata /dev/mapper/ssd-cache /dev/sdb 512 1 writeback default 0'

7.验证:

root@xxxx:~$ sudo ls -l /dev/mapper/hdd-origin
lrwxrwxrwx 1 root root 7 April  10 18:16 /dev/mapper/hdd-origin -> ../dm-2
root@xxxx:~$ sudo dmsetup status /dev/mapper/hdd-origin
0 467664896 cache 8 817/***** 512 0/****** 0 43 0 0 0 0 0 1 writeback 2 migration_threshold 2048 smq 0 rw –

上面最后一排信息的具体含义如下:

Der Device-Mapper stellt über dmsetup status den aktuellen Status des Caches zur Verfügung.
 
  sudo dmsetup status /dev/mapper/dmcache_test
Beispielausgabe:
 
    0 8388608 cache 34/1280 1781667 761103 200117 225373 0 0 3567 1 1 writethrough 2 migration_threshold 2048 4 random_threshold 4 sequential_threshold 512
                      │        │       │      │      │   │ │   │  │ │      │       │          │            │  │       └──────────└───────────└───────────└─<policy args>*
                      │        │       │      │      │   │ │   │  │ │      │       │          │            │  └─<#policy args>
                      │        │       │      │      │   │ │   │  │ │      │       │          └────────────└─<core args>*
                      │        │       │      │      │   │ │   │  │ │      │       └─<#core args>
                      │        │       │      │      │   │ │   │  │ │      └─<feature args>*
                      │        │       │      │      │   │ │   │  │ └─<#feature args>
                      │        │       │      │      │   │ │   │  └─<#dirty>
                      │        │       │      │      │   │ │   └─<#blocks in cache>
                      │        │       │      │      │   │ └─<#promotions>
                      │        │       │      │      │   └─<#demotions>
                      │        │       │      │      └─<#write misses>
                      │        │       │      └─<#write hits> 
                      │        │       └─<#read misses>
                      │        └─<#read hits>
                      └─<#used metadata blocks>/<#total metadata blocks>

 

8.挂载:

root@xxxx:~$ mkdir /mnt/cache #此处可能会产生错误,可以忽略不计
root@xxxx:~$ mount /dev/mapper/hdd-origin /mnt/cache

9.配置开机自动加载并挂载,需要手动配置两个文件放到/etc/init下:

root@xxxx:~$ sudo vim /etc/init/ssd-cache-wait.conf
# Start monitoring with inotifywait (will block) after the filesystem is
# mounted, when the filesystem is unmounted, teardown the dm devices.

start on mounted MOUNTPOINT=/mnt/cache

script
    inotifywait -e unmount $MOUNTPOINT
    dmsetup suspend hdd-origin
    dmsetup remove hdd-origin
    dmsetup remove ssd-cache
    dmsetup remove ssd-metadata
end script
root@xxxx:~$sudo  vim /etc/init/ ssd-cache.conf

# This would be handy, but it assumes the source device is already
# available, which in this case it isn't.
#start on mounting MOUNTPOINT=/mnt/cache
# Run after /proc and /dev are finalized
start on virtual-filesystems

task
script
    # Setup the /dev/mapper/hdd-origin entity so that mountall will automount it after reading fstab
    dmsetup create ssd-metadata --table '0 36736 linear /dev/nvme0n1p1 0'
    dmsetup create ssd-cache --table '0 467664896 linear /dev/nvme0n1p1 36736'
    dmsetup create hdd-origin --table '0 467628160 cache /dev/mapper/ssd-metadata /dev/mapper/ssd-cache /dev/sda2 512 1 writeback default 0'
    dmsetup resume hdd-origin
end script

10.删除dm-cache的办法:

停用dm-cache

umount /dev/mapper/hdd-origin

dmsetup remove hdd-origin

dmsetup remove ssd-metadata

dmsetup remove ssd-cache
并删除/etc/init下的文件就行

结语:

  不得不说这套方案是非常的不错的,SSD的价格相对还是较贵的,尤其是作为存储来说,算上使用寿命的话,整体价格和HDD还是有不小的差距,而这套方案的优势就在于,在速度与价格上实现了折中,大大降低了海量存储的成本,当然,如果是内部的私有存储,还是结合ceph等开源分布式存储更好。

文章参考链接如下:

https://blog.csdn.net/Agoni_xiao/article/details/83151629

https://www.centos.bz/2018/02/lvm%E4%B9%8Bcache%E5%8A%A0%E9%80%9F/

https://www.jianshu.com/p/edfd6e7deee1

原文地址:https://www.cnblogs.com/xiaoyuxixi/p/12178380.html