ivanjobs.github.io - Ceph源码解析(1)-Create Pool过程探究









Search Preview

Ceph源码解析(1)-Create Pool过程探究 | Ivan的博客

ivanjobs.github.io
这篇博客目的很单一,就是探究Create Pool的执行流程,实验的上下文也很简单,使用命令行工具创建Pool,在ceph源码中打log,以此来探究Ceph源码的执行过程,以及调用流程中遭遇的相关概念和技术。
.io > ivanjobs.github.io

SEO audit: Content analysis

Language Error! No language localisation is found.
Title Ceph源码解析(1)-Create Pool过程探究 | Ivan的博客
Text / HTML ratio 44 %
Frame Excellent! The website does not use iFrame solutions.
Flash Excellent! The website does not have any flash contents.
Keywords cloud << = Ceph pool Python Mesos return IvanJobs create osd reply mesos mona0leaderosd op test case OpenStack ceph dout0 onfinish
Keywords consistency
Keyword Content Title Description Headings
<< 18
= 17
Ceph 15
pool 13
Python 7
Mesos 7
Headings
H1 H2 H3 H4 H5 H6
1 0 8 0 0 0
Images We found 1 images on this web page.

SEO Keywords (Single)

Keyword Occurrence Density
<< 18 0.90 %
= 17 0.85 %
Ceph 15 0.75 %
pool 13 0.65 %
Python 7 0.35 %
Mesos 7 0.35 %
return 6 0.30 %
IvanJobs 5 0.25 %
create 5 0.25 %
osd 5 0.25 %
reply 5 0.25 %
mesos 5 0.25 %
mona0leaderosd 5 0.25 %
op 4 0.20 %
test 4 0.20 %
case 4 0.20 %
OpenStack 4 0.20 %
ceph 3 0.15 %
dout0 3 0.15 %
onfinish 3 0.15 %

SEO Keywords (Two Word)

Keyword Occurrence Density
pool create 5 0.25 %
osd pool 5 0.25 %
p = 4 0.20 %
dout0 << 3 0.15 %
<< dendl 3 0.15 %
v1 from 3 0.15 %
damp updates 2 0.10 %
= p>second 2 0.10 %
Ceph v1023 2 0.10 %
pg_num 8 2 0.10 %
mon_commandprefix osd 2 0.10 %
create pg_num 2 0.10 %
8 pool 2 0.10 %
pool test 2 0.10 %
Ceph RGW 2 0.10 %
test v 2 0.10 %
switch m>get_type 2 0.10 %
7fee3f881700 mona0leaderosd 2 0.10 %
op op>mark_osdmon_event__func__ 2 0.10 %
op>mark_osdmon_event__func__ PaxosServiceMessage 2 0.10 %

SEO Keywords (Three Word)

Keyword Occurrence Density Possible Spam
osd pool create 5 0.25 % No
PaxosServiceMessage m = 2 0.10 % No
pool test v 2 0.10 % No
8 pool test 2 0.10 % No
pg_num 8 pool 2 0.10 % No
create pg_num 8 2 0.10 % No
pool create pg_num 2 0.10 % No
mon_commandprefix osd pool 2 0.10 % No
7fee3f881700 mona0leaderosd e124 2 0.10 % No
op op>mark_osdmon_event__func__ PaxosServiceMessage 2 0.10 % No
op>mark_osdmon_event__func__ PaxosServiceMessage m 2 0.10 % No
m = static_castop>get_req 2 0.10 % No
v v1 from 2 0.10 % No
= static_castop>get_req dout0 2 0.10 % No
static_castop>get_req dout0 << 2 0.10 % No
mona0leaderosd e124 IvanJobs 2 0.10 % No
<< m << 2 0.10 % No
m << from 2 0.10 % No
<< from << 2 0.10 % No
from << m>get_orig_source_inst 2 0.10 % No

SEO Keywords (Four Word)

