Cache in BlueStore

代码量不大,所以全部贴出。

CacheShard

CacheShard 是整个BlueStore中实现Cache的基类。

  /// A generic Cache Shardstruct CacheShard {CephContext *cct;PerfCounters *logger;// 注意cache的操作一定要线程安全,这里创建一个锁/// protect lru and other structuresceph::recursive_mutex lock = {ceph::make_recursive_mutex("BlueStore::CacheShard::lock")};// cache 种最大容量和当前使用量std::atomic <uint64_t> max = {0};std::atomic <uint64_t> num = {0};CacheShard(CephContext *cct) : cct(cct), logger(nullptr) {}virtual ~CacheShard() {}// 设置容量void set_max(uint64_t max_) {max = max_;}// 获取当前使用量uint64_t _get_num() {return num;}// 在 LruOnodeCacheShard、LruBufferCacheShard和TwoQBufferCacheShard种实现virtual void _trim_to(uint64_t new_size) = 0;void _trim() {if (cct->_conf->objectstore_blackhole) {// do not trim if we are throwing away IOs a layer downreturn;}_trim_to(max);}void trim() {std::lock_guard l(lock);_trim();}void flush() {std::lock_guard l(lock);// we should not be shutting down after the blackhole is enabledassert(!cct->_conf->objectstore_blackhole);_trim_to(0);}#ifdef DEBUG_CACHEvirtual void _audit(const char *s) = 0;
#elsevoid _audit(const char *s) { /* no-op */ }#endif};

OnodeCacheShard

  /// A Generic onode Cache Shardstruct OnodeCacheShard : public CacheShard {std::atomic <uint64_t> num_pinned = {0};std::array<std::pair<ghobject_t, ceph::mono_clock::time_point>, 64> dumped_onodes;virtual void _pin(Onode *o) = 0;virtual void _unpin(Onode *o) = 0;public:OnodeCacheShard(CephContext *cct) : CacheShard(cct) {}static OnodeCacheShard *create(CephContext *cct, std::string type,PerfCounters *logger);virtual void _add(Onode *o, int level) = 0;virtual void _rm(Onode *o) = 0;virtual void _unpin_and_rm(Onode *o) = 0;virtual void move_pinned(OnodeCacheShard *to, Onode *o) = 0;virtual void add_stats(uint64_t *onodes, uint64_t *pinned_onodes) = 0;bool empty() {return _get_num() == 0;}};

OnodeCacheShard::create()

// 父类引用指向子类对象。实际返回LruOnodeCacheShard对象。
// OnodeCacheShard
BlueStore::OnodeCacheShard *BlueStore::OnodeCacheShard::create(CephContext *cct,string type,PerfCounters *logger) {BlueStore::OnodeCacheShard *c = nullptr;// Currently we only implement an LRU cache for onodesc = new LruOnodeCacheShard(cct);c->logger = logger;return c;
}

LruOnodeCacheShard

// LruOnodeCacheShard
struct LruOnodeCacheShard : public BlueStore::OnodeCacheShard {// 创建一个list,其中保存的是Bluestore::Onode。list<Onode>typedef boost::intrusive::list<BlueStore::Onode,boost::intrusive::member_hook<BlueStore::Onode,boost::intrusive::list_member_hook<>,&BlueStore::Onode::lru_item> > list_t;list_t lru;// 构造函数,只在 OnodeCacheShard::create() 中被引用。explicit LruOnodeCacheShard(CephContext *cct) : BlueStore::OnodeCacheShard(cct) {}// 把onode加入缓存队列。void _add(BlueStore::Onode *o, int level) override {// put_cache()中设置Onode.cached标志位,表示该Onode加入缓存。检查pinned标志位,返回!pined。// pined 表示该对象是否加入缓存淘汰队列,如果不加入,说明不会被淘汰。if (o->put_cache()) {// level > 0,加入lru头部// level <= 0,加入lru尾部(level > 0) ? lru.push_front(*o) : lru.push_back(*o);} else {++num_pinned;}++num; // we count both pinned and unpinned entriesdout(20) << __func__ << " " << this << " " << o->oid << " added, num=" << num << dendl;}// 把onode从缓存队列中删除void _rm(BlueStore::Onode *o) override {// pop_cache()删除Onode.cached标志位(置未false)。检查pinned标志位,返回!pined。if (o->pop_cache()) {lru.erase(lru.iterator_to(*o));} else {ceph_assert(num_pinned);--num_pinned;}ceph_assert(num);--num;dout(20) << __func__ << " " << this << " " << " " << o->oid << " removed, num=" << num << dendl;}// 把对象从缓存队列中删除,并把num_pinned++,需要先调用addvoid _pin(BlueStore::Onode *o) override {lru.erase(lru.iterator_to(*o));++num_pinned;dout(20) << __func__ << this << " " << " " << " " << o->oid << " pinned" << dendl;}// 把对象加入缓存队列,num_pinned--,需要先调用addvoid _unpin(BlueStore::Onode *o) override {lru.push_front(*o);ceph_assert(num_pinned);--num_pinned;dout(20) << __func__ << this << " " << " " << " " << o->oid << " unpinned" << dendl;}// pined对象不在list队列中,所以只要把onode对象的cache标志位置为false即可void _unpin_and_rm(BlueStore::Onode *o) override {o->pop_cache();ceph_assert(num_pinned);--num_pinned;ceph_assert(num);--num;}//裁剪lru_list大小,此函数只能缩小,不能扩大,因为是删除操作,总不能无中生有吧void _trim_to(uint64_t new_size) override {if (new_size >= lru.size()) {return; // don't even try}uint64_t n = lru.size() - new_size;auto p = lru.end();ceph_assert(p != lru.begin());--p;ceph_assert(num >= n);num -= n;while (n-- > 0) {BlueStore::Onode *o = &*p;dout(20) << __func__ << "  rm " << o->oid << " "<< o->nref << " " << o->cached << " " << o->pinned << dendl;if (p != lru.begin()) {lru.erase(p--);} else {ceph_assert(n == 0);lru.erase(p);}auto pinned = !o->pop_cache();ceph_assert(!pinned);o->c->onode_map._remove(o->oid);}}// 移动pinned对象到新的OnodeCacheShardvoid move_pinned(OnodeCacheShard *to, BlueStore::Onode *o) override {if (to == this) {return;}ceph_assert(o->cached);ceph_assert(o->pinned);ceph_assert(num);ceph_assert(num_pinned);--num_pinned;--num;++to->num_pinned;++to->num;}// 统计对象总数和pinned对象数void add_stats(uint64_t *onodes, uint64_t *pinned_onodes) override {*onodes += num;*pinned_onodes += num_pinned;}
};

