标签:
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 的方法实现。
与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)
标签:
原文地址:http://my.oschina.net/u/2271251/blog/361918