最近,由于项目需要,在做关于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的实现与分析的更多相关文章

  1. linux内核源码阅读之facebook硬盘加速flashcache之八

    前面我们的分析中重点关注正常的数据流程,这一小节关注如果有异常,那么流程是怎么走完的呢? 1)创建新任务时kcached_job申请不到 2)读写命中时cache块为忙 3)系统关机时处理,系统开机时 ...

  2. flashcache 介绍

    rpm: flashcache-utils-0.0-4.1.el6.x86_64 kmod-flashcache-0.0-3.el6.x86_64 基本介绍: Flashcache是Facebook技 ...

  3. linux内核源码阅读之facebook硬盘加速flashcache之五

    正常流程到flashcache_map的1623行或1625行,按顺序先看读流程: 1221static void 1222flashcache_read(struct cache_c *dmc, s ...

  4. linux内核源码阅读之facebook硬盘加速利器flashcache

    从来没有写过源码阅读,这种感觉越来越强烈,虽然劣于文笔,但还是下定决心认真写一回. 源代码下载请参见上一篇flashcache之我见 http://blog.csdn.net/liumangxiong ...

  5. ceph与flashcache的around模式结合启动问题

    问题 通过对我们的启动流程看了下,目前是穿到一个脚本里面的,然后这个脚本是用无限循环的方式去执行一些事情,这个地方不符合松耦合的设计,一个模块做一个事情,两个并不相关的功能不要嵌入另一个脚本,否则出现 ...

  6. alias导致virtualenv异常的分析和解法

    title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...

  7. 火焰图分析openresty性能瓶颈

    注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...

  8. 一起来玩echarts系列(一)------箱线图的分析与绘制

    一.箱线图 Box-plot 箱线图一般被用作显示数据分散情况.具体是计算一组数据的中位数.25%分位数.75%分位数.上边界.下边界,来将数据从大到小排列,直观展示数据整体的分布情况. 大部分正常数 ...

  9. 应用工具 .NET Portability Analyzer 分析迁移dotnet core

    大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易.如果您创建与 .NET Core 兼容的.NET 标准库,那么现在比以往任何时候 ...

随机推荐

  1. USACO 6.2 Packing Rectangles

    Packing RectanglesIOI 95 The six basic layouts of four rectangles Four rectangles are given. Find th ...

  2. 41-2:和为S的连续正数序列

    import java.util.ArrayList; /** * 面试题41-题目2:和为S的连续正数序列 * 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案 ...

  3. Hadoop整理四(Hadoop分布式计算框架MapReduce)

    Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提 ...

  4. ref:JAVA之Forward和Redirect的区别

    ref:https://www.cnblogs.com/selene/p/4518246.html 阅读目录 一:间接请求转发(Redirect) 二:直接请求转发(Forward) 用户向服务器发送 ...

  5. Android Studio奇技淫巧

    No1: Ctrl+E:显示最近浏览过的文件 Ctrl+Shift+E:显示最近编辑过的文件 Ctrl+Tab:切换最近编辑过的文件 No2: 条件断点:断点右键 No3: 全局断点 这样只要碰到空指 ...

  6. 【GO基础】神奇的iota特殊常量

    最近在学习GO语言,然后发现有一个特殊常量是以前没有接触过的,比较感兴趣,这里给大家介绍一下. iota,特殊常量,可以被认为是一个可以被编译器修改的常量. 核心概念:iota在const关键字出现时 ...

  7. 支撑大规模公有云的Kubernetes改进与优化 (2)

    接下来我们按照kubernetes创建容器的详细过程,以及可能存在的问题. 一.API Server的认证,鉴权,Quota 当客户需要创建一个pod的时候,需要先请求API Server. Kube ...

  8. CodeForces600E Lomsat gelral 线段树合并

    从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \ ...

  9. luogu4770 [NOI2018]你的名字 后缀自动机 + 线段树合并

    其实很水的一道题吧.... 题意是:每次给定一个串\(T\)以及\(l, r\),询问有多少个字符串\(s\)满足,\(s\)是\(T\)的子串,但不是\(S[l .. r]\)的子串 统计\(T\) ...

  10. POJ 2117 Electricity 双联通分量 割点

    http://poj.org/problem?id=2117 这个妹妹我竟然到现在才见过,我真是太菜了~~~ 求去掉一个点后图中最多有多少个连通块.(原图可以本身就有多个连通块) 首先设点i去掉后它的 ...