ceph bluestore源码分析:非对齐写逻辑
文章目录
- 环境
- 原理说明
- 总结
环境
ceph:12.2.1
场景:ec 2+1
部署cephfs,执行如右写模式:dd if=/dev/zero of=/xxx/cephfs bs=6K count=4 oflag=direct
关键配置:
bluestore_min_alloc_size_hdd = 65536
bluestore分配空间的最小粒度 单位:B
bdev_block_size = 4096
磁盘分配空间的最小粒度 单位:B
原理说明
以上dd写方式总共直写四次6K大小的io,每一个io在经过PG落到bluestore层次会根据分片大小2副本+1校验块 被拆分为3K大小的 io到每个osd上
第一次写3K io 由于未chuck(bdev_size 4K )对齐,则对3K io补零后和bdev_size对齐,然后写入bluestore按照bluestore_min_alloc_size_hdd大小分配的blob中
bluestore.cc :_txc_add_transaction–> _write --> _do_write–>_do_write_data --> _do_write_small
直接写入一个新的blob中
_do_alloc_write txc 0x7fcb6e6443c0 1 blobs
第二次写3K io主要执行如下步骤:
a. 会先进行clone blob1
b. 使用前1K 数据补齐blob1中的lextent1,再重新分配一个blob,写入补齐后的lextent3
c. 剩下的2K io用0补齐后写入新的lextent4
d. 移除lextent1对临时onode的引用,remove临时onde,进而释放lextent1对blob1的引用,进而释放blob1回收磁盘空间a. 执行clone
这里clone是为当前extent创建一个单独的onode,即一个新的对象 空间来存储,所以这里可以看到offset从0开始分配
这里在执行clone的时候根据bluestore配置参数bluestore_clone_cow来判断是否执行cow机制:即当前io补齐上一个extent之后,为其重新分配一个blob并写入。RMW:需要有额外的写,即先读出当前blob的extent数据,使用第二次io的前1K补齐改blob,再写入当前blob空间。bluestore为了提升性能,减少小写次数,这里默认使用了cow机制。
bluestore.cc :_txc_add_transaction–> _clone --> _do_clone
b. 此时blob1即被两个逻辑段lexten共享,则blob1成为sharedblob
接下来使用1K数据补齐lextent1的3K,同时使用0补齐当前剩余2K,补齐后的数据如下
c. 将补齐后的第一个4K IO写入到lextent3中,第二次io剩余的数据写入到lextent4中
可以看到这里进行了两次写,第一次是写clone之后补齐的数据,第二次写剩余用0补齐的数据。因为第一次写是重新分配了blob,所以offset 为0,第二次写是紧接着第一次的写,所以这里offset为4096
补齐后的第一次写 ,执行小写,分配了一个新的blob
bluestore.cc :_txc_add_transaction–> _write --> _do_write–>_do_write_data --> _do_write_small
第二次写为直接写入blob中未使用的块
bluestore.cc :_txc_add_transaction–> _write --> _do_write–>_do_write_data --> _do_write_small
写完之后的blob和extent引用关系如下
d. 此时释放lextent1对blob1的引用如下:
垃圾回收,进而释放lextent1
bluestore.cc :_txc_add_transaction–> _write --> _do_write
_txc_add_transaction–> _write --> _do_write --> _wctx_finish
释放blob1中lexten1对blob1的引用
同时remove临时onode(clone后的extent2所在的内存元数据结构),并释放blob1的空间.最终第二个3k io写完效果如下
_txc_add_transaction–> _remove --> _do_remove -->
回收磁盘空间 _txc_add_transaction–> _remove --> _do_remove --> _do_truncate --> _wctx_finish
_txc_add_transaction–> _remove --> _do_remove --> _do_truncate --> _wctx_finish
第三次写 3K io同样会进行一次clone,不过clone完成之后的补齐上一次io的写lextent4和新的补零写lextent5之后blob2成为sharedblob,但是由于shareblob仍然再被lextent3引用,所以此时无法remove blob2
第四次写3k io,同上最后的映射关系如下
源码调用栈如下,本调用栈只打到了_do_write_small这一层,具体如何向源码加入函数调用栈可以参考ceph bluestore源码梳理:C++ 获取线程id:
ceph-osd(BlueStore::_do_write_small(BlueStore::TransContext*,
ceph-osd(BlueStore::_do_write(BlueStore::TransContext*,
ceph-osd(BlueStore::_write(BlueStore::TransContext*,
ceph-osd(BlueStore::_txc_add_transaction(BlueStore::TransContext*,
ceph-osd(BlueStore::queue_transactions(ObjectStore::Sequencer*,
ceph-osd(PrimaryLogPG::queue_transactions(std::vector<ObjectStore::Transaction,
ceph-osd(ECBackend::handle_sub_write(pg_shard_t, boost::intrusive_ptr<OpRequest>,
ceph-osd(ECBackend::_handle_message(boost::intrusive_ptr<OpRequest>)+0x327)
ceph-osd(PGBackend::handle_message(boost::intrusive_ptr<OpRequest>)+0x50)
ceph-osd(PrimaryLogPG::do_request(boost::intrusive_ptr<OpRequest>&,
ceph-osd(OSD::dequeue_op(boost::intrusive_ptr<PG>, boost::intrusive_ptr<OpRequest>,
ceph-osd(PGQueueable::RunVis::operator()(boost::intrusive_ptr<OpRequest> const&)+0x57)
ceph-osd(OSD::ShardedOpWQ::_process(unsigned int, ceph::heartbeat_handle_d*)
ceph-osd(ShardedThreadPool::shardedthreadpool_worker(unsigned int)+0x839)
总结
综上,我们可以看到bluestore在非对齐写4个io时会进行3次clone,总共执行6次do_write_small方式的小写。这里是因为clone时使用了cow机制,然而我们使用RMW时会额外增加一次写。可以参考_clone
函数中的逻辑。所以按照如上测试方式,每经过4次io,bluestore会进行9次的小写。这里bluestore为了性能稳定,牺牲磁盘空间来将cow机制作为默认的非对齐写处理方式。
相关文章:

JVM系列(之ClassLoader)
Class Loader Java运作流程 内部class loader bootstrap class loader --引导类加载器,它负责加载Java的核心类【java.* 】(如classpath下面的类库),不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。Code . UR…

java平台类成员访问修饰符_JAVA类的修饰符及访问权限
1.类外部类 class前的修饰符只能有publicfinalabstrct无(默认) :同包可见 (Eclipse中选择package)内部类 class前的修饰符有public、protected、private、默认、final、abstract、static。先看类的访问权限,再看成员的访问权限,类…

ios实例开发精品源码文章推荐
1、IOS代码分享:视图布局(View Layout)Border View140601bvpw22rir88b9i8i.png(19.97 KB, 下载次数: 0)下载附件保存到相册半小时前 上传http://www.apkbus.com/android-101999-1-14.html2、IOS代码分享:导航条(Navigation Bar&am…

Spring BeanDefinitionRegistryPostProcessor BeanPostProcessor作用
写博客,写博客,把自己知道的小知识点全部记录,? BeanDefinitionRegistryPostProcessor 接口属于Beanddefination 装配定义的范畴,此时bean 并没有初始化 BeanPostProcessor属于be an 实例化修改的范畴,be an 已经进行…

关于ceph源码 backtrace 打印函数调用栈
当集中精力看一个问题的时候,时间久了就会有这样一个状态,天空飘来五个字,那都不算事 ceph源码庞大的体量以及复杂的设计让很多人望而却步,尤其是大量的纯虚函数更是让读者迷失在代码的海洋,这个时候函数调用栈是一个救…
泛型java 代码讲解_Java泛型详解
2516326-5475e88a458a09e4.png一,打破砂锅问到底泛型存在的意义?泛型类,泛型接口,泛型方法如何定义?如何限定类型变量?泛型中使用的约束和局限性有哪些?泛型类型的继承规则是什么?泛…

(转)金额转中文大写
public class RMB {//返回转换好的大写形式public static String numberToRMB(String money) {return cleanZero(splitNum(roundString(money)));}// 将小写金额转换成大写金额private static String splitNum(String s) {// 如果传入的是空串则继续返回空串if ("".e…

[IOS]UIWebView实现保存页面和读取服务器端json数据
如何通过viewView保存访问过的页面?和如何获取并解析服务器端发送过来的json数据?通过一个简单的Demo来学习一下吧! 操作步骤: 1.创建SingleViewApplication应用,新建VIewController,并在xib试图中添加WebV…

struts2之配置文件struts.xml详解
struts配置文件 struts.xml配置参数详解 struts.xml中很大一部分配置默认配置就好了 但是有些还是需要做了解 以便于理解 和修改 <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Str…

ceph bluestore 源码分析:刷缓存(trim)逻辑
环境 ceph版本:12.2.1 部署模式:ec 21 osd: 3个 且资源池已经有数据 执行命令:ceph daemon osd.0 flush_store_cache 进行刷缓存。即将dump_mempools内存池管理的bluestore cache中的无用数据进行释放 主要参数: bluestore_cac…

php中怎么过滤器_PHP 过滤器(Filter)
过滤多个输入表单通常由多个输入字段组成。为了避免对 filter_var 或 filter_input 重复调用,我们可以使用 filter_var_array 或 the filter_input_array 函数。在本例中,我们使用 filter_input_array() 函数来过滤三个 GET 变量。接收到的 GET 变量是一…

c++ Qt向PHP接口POST文件流
Qt调用PHP写的接口,向其传递图片文件,并保存在服务器。 二进制文件无法直接传递,Qt采用Base64进行编码发送,PHP解码保存为文件。 注意:PHP收到数据之后会将POST过来的数据中的加号()替换为空格,造成接收到的…

在网络通讯中应用Protobuf
Protobuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性非常强;还有一个比较大的优点就是有着很多的语言平台支持。下面讲解一下如何在TCP通讯应用中集成Protobuf. Protobuf…

JS中Math函数的常用方法
Math 是数学函数,但又属于对象数据类型 typeof Math > ‘object’ console.dir(Math) 查看Math的所有函数方法。 1,Math.abs() 获取绝对值 Math.abs(-12) 12 2,Math.ceil() and Math.floor() 向上取整和向下取整 console.log(Math.ceil(1…

C++ 泛型编程 -- 函数模版
文章目录定义声明调用方式函数模版的重载函数模版的特点工作中一个同事写了测试demo,想要自己尝试使用发现调用老出错,请教的时候发现是函数模版,有自己的调用方式,并且发现核心代码中大量的函数模版和类模版。特此做一个函数模版…

bellman_ford寻找平均权值最小的回路
给定一个有向图,如果存在平均值最小的回路,输出平均值。 使用二分法求解,对于一个猜测值mid,判断是否存在平均值小于mid的回路 如果存在平均值小于mid的包含k条边的回路,那么有w1w2w3...wk < k * mid,即(w1-mid)(w2…

守护进程中创建的对象php,在PHP中生成守护进程(Daemon Process)
前两天看到一篇文章《如何使用PHP编写daemon process》,其中对核心代码却没有细说,我又查了一些资料,还看了一本《理解Unix进程》,才搞明白生成守护进程的时候发生了什么。这段代码是这个样子的:function run(){//第一…

log4j个人使用整理
Log4j介绍: 略过。 配置: Eclipse项目中添加log4j.jar到lib下。 在bin目录下新建log4j.properties,编辑好log4j配置文件。 样例分析: 1 log4j.rootLoggerWARN, stdout, file2 log4j.appender.stdoutorg.apache.log4j.ConsoleAppen…

完全理解 Python 迭代对象、迭代器、生成器(转)
完全理解 Python 迭代对象、迭代器、生成器 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators nvie.com,俺写的这篇文章是按照自己的理解做的参考翻译,算不上是原文的中译版本,推荐阅读原文,谢…

Rocksdb 与 TitanDb 原理分析 及 性能对比测试
文章目录前言Rocksdb的compaction机制compaction作用compaction分类level style compaction(rocksdb 默认进行的compaction策略)level 的文件存储结构compaction过程compaction中的level target sizeuniversal style compactionfifo style compactionTit…

经典SQL练习题
题目地址:http://blog.csdn.net/qaz13177_58_/article/details/5575711 1、 查询Student表中的所有记录的Sname、Ssex和Class列。select sname,ssex,class from STUDENT2、 查询教师所有的单位即不重复的Depart列。select depart from TEACHER group by departselec…

php url模式在哪修改,php如何修改url
php如何修改url2020-07-03 12:15:40php修改url的方法:1、通过配置文件修改URL规则;2、设置URL伪静态,即限制伪静态的后缀;3、在配置文件中开启路由支持,并配置路由;4、将URL进行重写即可。PHP对URL设置一、…

国外十大最流行PHP框架排名
以下为十个目前最流行的基于MVC设计模式的PHP框架。1. YiiYii是一个基于组件的高性能的PHP的框架,用于开发大规模Web应用。Yii采用严格的OOP编写,并有着完善的库引用以及全面的教程。从MVC,DAO/ActiveRecord,widgets,c…

python_web框架
一、web框架 web框架: 自己完成socket的web框架:如,Tornado等由WSGI完成socket的web框架:如,Django、flash等两种实现过程: 第二种WSGI方式的,由于自带socket所以可直接写后端代码。 python标准…

g-gdb 调试多线程
代码调试工具gdb是一个能够让我们在工作中高效排查代码异常根源的利器。 在此将gdb针对多线程的调试方式做一个笔记,也方便后续回顾以及分享大家。 本文采用的是一个简单的多线程代码示例,同时调试是在mac上进行的 mac安装gdb brew install gdb即可 基…

php数据库html文本,关于php,mysql,html的数字分页和文本_php
请勿盗版,转载请加上出处http://blog.csdn.net/yanlintao1请勿盗版,转载请加上出处http://blog.csdn.net/yanlintao1首先进行样式展示希望对大家有所帮助,也希望大家给出意见和建议:第一种:数字分页第二种:…

WinDbg加载不同版本CLR
WinDbg调试.net2.0和.net4.0程序有所不同,因为.net4.0使用新版本的CLR。例如: mscoree.dll 变为 mscoree.dll 和 mscoreei.dll, mscorwks.dll 变为 clr.dll, mscorjit.dll 变为 clrjit.dll。 因此,在.net2.0加载mscorj…

交换机***工具——Yersinia
Yersinia是国外一款专门针对交换机执行第二层***的***工具。目前的版本是0.7.1。目前支持的操作系统及版本号如表1所示。表1 Yerdinia支持的操作系统操作系统名称版本号OpenBSD3.4 (pcap库版本至少0.7.2以上)Linux2.4.x和2.6.xSolaris5.8 64bits SPARCMac OSX10.4 Tiger (Intel…

Rocksdb 写流程,读流程,WAL文件,MANIFEST文件,ColumnFamily,Memtable,SST文件原理详解
文章目录前言Rocksdb写流程图WAL 原理分析概述文件格式查看WAL的工具创建WAL清理WALMANIFEST原理分析概述查看MANIFEST的工具创建 及 清除 MANIFEST文件内容CcolumnFamily 详解概述API介绍核心数据结构创建以及删除MEMTABLE 实现概述实现Rocksdb写入逻辑概述实现总结关于写的一…

react 入门
首先安装node.js环境 下载地址 https://nodejs.org/en/download/检查安装版本 进入命令行npm -v~~3. 安装react命令环境 npm install - g react-native-cli ~~~ 初始化项目 FirstAppreact-native init FirstApp 转载于:https://www.cnblogs.com/liu-ya/p/10511537.html