Keyword Occurrence Density Possible Spam
op>mark_osdmon_event__func__ PaxosServiceMessage m = 2 0.10 % No
from << m>get_orig_source_inst << 2 0.10 % No
PaxosServiceMessage m = static_castop>get_req 2 0.10 % No
m = static_castop>get_req dout0 2 0.10 % No
= static_castop>get_req dout0 << 2 0.10 % No
mon_commandprefix osd pool create 2 0.10 % No
osd pool create pg_num 2 0.10 % No
7fee3f881700 mona0leaderosd e124 IvanJobs 2 0.10 % No
pool create pg_num 8 2 0.10 % No
create pg_num 8 pool 2 0.10 % No
<< m << from 2 0.10 % No
m << from << 2 0.10 % No
<< from << m>get_orig_source_inst 2 0.10 % No
<< m>get_orig_source_inst << dendl 2 0.10 % No
op op>mark_osdmon_event__func__ PaxosServiceMessage m 2 0.10 % No
pg_num 8 pool test 2 0.10 % No
<< dendl switch m>get_type 2 0.10 % No
8 pool test v 2 0.10 % No
pool test v v1 2 0.10 % No
test v v1 from 2 0.10 % No

Internal links in - ivanjobs.github.io

开始使用gtest
开始使用gtest | Ivan的博客
寻找正确的语义[比赛总结]
寻找正确的语义[比赛总结] | Ivan的博客
score_thresholder服务开发总结
score_thresholder服务开发总结 | Ivan的博客
Debug CPP Program On Ubuntu
Debug CPP Program On Ubuntu | Ivan的博客
Modern CPP Developer Need To Know
Modern CPP Developer Need To Know | Ivan的博客
汇编语言学习笔记
汇编语言学习笔记 | Ivan的博客
Mesos Quota 和 Reservation
Mesos Quota 和 Reservation | Ivan的博客
libprocess学习笔记
libprocess学习笔记 | Ivan的博客
Consul使用笔记
Consul使用笔记 | Ivan的博客
SSH重新学习
SSH重新学习 | Ivan的博客
Protocol buffers 代码入门
Protocol buffers 代码入门 | Ivan的博客
Mesos Slave 如何上报资源?
Mesos Slave 如何上报资源? | Ivan的博客
Object Locator (Ceph) 探究笔记
Object Locator (Ceph) 探究笔记 | Ivan的博客
librados接口使用
librados接口使用 | Ivan的博客
Ceph RGW Pools 浅析
Ceph RGW Pools 浅析 | Ivan的博客
在单机上搭建多Ceph集群
在单机上搭建多Ceph集群 | Ivan的博客
Dockerfile中RUN/CMD/ENTRYPOINT的区分
Dockerfile中RUN/CMD/ENTRYPOINT的区分 | Ivan的博客
strace使用入门
strace使用入门 | Ivan的博客
Haystack论文学习笔记
Haystack论文学习笔记 | Ivan的博客
Mesos关联配置
Mesos关联配置 | Ivan的博客
ZooKeeper概览
ZooKeeper概览 | Ivan的博客
Ceph故障解析-filestore_merge_threshold
Ceph故障解析-filestore_merge_threshold | Ivan的博客
基于laravel+mysql的容器化DAL方案
基于laravel+mysql的容器化DAL方案 | Ivan的博客
vuejs使用小结1
vuejs使用小结1 | Ivan的博客
Ceph新技能Get
Ceph新技能Get | Ivan的博客
Ceph v10.2.3 RGW源码解析2
Ceph v10.2.3 RGW源码解析2 | Ivan的博客
Ceph v10.2.3 RGW源码解析1
Ceph v10.2.3 RGW源码解析1 | Ivan的博客
s3cmd使用说明
s3cmd使用说明 | Ivan的博客
vuejs工具链简介
vuejs工具链简介 | Ivan的博客
requirejs简介
requirejs简介 | Ivan的博客
可编程自动化输入方案(Mac下)
可编程自动化输入方案(Mac下) | Ivan的博客
Mesos Supress/Revive Offers测试
Mesos Supress/Revive Offers测试 | Ivan的博客
Mesos Offer生命周期杂记
Mesos Offer生命周期杂记 | Ivan的博客
Mesos Agent Containerizer分析
Mesos Agent Containerizer分析 | Ivan的博客
get started with createjs chapter 1 notes
get started with createjs chapter 1 notes | Ivan的博客
mesos agent /monitor/statistics返回数据业务意义
mesos agent /monitor/statistics返回数据业务意义 | Ivan的博客
mesos master/messages_deactivate_frameworks 不生效?
mesos master/messages_deactivate_frameworks 不生效? | Ivan的博客
KMP算法杂谈
KMP算法杂谈 | Ivan的博客
Mesos配置项深入分析
Mesos配置项深入分析 | Ivan的博客
mesos-master replicated_log存的是什么?
mesos-master replicated_log存的是什么? | Ivan的博客
mesos disk usage vs df 结果不一致问题
mesos disk usage vs df 结果不一致问题 | Ivan的博客
Mesos GC原理解析
Mesos GC原理解析 | Ivan的博客
准备mesos单机版开发测试环境
准备mesos单机版开发测试环境 | Ivan的博客
Mesos 1.0.0 源码解析杂记
Mesos 1.0.0 源码解析杂记 | Ivan的博客
stout学习笔记
stout学习笔记 | Ivan的博客
gflags学习笔记
gflags学习笔记 | Ivan的博客
ceph fuse挂载cephfs, ls不出文件列表问题,调试记录
ceph fuse挂载cephfs, ls不出文件列表问题,调试记录 | Ivan的博客
Ceph源码解析(3)-rados put过程探究
Ceph源码解析(3)-rados put过程探究 | Ivan的博客
Hub,Bridge,Switch和Gateway是什么?
Hub,Bridge,Switch和Gateway是什么? | Ivan的博客
数论学习笔记
数论学习笔记 | Ivan的博客
二分图专题解析
二分图专题解析 | Ivan的博客
Ceph Cluster调优日志
Ceph Cluster调优日志 | Ivan的博客
boost库的智能指针
boost库的智能指针 | Ivan的博客
Linux命令使用记录
Linux命令使用记录 | Ivan的博客
Vim Cheat Sheet
Vim Cheat Sheet | Ivan的博客
原码、反码、补码笔记
原码、反码、补码笔记 | Ivan的博客
ceph-deploy 配置文件比较 BUG
ceph-deploy 配置文件比较 BUG | Ivan的博客
Ceph源码解析(2)-rados put过程探究
Ceph源码解析(2)-rados put过程探究 | Ivan的博客
Ceph Release 概述
Ceph Release 概述 | Ivan的博客
Ceph CRUSH Map 维护详解
Ceph CRUSH Map 维护详解 | Ivan的博客
题解[第二周]
题解[第二周] | Ivan的博客
MathQuill Math Equation Cheatsheet
MathQuill Math Equation Cheatsheet | Ivan的博客
题解[第一周]
题解[第一周] | Ivan的博客
Ceph集群运维问题记录
Ceph集群运维问题记录 | Ivan的博客
linux man高级技巧
linux man高级技巧 | Ivan的博客
Git 我错了!
Git 我错了! | Ivan的博客
Ceph源码解析(1)-Create Pool过程探究
Ceph源码解析(1)-Create Pool过程探究 | Ivan的博客
准备Ceph开发环境
准备Ceph开发环境 | Ivan的博客
Ceph:Too Many PGs Per OSD
Ceph:Too Many PGs Per OSD | Ivan的博客
UVA 11292 题解
UVA 11292 题解 | Ivan的博客
Ceph RBD 文件映射实验笔记
Ceph RBD 文件映射实验笔记 | Ivan的博客
硬盘分区
硬盘分区 | Ivan的博客
硬盘模型
硬盘模型 | Ivan的博客
Ceph配置项
Ceph配置项 | Ivan的博客
OSTEP 文件系统实现
OSTEP 文件系统实现 | Ivan的博客
在Ceph底层xfs上找到你上传的文件
在Ceph底层xfs上找到你上传的文件 | Ivan的博客
使用s3cmd操作ceph rgw
使用s3cmd操作ceph rgw | Ivan的博客
Ceph核心概念备忘录
Ceph核心概念备忘录 | Ivan的博客
COSBench使用笔记
COSBench使用笔记 | Ivan的博客
使用saltstack部署运维ceph集群笔记
使用saltstack部署运维ceph集群笔记 | Ivan的博客
如何使用salt states?
如何使用salt states? | Ivan的博客
ceph-deploy命令详解
ceph-deploy命令详解 | Ivan的博客
dd笔记
dd笔记 | Ivan的博客
DTrace是什么?
DTrace是什么? | Ivan的博客
Ceph Cache Tier笔记
Ceph Cache Tier笔记 | Ivan的博客
Linux下理解filesystem/device/mount等概念
Linux下理解filesystem/device/mount等概念 | Ivan的博客
Base64编码详解与应用
Base64编码详解与应用 | Ivan的博客
URLEncoder学习笔记
URLEncoder学习笔记 | Ivan的博客
Ceph论文阅读笔记
Ceph论文阅读笔记 | Ivan的博客
使用Python inotify监控文件变化
使用Python inotify监控文件变化 | Ivan的博客
Git命令Snippets
Git命令Snippets | Ivan的博客

