Ceph源码分析-KeyValueStore

KeyValueStore 是 Ceph 支持的另一个存储引擎(第一个是FileStore),它是在 Emporer 版本中Add LevelDB support to ceph cluster backend store Design Summit 上由本人提出并实现了原型系统,在 Firely 版本中实现了与 ObjectStore 的对接。目前已经合并到 Ceph 的 Master 上。

KeyValueStore 相对于 FileStore 是一个轻量级实现,目标是利用其不同 Backend 提供的能力来为 Ceph 的不同应用场景服务。如目前的默认 engine 是 LevelDB,期望来提供高性能的写性能。

主要数据结构

KeyValueStore主要由三部分组成,一个是继承ObjectStore 的KeyValueStore 类,另一个是GenericObjectMap(类似于FileStore 的DBObjectMap),最后一个是继承GenericObjectMap 的StripObjectMap。GenericObjectMap 是主要用来访问后端Engine 的实现,它的作用有点类似VFS,而Engine 就是各种不同的FileSystem,它抽象出一些基本的方法(read/write)和一些高级接口(rename/clone)等等,首先最初开始设计GenericObjectMap的时候是打算直接利用已经存在的FileStore 的DBObjectMap,但是在一定的调查后发现DBObjectMap 缺少一定的扩展性,很难在不破坏现有接口的前提下来实现,因此最后与Sage 商定直接实现新的ObjectMap。那么什么是ObjectMap,正如在上篇FileStore 文章中所述,ObjectMap 是利用K/V 接口实现的一个多层次Map,目的是让OSD 最重要的Object 具备一个独立和高效查找的KV 空间,同时这个空间还能使用no-copy 的clone。

GenericObjectMap 在提供了一个面向Object 的通用KV 空间后,StripObjectMap 继承了GenericObjectMap 实现了对Object Data 的封装,ObjectStore 有三种类型的数据: Data, attr 和Omap,后两者都是单一的KV 实现,可以直接利用GenericObjectMap 的原生接口实现,但是Data 的接口是类似于Posix 需要具备Parity Write 的能力,因此简单的将一个Object 的Data 作为一个键值对是不合适的,需要做一个Strip 的工作,将一个Object 的Data 根据一定宽度划分成多个键值对,这个工作就是由StripObjectMap 来完成。

最后KeyValueStore 类利用StripObjectMap 来完成了对ObjectStore 的方法实现。

主要 IO 路径

与FileStore 的实现类似,KeyValueStore 也会产生一个消息队列,所有来自上层PG 产生的IO 请求都会先放入这个队列,然后会有多个KeyValueStore 线程作为队列的消费者获取请求进行处理,因为PG 天生的隔离性,目前KeyValueStore 是利用PG 作为一个隔离单元,同一时间只有一个线程处理同一个PG 的请求。KeyValueStore 线程针对每一个请求会产生一个缓冲空间,因为一个请求作为一个事务会包含多个原子操作,为了保证事务的原子性和隔离性,每一个请求在中间阶段并不能写入到持久层,只能产生一些操作序列,而可能的副作用就需要被缓冲空间保存起来作为后续操作的上下文。最后KeyValueStore 线程会提交这个请求来完成这次事务。</font

KeyValueStore.h中相关定义如下

struct Op {
 utime_t start;
 uint64_t op;
 list<Transaction*> tls;
 Context *ondisk, *onreadable, *onreadable_sync;
 uint64_t ops, bytes;
 TrackedOpRef osd_op;
 };
 struct OpWQ : public ThreadPool::WorkQueue<OpSequencer>

消息处理请求控制

unsigned KeyValueStore::_do_transaction(Transaction& transaction,                                        BufferTransaction &t,                                        ThreadPool::TPHandle *handle)
时间: 2024-10-15 18:43:40

Ceph源码分析-KeyValueStore的相关文章

Openstack liberty 创建实例快照源码分析2

