flashcache的实现与分析
最近,由于项目需要,在做关于flashcache的一些工作,主要涉及模块组织、元数据管理及数据分布、读写流程分析、数据在磁盘和 cache(SSD)之间的调度、缺点及可优化方向等一些方面的分析研究。也想,抽空写一下心得,整理一下最近工作的思路,以弥补自己不善于表达的恶习。 特别是,要深入下去的话,会涉及到整个Linux系统栈的各个层次,从文件系统、磁盘缓存、通用块层、驱动层,以及DM的工作流程(细节),也遇到了很多 问题,像DM层基于split_bio如何做拆分,在拆分中的边界问题等,不可能一下子解决,也趁此机会,记录下心里的困惑。
好了,不啰嗦了,马上开始!还是从源头讲起。。。
flashcache,是facebook技术团队开发的新开源项目,主要目的是用SSD硬盘来缓存数据以加速MySQL的一个内核模块。可以看到,它最初是用来做数据库加速,但同时,它也被作为通用的缓存模块而设计,能够用于任何搭建在块设备上的应用程序。
工作原理。基于Device Mapper,它将快速的SSD硬盘和普通的硬盘映射成一个 带缓存的逻辑块设备,作为用户操作的接口。用户直接对这个逻辑设备执行读写操作,而不直接对底层的SSD或者普通硬盘操作。如果对底层的这些块设备操作, 那么会失去作为一个整体提供的缓存功能。
内核层次。flashcache,它是通过在文件系统和块设备驱动层中间 增加一缓存层次实现的,这里不得不提到DM层的映射机制。由于DM是作为虚拟的块设备驱动在内核中被注册的,它不是一个真实的设备驱动,不能完成bio的 处理,因此,它主要是基于映射表对bio进行分解、克隆和重映射,然后,bio到达底层真实的设备驱动,启动数据传输。在Device mapper中,引入了target_driver,每个target_driver由target_type类型描述,代表了一类映射,它们分别用来具 体实现块设备的映射过程。通过调用某一target_driver的map方法,来映射从上层分发下来的bio,也即是,找到正确的目标设备,并将bio 转发到目标设备的请求队列,完成操作。flashcache_target就是这样一个新的target_driver(作为一个新的映射类 型,target_type是必须的),以模块化的方式加入到了DM层。
逻辑架构。从源代码层次分析,可以将flashcache分为这个四个模 块,调度模块(也称‘读写模块’)、逻辑处理模块(也称“读写后处理模块”)、底层存储模块、以及后台清理模块,它们都是基于SSD Layout实现的,构建在SSD布局(后面会分析)之上。其中,调度模块,在代码中对应flashcache_map映射函数,它是 flashcache缓存层次数据入口,所以到达逻辑设备的读写请求,最终都会经过DM层的处理,通过flashcache_map进入调度模块。称之为 “调度”,主要是指,接收到数据后,它会根据bio请求的读写类型、是否命中缓存等因素,选择不同的处理分支,如 flashcache_read/write或者flashcache_uncached_io,在read和write中会选择是 flashcache_read_hit/miss还是flashcache_write_hit/miss。经过不同分支的读写,会调用底层存储模块来 完成磁盘或cache的数据读写。逻辑处理模块,在代码中对应flashcache_io_callback,它在调度模块通过底层存储模块执行数据读写 操作完成后回调执行,所以说它是“读写后处理模块”,它是采用状态机实现的,根据调度模块中的读写类型进行后续的处理,如读未命中情况下,磁盘读完成后, 回调到逻辑处理模块,由它负责将从磁盘读取的数据写回到SSD,或者写未命中情况下,写SSD完成后,回调到逻辑处理模块执行元数据的更新,再有就是对调 度模块中读写操作的错误进行处理。底层存储模块,主要提供了两种方式来完成真实的数据读写,一是由DM提供的dm_io函数,它最终还是通过 submit_bio的方式,将由调度模块处理过的bio提交到通用块层,进行转发到真实的设备驱动,完成数据读写;另外,一种方式,kcopyd,是由 内核提供的一种底层拷贝函数,主要负责脏块的写回(从SSD到磁盘),会引起元数据的更新。而后台清理模块,是针对每个set进行数据清理,它会基于两种 策略对脏块做回收:(1)set内脏块超过了阈值;(2)脏块超过了设定的空闲时间,即fallow_delay,一般是15分钟,在15分钟没有被操作 则会被优先回收。要注意的是,并没有单独的线程在后台做定期空闲块回收,必须由IO操作触发,如果长时间没有对某set操作,则其中的脏数据很长期保持, 容易危害数据安全。
数据布局(待补充)。
源代码布局。两个工作队列。结合device mapper代码,特别是dm.c可以知道,在调用flashcache_create工具创建flashcache设备时,会调用 flashcache_ctl函数,执行创建工具,它会创建一工作队列_delay_clean,主要负责对整个cache设备的脏块清理,由 flashcache_clean_set在特定条件下调用(见代码),通过flashcache_clean_all执行对所有sets的扫描与清理。 另外一个工作队列,_kq_xxx(记不清了),在flashcache_init中,由flashcache模块加载时执行,通过对5个job链表进行 处理,执行元数据的更新与完成处理函数、读磁盘后的SSD写入、以及对等待队列的处理,主要就是负责读写后的处理工作隶属于逻辑处理模块,即“读写后处理 模块”,由磁盘或SSD读写后不同情况下被调度。
调度的时机可以看flashcache_map函数,处理逻辑则主要在函数flashcache_io_callback内部判断,the same block的等待队列是否为空,如果不为空,则同样会调用flashcache_do_handler,执行对等待队列的处理。
数据调度。对读,接收到bio,首先,根据 bio->bi_sector,即硬盘的扇区号,得到SSD上的set。其次,在set内查找是否命中,如果命中,则将硬盘的扇区号转换为SSD的 扇区号,然后将此bio向SSD提交,进行读取;如果未命中,则首先向硬盘驱动提交bio,从硬盘读数据,读取完成后,由回调函数启动回写SSD操作,将 bio的扇区号转换为SSD的=扇区号,然后向SSD驱动程序提交,将硬盘读取的数据写入SSD。对写,同文件系统页缓冲,并不直接写入硬盘,而是写入 SSD,同时,保持一个阀值,一般为20%,在脏块数目达到此数值时,写回磁盘。
flashcache的实现与分析的更多相关文章
- linux内核源码阅读之facebook硬盘加速flashcache之八
前面我们的分析中重点关注正常的数据流程,这一小节关注如果有异常,那么流程是怎么走完的呢? 1)创建新任务时kcached_job申请不到 2)读写命中时cache块为忙 3)系统关机时处理,系统开机时 ...
- flashcache 介绍
rpm: flashcache-utils-0.0-4.1.el6.x86_64 kmod-flashcache-0.0-3.el6.x86_64 基本介绍: Flashcache是Facebook技 ...
- linux内核源码阅读之facebook硬盘加速flashcache之五
正常流程到flashcache_map的1623行或1625行,按顺序先看读流程: 1221static void 1222flashcache_read(struct cache_c *dmc, s ...
- linux内核源码阅读之facebook硬盘加速利器flashcache
从来没有写过源码阅读,这种感觉越来越强烈,虽然劣于文笔,但还是下定决心认真写一回. 源代码下载请参见上一篇flashcache之我见 http://blog.csdn.net/liumangxiong ...
- ceph与flashcache的around模式结合启动问题
问题 通过对我们的启动流程看了下,目前是穿到一个脚本里面的,然后这个脚本是用无限循环的方式去执行一些事情,这个地方不符合松耦合的设计,一个模块做一个事情,两个并不相关的功能不要嵌入另一个脚本,否则出现 ...
- alias导致virtualenv异常的分析和解法
title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...
- 火焰图分析openresty性能瓶颈
注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...
- 一起来玩echarts系列(一)------箱线图的分析与绘制
一.箱线图 Box-plot 箱线图一般被用作显示数据分散情况.具体是计算一组数据的中位数.25%分位数.75%分位数.上边界.下边界,来将数据从大到小排列,直观展示数据整体的分布情况. 大部分正常数 ...
- 应用工具 .NET Portability Analyzer 分析迁移dotnet core
大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易.如果您创建与 .NET Core 兼容的.NET 标准库,那么现在比以往任何时候 ...
随机推荐
- easyUI小技巧-纯干货
一.显示分页(pagination:true)情况下,隐藏每页显示的记录条数的那个select(即pageList),下图箭头 方法1:onBeforeLoad:function(param){ ...
- echarts3.0 本期累计堆叠
@{ ViewBag.Title = "barlj"; } <h2>barlj</h2> <div id="main" style ...
- 设置Loadrunner负载机临时文件目录
设置Loadrunner负载机临时文件目录 最近在跑稳定性测试 3 X 24小时的时候,发现负载机产生的日志还运行记录等等竟然有100多G! C盘空间不足,但是D盘还有700多G空间呢,怎么让临时文件 ...
- 002 Ajax中传输格式为HTML
一: 1.介绍 返回的数据可以直接插入到需要的地方. 2.优缺点 二:程序大纲 1.结构 三:程序 1.css body { background: #ffb url("logo.png&q ...
- 复习一下xml(c)
简单介绍 Using System.Xml; XMLDocument xml=new XmlDocument();xml.Load(path);//初始化一个实例 xml.Load(HttpConte ...
- Tkinter制作简单的python编辑器
想要制作简单的python脚本编辑器,其中文字输入代码部分使用Tkinter中的Text控件即可实现. 但是问题是,如何实现高亮呢?参考python自带的编辑器:python27/vidle文件夹中的 ...
- ?P<username>\w+
- luoguP4360 [CEOI2004]锯木厂选址
题目链接 luoguP4360 [CEOI2004]锯木厂选址 题解 dis:后缀和 sum:前缀和 补集转化,减去少走的,得到转移方程 dp[i] = min(tot - sumj * disj - ...
- Codeforces.714D.Searching Rectangles(交互 二分)
题目链接 \(Description\) 在一个\(n*n\)的二维平面中有两个不相交的整点矩形,每次可以询问两个矩形有几个完全在你给出的一个矩形中.200次询问内确定两个矩形坐标. \(Soluti ...
- 【set】【可持久化Trie】The 16th UESTC Programming Contest Preliminary K - Will the circle be broken
题意:You are given an array A of N non-negative integers and an integer M. Find the number of pair(i,j ...