Linux 下的两种分层存储方案
背景介绍
随着固态存储技术 (SSD),SAS 技术的不断进步和普及,存储介质的种类更加多样,采用不同存储介质和接口的存储设备的性能出现了很大差异。SSD 相较于传统的机械硬盘,由于没有磁盘的机械转动,寻址速度大大提高,尤其在随机读写较多的应用环境下,性能会大大提升,但这些高性能存储设备的单位存储价格相对于传统的磁带和 SATA 硬盘也高出很多,如图 1 所示。
图 1 不同存储设备的性能价格对比
所以,如何高效平衡地利用这些存储设备,是所有存储厂商都在关注的问题。采用 Storage Tiering 分层存储,将数据按照冷热进行自动分层,越热的数据存放在访问性能越高的设备上,而越冷的数据存放在访问性能越低的设备上,既可以获取高的性能,又可以有效节约成本。
Storage Tiering 分层存储技术在企业级的存储设备中已经被广泛使用,如 IBM 的 Easy Tier, EMC 的 FAST 等,但这些功能都集成在存储设备内部,需要存储设备固件的支持。
本文主要 Host 主机的角度,分析在 Linux 上实现 Storage Tiering 分层存储的两种方案以及其开源实现。为便于表述,本文中仅以两级 Tiering 为例,慢速设备为传统的 SATA 硬盘(DEV1),快速设备为固态存储硬盘 SSD(DEV2)。
分层存储的技术要点
要实现分层存储,首先需要将具有不同访问性能的存储设备(DEV1, DEV2)虚拟化成一个新的存储设备(VDEV)。与缓存(Cache)不同,VDEV 的存储容量是 DEV1 与 DEV2 的容量之和(需除去一些用于存放元数据的空间)。
所有用户的 IO 请求将会发给新的存储设备 VDEV,然后再按照一定的地址映射关系被转发到相应的物理设备 DEV1 或 DEV2。
同时还需要统计 IO 的热度,并根据这些热度数据,动态地在不同的 Tiering 间迁移数据,以达到性能容量的优化。
因此,实现分层存储主要包括三方面的工作,如图 2 所示。
- 存储设备的虚拟化
负责虚拟设备的创建,删除; 维护虚拟设备到物理设备的地址映射关系。
- IO 性能的监测统计
统计 IO 的热度,以及 IO 的大小,随机性能属性,为数据迁移提供依据。
- 数据的迁移
根据 IO 数据的热度等统计属性,将访问频度高的数据迁移至读写性能高的 Tier 存放,而将访问频度低的数据迁移到性能低的 Tier 存放。
图 2 分层存储的数据迁移
基于 Block Device 的分层存储方案
该方案完整地实现了以上提到的分层存储中所有的工作,包括虚拟化,IO 性能统计以及数据的迁移。
方案结构
该方案的结构包括一个 Linux 设备驱动程序和若干用户态的控制程序,如图 3 所示。
驱动程序实现存储设备的虚拟化,IO 性能监测统计以及数据的迁移;
用户态控制程序负责创建、删除虚拟设备,手动触发数据迁移,以及设置获取设备状态。
该方案由于 Storage Tiering 所有的功能都在 Linux 内核实现,且需要维护虚拟设备到物理设备的地址映射表,以及保证数据一致性,所以实现难度和工作量比较大,但可扩展性和灵活性也相对较大。
图 3 基于 Block Device 的分层存储方案
方案实现
该方案的实现主要包括以下内容:
- 管理设备的注册
管理设备主要用于与用户态程序的 IOCTL 交互,可以是一个字符设备或者 Misc 设备。Linux 下可以通过 register_chrdev 或 misc_register 注册,并实现所需要的 IOCTL 接口。
- 虚拟块设备的创建
用户态控制程序通过 IOCTL 向控制设备发起创建虚拟设备的请求,并传入所有的物理磁盘(DEV1,DEV2)的参数,如设备名,磁盘大小,虚拟磁盘的块大小等;驱动程序收到该请求后,进行必要的参数检查,然后调用 register_blkdev 创建一个新的块设备(VDEV)。并设置新设备的相关参数,如 IO 处理函数,队列大小,设备容量等。
- 虚拟设备地址与物理设备地址映射
虚拟设备地址到物理设备的地址映射表在虚拟设备创建是被初始化,并在数据迁移过程中被修改。
虚拟设备和物理设备都被分成固定大小的块,块大小可以固定或通过 IOCTL 由用户指定,但一旦确定,不能更改,一个 Block 是热度统计以及数据迁移的最小单位;每个 Block 包含若干个 sector(512 Byte)。
当 VDEV 收到一个 bio,可以由 bi_sector 和 bi_size 找出所对应的 VDEV 的 Block 以及 Block 内的偏移量,通过查询映射表,找到各个 VDEV Block 所对应的物理设备以及 Block,然后读取物理设备 Block 内的偏移量,如图 4 所示。
地址映射表以及其他的元数据需要存储在物理设备上,以便机器重启时能重构这个虚拟的块设备,且需要采取一定的备份策略,防止断电或磁盘损坏造成数据丢失。
- IO 热度统计
IO 热度统计也以 Block 为基本单位,每个 Block 内的任何一个 sector 被访问,该 Block 的热度都为增加。由于大 IO 以及顺序 IO 在性能在传统硬盘和 SSD 上的差异并不是特别大,所以在进行热度统计是应该考虑排除大 IO 和顺序 IO。
- 数据迁移
可以采用自动方式或手动方式。自动方式由驱动内的定时器驱动,每隔一定的时间,启动数据迁移的扫描,将 IO 热度统计中的热数据向高性能存储设备迁移,冷数据向低性能存储设备迁移;手动方式由用户指定,将某块数据向高性能存储设备迁移或低性能设备迁移。手动数据迁移方式增加了更大的灵活性和可扩展性。
图 4 虚拟设备与物理设备的地址映射
开源实现
BTier 基于 Block Device 的分层存储方案的开源实现。BTier 最大支持 16 个设备的虚拟化,这些设备被 BTier 简单地捆绑成一个 btier 块设备,因此,其中任何一个设备的失效,都会导致整个 btier 的失效。
编译并以模块形式安装 BTier 之后,会创建一个名为 tiercontrol 的字符设备;
然后使用 BTier 提供的 btier_setup 应用可以创建一个新的块设备 btiera,然后就可以对 btiera 设备进行所有块设备的读写操作,包括分区和创建文件系统。
BTier 还提供了丰富的 sysfs 接口,进行控制和信息获取,如数据迁移的开关,间隔时间,IO 统计信息等。
不过 BTier 每个 Tier 层仅支持 1 个物理设备,同层多个设备的虚拟化需要借助其他的方法,在虚拟化上面,BTier 还有可以改善的空间。
基于 LVM 的分层存储方案
Linux 的逻辑卷管理(LVM)提供了存储虚拟化,可以将多个物理卷(PV)建成一个卷组(VG),然后再在 VG 里创建虚拟卷(VG)。而且 LVM 提供了在不同物理卷之间迁移数据的 API。因此,基于 LVM 的分层存储方案借助 LVM 的虚拟化和数据迁移的能力,实现会更简单。
方案结构
该方案中,数据一致性的问题以及数据迁移时 IO 中断的问题都由 LVM 进行处理,重点在于如何分析并统计 IO 的热度信息,并且不涉及内核态的开发。该方案的结构如图 5 所示。
图 5 基于 LVM 的分层存储方案
方案实现
该方案的实现主要包括以下内容:
- 创建虚拟设备
使用 pvcreate 将所有的物理磁盘创建成物理卷(PV);再使用 vgcreate 将所有的 VG 创建成一个卷组(VG);最后使用 lvcreate 在创建出来的 VG 上建虚拟卷。
- IO 热度统计
IO 热度统计可以使用 blktrace 工具,或者实现一个设备驱动来检测 IO 的热度。使用 blkparse 可以解析 blktrace 的输出,然后分析这些 IO 的分布以及读写频度,从而得到 IO 的热度统计信息。
- 数据迁移
根据 IO 的热度统计信息,使用 LVM 提供的 pvmove 工具,可以在属于同一个 VG 里的不同 PV 之间进行数据迁移,将热数据和冷数据分布存放在不同的物理卷上。
开源实现
LVMTS(LVM Tired Storage)是一个使用 SSD 和 HDD 来创建混合存储的方案,完全在用户态实现,主要由几个守护进程构成。
Lvmtscd 负责监测 blktrace 的输出并统计块设备的访问频度,并将这些统计信息记录在文件中;
Lvmtsd 负责根据用户配置的信息,启动其他的守护进程,并完成数据迁移。
实际使用中发现,LVMTS 并不是太稳定,而且在 IO 分析统计上并不是太完善,可开发的空间仍然很大。
总结
在 Linux 上实现 Storage Tiering 分层存储,方法有很多,包括使用 Linux Device Mapper 机制等。本文对比较常用的两种方案的实现进行了大概的分析,以及各个方案的优劣,在实际实现中,还有很多细节需要考虑,如 Thin Provision,SSD Trim 等的支持。
Linux 下的两种分层存储方案的更多相关文章
- Linux下的两种磁盘分区工具的使用
如何使用fdisk和parted分区工具来进行硬盘分区,下面我来说一下在Linux系统中这两种硬盘分区工具的使用方法: ----------fdisk分区工具---------- ...
- linux 下的两种软件安装方式 —— 源码(编译、安装),编译好的二进制(直接安装)
我们以 GPG(加密工具)为例来说明两种安装方式的区别: 源码(Source code releases,名称中则会含有src等说明信息,tarball:source),先编译再安装 GPU 的源码地 ...
- Linux下的5种I/O模型(转)
Linux下的五种I/O模型: l 阻塞I/O l 非阻塞I/O l I/O复用(select.poll.epoll) l 信号驱动I/ ...
- INNODB与MyISAM两种表存储引擎区别
mysql数据库分类为INNODB为MyISAM两种表存储引擎了,两种各有优化在不同类型网站可能选择不同,下面小编为各位介绍mysql更改表引擎INNODB为MyISAM技巧. 常见的mysql表引擎 ...
- Linux 下启动两个tomcat
Linux 下启动两个tomcat 闲来无事学习nginx,想要配置个load balance.可是先决条件是:得有两个web容器.两个电脑是不用想了.只能想办法在一个机器上启动两个tomcat.原以 ...
- Linux下的5种I/O模型与3组I/O复用
引言 上一篇文章中介绍了一些无缓冲文件I/O函数,但应该什么时机调用这些函数,调用这些I/O函数时进程和内核的行为如何,如何高效率地实现I/O?这篇文章就来谈一谈Linux下的5种I/O模型,以及高性 ...
- Linux中的两种守护进程stand alone和xinetd
Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...
- Linux 下的五种 IO 模型
概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的 ...
- []转帖] 浅谈Linux下的五种I/O模型
浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html 一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是 ...
随机推荐
- Xcode C++ and Objective-C refactoring
Is there a way to refactor mixed C++/Objective-C code in Xcode ?? I am writing a game using Cocos2D ...
- 9.1 UDP协议
TCP 协议是面向连接的基于流的,可靠的传输服务.UDP是无连接的,基于数据报的,不可靠的传输服务,UDP没有粘包,但是会产生丢包. UDP模型如下: 可以看到,服务器端不用listen,也不用acc ...
- (树莓派、Arduino、物联网、智能家居、机器人)传感器、机械装置、电子元件
定制 PCB 1. 机械类 履带底盘 2. 传感器 温度传感器(temperature).湿度传感器(humidity) DHT11/DHT22 驱动:BCM2835 (被动)红外传感器(Passiv ...
- Android 运行 Linux 可执行程序
/**************************************************************************** * Android 运行 Linux 可执行 ...
- 【OpenCV】Learn OpenCV
learn opencv website: https://www.learnopencv.com/ learn opencv github:https://github.com/spmallick/ ...
- ACdream - 1735:输油管道
Time Limit: 2000/1000MS (Java/Others) Memory Limit: 262144/131072KB (Java/Others) Problem Descriptio ...
- memsql 6.7集群安装
预备环境处理 安装yum 源 yum install -y yum-utils yum-config-manager --add-repo https://release.memsql.com/pro ...
- android 图片解码显示流程
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/32327699 问题来源 android 能 ...
- Eolinker API 接口文档神器
Eolinker API 接口文档神器 群里小伙伴推荐的,还没有去研究,先记下来. API文档管理.自动化测试.开发协作利器 正在为数万企业管理超过100万APIs,提高开发效率以及规范开发流程
- RabbitMQ之监控
RabbitMQ作为一个工业级的消息中间件,肯定是缺少不了监控的,RabbitMQ提供了WEB版的页面监控(访问地址:http://xxx.xxx.xxx.xxx:15672/,默认端口号是15672 ...