这是创建云主机实例快照源码分析系列的最后一篇,在第一篇文章中分析了从镜像启动云主机,创建在线/离线快照的过程:本篇将分析从启动盘启动的云主机创建快照的过程,下面请看正文: 磁盘启动云主机,离线(在线)快照 nova-api处理过程 函数入口和前述一样,还是 nova/api/openstack/compute/servers.py/ServersController._action_create_image,下面一起来看看: def _action_create_image(self, req,

Openstack liberty源码分析 之 云主机的启动过程3

接上篇Openstack liberty源码分析 之 云主机的启动过程2, 简单回顾下:nova-conductor收到nova-scheduler返回的主机列表后,依次发送异步rpc请求给目标主机的nova-compute服务,下面继续来看nova-compute服务的处理过程: nova-compute 根据路由映射,nova-compute中处理云主机启动请求的方法为 nova/compute/manager.py.ComputeManager.py.build_and_run_insta

Openstack liberty 创建实例快照源码分析1

Openstack liberty中也支持对云主机执行快照,快照是备份系统中一种常用的数据保护技术,在生产系统故障后,能通过快照将系统快速恢复到快照时间点:那Openstack中的云主机快照是否也支持这种故障恢复呢?请看下文: Openstack支持对处于运行或者停止状态的云主机执行快照,另外Openstack既可以从镜像启动云主机,也可以从启动磁盘启动云主机,根据条件组合,可以执行下面4中快照: 镜像启动云主机的离线快照 镜像启动云主机的在线快照 磁盘启动云主机的离线快照 磁盘启动云主机的在线

OpenStack Kolla 源码分析 --Ansible

OpenStack Kolla 源码分析 –Ansible Kolla介绍 Kolla项目利用Docker.Docker-Compose.Ansible来完成部署OpenStack,目前Kolla已经能够完成一个all-in-one的开发环境的部署.从Kolla项目spec中的描述来看,主要是利用Docker容器的隔离性来达到OpenStack的原子升级.回退在升级.整个升级.回退的过程更容易控制影响范围,降低整个OpenStack的运维复杂度.Kolla 提供了生产级别的 OpenStack

TeamTalk源码分析之login_server

login_server是TeamTalk的登录服务器,负责分配一个负载较小的MsgServer给客户端使用,按照新版TeamTalk完整部署教程来配置的话,login_server的服务端口就是8080,客户端登录服务器地址配置如下(这里是win版本客户端): 1.login_server启动流程 login_server的启动是从login_server.cpp中的main函数开始的,login_server.cpp所在工程路径为server\src\login_server.下表是logi

Android触摸屏事件派发机制详解与源码分析二(ViewGroup篇)

1 背景 还记得前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>中关于透过源码继续进阶实例验证模块中存在的点击Button却触发了LinearLayout的事件疑惑吗?当时说了,在那一篇咱们只讨论View的触摸事件派发机制,这个疑惑留在了这一篇解释,也就是ViewGroup的事件派发机制. PS:阅读本篇前建议先查看前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>,这一篇承接上一篇. 关于View与ViewGroup的区别在前一篇的A

HashMap与TreeMap源码分析

1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Java这么久,也写过一些小项目,也使用过TreeMap无数次,但到现在才明白它的实现原理).因此本着"不要重复造轮子"的思想,就用这篇博客来记录分析TreeMap源码的过程,也顺便瞅一瞅HashMap. 2. 继承结构 (1) 继承结构 下面是HashMap与TreeMap的继承结构: pu

Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7)【转】

原文地址:Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinaunix.net/uid-25909619-id-4938395.html 前面粗略分析start_kernel函数,此函数中基本上是对内存管理和各子系统的数据结构初始化.在内核初始化函数start_kernel执行到最后,就是调用rest_init函数,这个函数的主要使命就是创建并启动内核线

Spark的Master和Worker集群启动的源码分析

基于spark1.3.1的源码进行分析 spark master启动源码分析 1.在start-master.sh调用master的main方法,main方法调用 def main(argStrings: Array[String]) { SignalLogger.register(log) val conf = new SparkConf val args = new MasterArguments(argStrings, conf) val (actorSystem, _, _, _) =