Cache in BlueStore相关推荐

  1. ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析

    文章目录 内存查看 内存控制 内存控制源码分析 通过gperftools接口获取osd进程实际内存 动态设置cache大小 动态调整cache比例 trim释放内存 本文通过对ceph-osd内存查看 ...

  2. ceph bluestore 源码分析:刷缓存(trim)逻辑

    环境 ceph版本:12.2.1 部署模式:ec 2+1 osd: 3个 且资源池已经有数据 执行命令:ceph daemon osd.0 flush_store_cache 进行刷缓存.即将dump ...

  3. ceph存储引擎bluestore解析

    原文链接:http://www.sysnote.org/2016/08/19/ceph-bluestore/ ceph后端支持多种存储引擎,以插件式的方式来进行管理使用,目前支持filestore,k ...

  4. Ceph BlueStore 和双写问题

    论开源分布式存储,Ceph大名鼎鼎.用同一个存储池融合提供块存储.对象存储.集群文件系统.在国内有近年使用量迅速攀升,Ceph Day峰会也搬到北京来开了. 大型公司内部研发云虚拟化平台,常使用开源方 ...

  5. ceph bluestore中的磁盘空间管理

    ceph bluestore摒弃了传统的本地文件系统,而直接使用裸磁盘作为OSD的存储介质,因而需要自行管理磁盘空间的分配与回收 概述 一个设计良好的磁盘空间管理器,需要兼顾空间和时间效率:blues ...

  6. 【ceph】后端存储ObjectStore|BlueStore

    目录 ObjectStore简介 CEPH OBJECTSTORE API介绍 ObjectStore API 操作 事务 日志 实现 ObjectStore 实现 FileStore KeyValu ...

  7. BlueStore 介绍

    ceph 目前是开源社区比较流行的分布式块存储系统,其以良好的架构,稳定性和完善的数据服务功能,获得的了广泛的部署和应用. 目前ceph 最大的问题是其性能相对较差,特别是无法发挥SSD等高速设备的硬 ...

  8. CPU Cache原理与示例

    CPU Cache原理与示例 基础知识 现在的 CPU 多核技术,都会有几级缓存,老的 CPU 会有两级内存(L1 和 L2),新的CPU会有三级内存(L1,L2,L3 ),如下图所示: 其中:  ...

  9. Cache Memory技术示例

    Cache Memory技术示例 为什么需要cache?如何判断一个数据在cache中是否命中?cache的种类有哪些,区别是什么? 为什么需要cache memory 先思考第一个问题:程序是如何运 ...

最新文章

  1. 实现第一个自定义nginx模块
  2. commons-pool2-2.4.2连接池读后笔记
  3. layer的一种用法,自己画出弹出框样式
  4. php屏幕抓取,关于屏幕抓取:如何在PHP中实现Web scraper?
  5. 根据当前记录获取前一条与下一条记录常用 sql语句
  6. java两个线程交替执行
  7. LeetCode【217. Contains Duplicate】
  8. 详解各种锁:CAS、共享锁、排它锁、互斥锁、悲观锁、乐观锁、行级锁、表级锁、页级锁、死锁、JAVA对CAS的支持、ABA问题、AQS原理
  9. 【第二十七章】 springboot + zipkin(brave-okhttp实现)
  10. java生日正则表达式_java之正则表达式、日期操作
  11. 系统hosts文件的作用
  12. vue树形权限菜单_Vue.js 递归组件实现树形菜单(实例分享)
  13. MYSQL MVCC 实现机制
  14. 【组播技术入门 01】IP组播概述
  15. 小程序发布提审被驳回,提示当前提审小程序代码包中地理位置相关接口wx.getLocation暂未开通
  16. 数据库数据迁移的3种方案学习
  17. Failed to install the following Android SDK packages as some licences have not been accepted.
  18. 三菱Q系列PLC基本指令讲解
  19. 商用计算机使用温度,电脑一般的使用温度为?
  20. Linux常用命令——mysqladmin命令

热门文章

  1. ora01722java_java.sql.SQLSyntaxErrorException: ORA-01722: 无效数字
  2. 题外话:学习算法再出发
  3. 实训第 3 天 ------ 7.17
  4. 敬回忆一杯酒,来祭奠我那逝去的青春。
  5. 满足正常需求:Ubuntu下安装微信、QQ等
  6. MySql 查看未提交事务
  7. 专为实习生开发的一款程序:实习宙
  8. 【深度首发】车萝卜CEO马斌斌:以一百万销量、一个亿营收为小目标,成为汽车市场的“后装之王”丨Xtecher封面
  9. Tuxera NTFS2023Mac电脑免费U盘硬盘读写工具
  10. 浅谈线上教学--致2019年的那个寒冬