Ivanjobs.github.io Spined HTML


Ceph源码解析(1)-Create Pool过程探究 | Ivan的博客 最新文章 dev ops math algorithm personal 开始使用gtest 2018书单课单 2017年总结/2018年展望 寻找正确的语义[比赛总结] score_thresholder服务开发总结 Debug CPP Program On Ubuntu Modern CPP Developer Need To Know 汇编语言学习笔记 Mesos Quota 和 Reservation libprocess学习笔记 Consul使用笔记 SSH重新学习 Protocol buffers 代码入门 Mesos Slave 如何上报资源? Object Locator (Ceph) 探究笔记 librados接口使用 Ceph RGW Pools 浅析 在单机上搭建多Ceph集群 2016年总结/2017年展望 Dockerfile中RUN/CMD/ENTRYPOINT的区分 strace使用入门 Haystack论文学习笔记 Mesos关联配置 ZooKeeper概览 Ceph故障解析-filestore_merge_threshold 基于laravel+mysql的容器化DAL方案 vuejs使用小结1 Ceph新技能Get Ceph v10.2.3 RGW源码解析2 Ceph v10.2.3 RGW源码解析1 s3cmd使用说明 vuejs工具链简介 requirejs简介 mesos maintenance深度解析 可编程自动化输入方案(Mac下) Mesos Supress/Revive Offers测试 Mesos Offer生命周期杂记 MesosWage-earnerContainerizer分析 get started with createjs installment 1 notes mesos wage-earner /monitor/statistics返回数据业务意义 mesos master/messages_deactivate_frameworks 不生效? mesos /flags 403 forbidden? KMP算法杂谈 Mesos配置项深入分析 mesos-master replicated_log存的是什么? mesos disk usage vs df 结果不一致问题 Mesos GC原理解析 准备mesos单机版开发测试环境 Mesos 1.0.0 源码解析杂记 stout学习笔记 gflags学习笔记 ceph fuse挂载cephfs, ls不出文件列表问题,调试记录 Ceph源码解析(3)-rados put过程探究 Hub,Bridge,Switch和Gateway是什么? 数论学习笔记 二分图专题解析 Ceph Cluster调优日志 boost库的智能指针 Linux命令使用记录 Vim Cheat Sheet 原码、反码、补码笔记 ceph-deploy 配置文件比较 BUG Ceph源码解析(2)-rados put过程探究 Ceph Release 概述 Ceph CRUSH Map 维护详解 题解[第二周] MathQuill Math Equation Cheatsheet 题解[第一周] Ceph集群运维问题记录 linux man高级技巧 Git 我错了! Ceph源码解析(1)-Create Pool过程探究 准备Ceph开发环境 Ceph:Too Many PGs Per OSD UVA 11292 题解 Docker Private Registry(Ceph Swift) 搭建笔记 Ceph RBD 文件映射实验笔记 硬盘分区 硬盘模型 Ceph配置项 OSTEP 文件系统实现 在Ceph底层xfs上找到你上传的文件 使用s3cmd操作ceph rgw Ceph核心概念备忘录 COSBench使用笔记 GCJ2015 Qualification Round-B题解 使用saltstack部署运维ceph集群笔记 如何使用salt states? ceph-deploy命令详解 dd笔记 DTrace是什么? Ceph Cache Tier笔记 Linux下理解filesystem/device/mount等概念 Base64编码详解与应用 URLEncoder学习笔记 Ceph论文阅读笔记 使用Python inotify监控文件变化 Git命令Snippets 使用Nginx做LB MathQuill学习笔记 Docker化Laravel开发环境 Ceph Pool PG配置说明 Ceph 笔记 Ceph源码分析 Latex数学符号 为Ceph OSS服务搭建LB Ceph RGW S3接口测试:诡异的403 AccessDenied问题 访问Ceph RGW失败 403 Forbidden问题 解决历程 Ceph RADOS论文研读笔记 Ceph源码分析:从一个REST请求,到OSD存储。 各种开源代码协议简述 OpenStack Projects简述 OpenStack Ceilometer 笔记 RabbitMQ 和 oslo.messaging Ceph Rest API 身份验证方式(S3) tcpdump笔记 Ceph集群部署笔记 Python PEP8规范笔记 Python Decorator(装饰器)模式 笔记 libvirt笔记 OpenStack oslo 概览 OpenStack KeyStone API http://localhost:5000/ 源码追踪 Python pdb笔记 zero length variety in a struct Jenkins' Hash Functions NTP部署笔记 Linux iptables笔记 Python Paste笔记 Python PasteDeploy笔记 Python eventlet笔记 使用curl测试RESTful接口 ubuntu14.04下安装devstack devstack 安装指南【最简单】 Docker操作记录 git merge 详解 Python 包管理详解 阿里云服务器设置swapfile的方法 shell脚本编写向导 搭建Laravel全栈开发环境 2016 May 12 Ceph源码解析(1)-Create Pool过程探究 这篇博客目的很单一,就是探究Create Pool的执行流程,实验的上下文也很简单,使用命令行工具创建Pool,在ceph源码中打log,以此来探究Ceph源码的执行过程,以及调用流程中遭遇的相关概念和技术。 执行命令 ceph osd pool create test 8 ./rados ls -p test rados 首先从命令行下手探究,ceph集群上的rados命令,对应的是一个二进制程序,具体代码在src/tools/rados.cc。 从rados.cc的源码里追溯,发现rados这个命令行工具实际上使用的是librados库的接口。 if (create_pool) { ret = rados.pool_create(pool_name, 0, 0); if (ret < 0) { cerr << "error creating pool " << pool_name << ": " << cpp_strerror(ret) << std::endl; goto out; } } librados 所以创建一个pool的线索,就来到了librados里,具体源码文件为:src/librados/librados.cc。 librados里,pool_create是由RadosClient类实现的,具体代码为: int librados::RadosClient::pool_create(string& name, unsigned long long auid, int16_t crush_rule) { int r = wait_for_osdmap(); if (r < 0) { return r; } Mutex mylock ("RadosClient::pool_create::mylock"); int reply; Cond cond; bool done; Context *onfinish = new C_SafeCond(&mylock, &cond, &done, &reply); reply = objecter->create_pool(name, onfinish, auid, crush_rule); if (reply < 0) { delete onfinish; } else { mylock.Lock(); while(!done) cond.Wait(mylock); mylock.Unlock(); } return reply; } 杂七杂八的先不管,可以看出,RadosClient使用的是Objecter这个类来实现pool的创建。 osdc/objecter osdc是osd client的意思,该目录下封装了各类操作OSD的方法(感谢Ceph官方QQ群里“暴走中的徐尼玛”的帮助)。 objecter最终会创造一个操作,并且把它提交。可以从代码中看出,检查pool是否已经存在,是使用osdmap, 也就是说创建的pool信息是至少有部分在osdmap中的。最后会交由MonClient发送消息给Monitor,走的是PaxosService。如果要继续追溯,前提条件是对Ceph的消息发送机制熟悉,这样才能在Monitor端接收消息的地方,继续追踪下去。 ceph log系统 基于log调试ceph之前,需要对ceph 的log系统有一个大概的认识。如果浏览源码的话,你会发现一些dout,这些dout其实 是宏,用于输出调试信息,dout = debug out。并且跟我们常见的日志系统一样,可以设置日志等级。我们可以查看一些 模块默认的日志等级以及可以设置的日志等级。当然默认情况下,为了性能考虑。好的,下面我们看下ceph可以设置的log级别(1~20), level越大,则log的信息越多。如果设置log level 为10, 则小于等于10的所有dout信息都将记录下来。 mon/OSDMonitor 创建pool的消息发送给mon之后,交由OSDMonitor来处理,看一下preprocess_query这个函数: bool OSDMonitor::preprocess_query(MonOpRequestRef op) { op->mark_osdmon_event(__func__); PaxosServiceMessage *m = static_cast<PaxosServiceMessage*>(op->get_req()); dout(0) << "ivanjobs: preprocess_query " << *m << " from " << m->get_orig_source_inst() << dendl; switch (m->get_type()) { // READs specimen MSG_MON_COMMAND: return preprocess_command(op); specimen CEPH_MSG_MON_GET_OSDMAP: return preprocess_get_osdmap(op); // wateriness updates specimen MSG_OSD_MARK_ME_DOWN: return preprocess_mark_me_down(op); specimen MSG_OSD_FAILURE: 我们将上面的dout的等级调高,即为dout(0), 创建一个pool观察其输出。 ./src/out/mon.a.log:2016-05-16 15:54:09.624333 7fa239119700 0 mon.a@0(leader).osd e100 ivanjobs: preprocess_query mon_command({"prefix": "osd pool create", "pg_num": 8, "pool": "test"} v 0) v1 from client.134105 172.16.6.75:0/284101927 可以看出,pool create是作为MSG_MON_COMMAND传入OSDMonitor, 下面我们继续深入preprocess_command: 这个函数有非常多的if/else分支,用于处理不同的MON_COMMAND,我们只挂住osd pool create这个命令(ceph osd pool create): 但是在preprocess_command函数中,并没有找到osd pool create分支,为什么?因为这只是一个preprocess_query, 字面意思 就是对query的预处理,并不是所有的消息都会进行预处理。进行进一步的追溯发现,实际上ceph-mon作为一个PaxosService 实际上,在dispatch消息的过程中会执行两步: // preprocess if (preprocess_query(op)) return true; // easy! ... // update if (prepare_update(op)) { double wait = 0.0; ... 实际上,在prepare_update阶段才会涉及到osd pool create操作,下面我们在OSDMonitor::prepare_update处打log: bool OSDMonitor::prepare_update(MonOpRequestRef op) { op->mark_osdmon_event(__func__); PaxosServiceMessage *m = static_cast<PaxosServiceMessage*>(op->get_req()); dout(0) << "prepare_update " << *m << " from " << m->get_orig_source_inst() << dendl; dout(0) << "IvanJobs: type:" << m->get_type() << dendl; switch (m->get_type()) { // wateriness updates ... 使用ceph命令创建一个名为test的pool,日志如下: ./src/out/mon.a.log:2016-05-16 16:41:49.775332 7fa3298c5700 0 mon.a@0(leader).osd e110 IvanJobs: type:50 ./src/out/mon.a.log:2016-05-16 16:41:53.729464 7fa3298c5700 0 mon.a@0(leader).osd e111 IvanJobs: prepare_update mon_command({"prefix": "osd pool create", "pg_num": 8, "pool": "test"} v 0) v1 from client.144107 172.16.6.75:0/3994929201 验证了我们的猜想,确实会调用prepare_update。 继续:prepare_update调用了prepare_command, prepare_command调用了prepare_command_impl, 在osd pool create的分支里,前面写了一大堆代码,check一些前置条件,最关键的一句是: err = prepare_new_pool(poolstr, 0, // auid=0 for admin created pool -1, // default crush rule ruleset_name, pg_num, pgp_num, erasure_code_profile, pool_type, (uint64_t)expected_num_objects, fast_read, ... prepare_new_pool并不是创建pool,而是prepare,真正的创建还没有开始,比较关键的是prepare_command_impl里的 wait_for_finished_proposal函数,这个函数将创建pool的操作,提交proposal。为什么? 因为OSDMap是Cluster Map的 一部分,也是通过PaxOs协议保持一致的,我们创建一个新pool的时候,OSDMap就发生了变化,这个变化必须在quorum里达成一致才行。 void wait_for_finished_proposal(MonOpRequestRef op, Context *c) { if (op) op->mark_event(service_name + ":wait_for_finished_proposal"); waiting_for_finished_proposal.push_back(c); } 我想要了解一下,上面的service_name是什么,打log发现: 2016-05-16 17:12:31.333927 7fee3f881700 0 mon.a@0(leader).osd e124 IvanJobs: prepare_update osd_alive(want up_thru 124 have 124) v1 from osd.1 172.16.6.75:6807/21127 2016-05-16 17:12:31.333929 7fee3f881700 0 mon.a@0(leader).osd e124 IvanJobs: type:73 2016-05-16 17:12:31.333936 7fee3f881700 0 service_name:osdmap 可以发现, service_name是osdmap。 因为不懂PaxOs算法,所以我们掠过PaxOs算法的过程,直接到达创建pool最终的地方,也就是元数据的创建。据我所知, OSDMap应该是保存在leveldb/RocksDB之类的数据库中的,只要找到对应的地方即可,猜测在OSDMonitor中有实现。 在OSDMonitor.cc的开头,包含了#include “MonitorDBStore.h”, 显然这个是跟本地存储相关,只要找到对应的接口调用的地方, 也就是pool元数据真正创建的地方。最终追溯到OSDMap.cc中的apply_incremental函数,关键部分: for (map<int64_t,pg_pool_t>::const_iterator p = inc.new_pools.begin(); p != inc.new_pools.end(); ++p) { pools[p->first] = p->second; pools[p->first].last_change = epoch; } for (map<int64_t,string>::const_iterator p = inc.new_pool_names.begin(); p != inc.new_pool_names.end(); ++p) { if (pool_name.count(p->first)) name_pool.erase(pool_name[p->first]); pool_name[p->first] = p->second; name_pool[p->second] = p->first; } 这里新增的pool是作为一个增量(incremental),增量是一个很好的抽象(联想到版本管理)。 这里可以看到,新增的pool被保存在两个个map中,分别是id=>pool_name和pool_name=>id。 总结 Ok,到这里就可以了,大概知道了从执行一个ceph osd pool create {pool_name} {pg_num}的一个完整过程。 中间涉及到client将消息传递给ceph-mon, ceph-mon之间通过PaxOs达成一致,并且最终写入元数据。本篇代码分析, 略显简陋,如果有读者看到,有更好的视角和总结,请不吝赐教。 参考 Ceph Commands (2) - Setting Debug Log Level Please enable JavaScript to view the comments powered by Disqus. All content is licensed under CC BY-NC-SA Buit with Jekyll and 3-Jekyll theme • Hosted on Github Table of Contents