Cache in BlueStore
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相关推荐
- ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析
文章目录 内存查看 内存控制 内存控制源码分析 通过gperftools接口获取osd进程实际内存 动态设置cache大小 动态调整cache比例 trim释放内存 本文通过对ceph-osd内存查看 ...
- ceph bluestore 源码分析:刷缓存(trim)逻辑
环境 ceph版本:12.2.1 部署模式:ec 2+1 osd: 3个 且资源池已经有数据 执行命令:ceph daemon osd.0 flush_store_cache 进行刷缓存.即将dump ...
- ceph存储引擎bluestore解析
原文链接:http://www.sysnote.org/2016/08/19/ceph-bluestore/ ceph后端支持多种存储引擎,以插件式的方式来进行管理使用,目前支持filestore,k ...
- Ceph BlueStore 和双写问题
论开源分布式存储,Ceph大名鼎鼎.用同一个存储池融合提供块存储.对象存储.集群文件系统.在国内有近年使用量迅速攀升,Ceph Day峰会也搬到北京来开了. 大型公司内部研发云虚拟化平台,常使用开源方 ...
- ceph bluestore中的磁盘空间管理
ceph bluestore摒弃了传统的本地文件系统,而直接使用裸磁盘作为OSD的存储介质,因而需要自行管理磁盘空间的分配与回收 概述 一个设计良好的磁盘空间管理器,需要兼顾空间和时间效率:blues ...
- 【ceph】后端存储ObjectStore|BlueStore
目录 ObjectStore简介 CEPH OBJECTSTORE API介绍 ObjectStore API 操作 事务 日志 实现 ObjectStore 实现 FileStore KeyValu ...
- BlueStore 介绍
ceph 目前是开源社区比较流行的分布式块存储系统,其以良好的架构,稳定性和完善的数据服务功能,获得的了广泛的部署和应用. 目前ceph 最大的问题是其性能相对较差,特别是无法发挥SSD等高速设备的硬 ...
- CPU Cache原理与示例
CPU Cache原理与示例 基础知识 现在的 CPU 多核技术,都会有几级缓存,老的 CPU 会有两级内存(L1 和 L2),新的CPU会有三级内存(L1,L2,L3 ),如下图所示: 其中: ...
- Cache Memory技术示例
Cache Memory技术示例 为什么需要cache?如何判断一个数据在cache中是否命中?cache的种类有哪些,区别是什么? 为什么需要cache memory 先思考第一个问题:程序是如何运 ...
最新文章
- 实现第一个自定义nginx模块
- commons-pool2-2.4.2连接池读后笔记
- layer的一种用法,自己画出弹出框样式
- php屏幕抓取,关于屏幕抓取:如何在PHP中实现Web scraper?
- 根据当前记录获取前一条与下一条记录常用 sql语句
- java两个线程交替执行
- LeetCode【217. Contains Duplicate】
- 详解各种锁:CAS、共享锁、排它锁、互斥锁、悲观锁、乐观锁、行级锁、表级锁、页级锁、死锁、JAVA对CAS的支持、ABA问题、AQS原理
- 【第二十七章】 springboot + zipkin(brave-okhttp实现)
- java生日正则表达式_java之正则表达式、日期操作
- 系统hosts文件的作用
- vue树形权限菜单_Vue.js 递归组件实现树形菜单(实例分享)
- MYSQL MVCC 实现机制
- 【组播技术入门 01】IP组播概述
- 小程序发布提审被驳回,提示当前提审小程序代码包中地理位置相关接口wx.getLocation暂未开通
- 数据库数据迁移的3种方案学习
- Failed to install the following Android SDK packages as some licences have not been accepted.
- 三菱Q系列PLC基本指令讲解
- 商用计算机使用温度,电脑一般的使用温度为?
- Linux常用命令——mysqladmin命令
热门文章
- ora01722java_java.sql.SQLSyntaxErrorException: ORA-01722: 无效数字
- 题外话:学习算法再出发
- 实训第 3 天 ------ 7.17
- 敬回忆一杯酒,来祭奠我那逝去的青春。
- 满足正常需求:Ubuntu下安装微信、QQ等
- MySql 查看未提交事务
- 专为实习生开发的一款程序:实习宙
- 【深度首发】车萝卜CEO马斌斌:以一百万销量、一个亿营收为小目标,成为汽车市场的“后装之王”丨Xtecher封面
- Tuxera NTFS2023Mac电脑免费U盘硬盘读写工具
- 浅谈线上教学--致2019年的那个寒冬