bluestore 自己管理裸设备为了提高性能自己也建立了cache BlueStore::Cache *BlueStore::Cache::create(CephContext* cct, string type, PerfCounters *logger) { Cache *c = nullptr; if (type == "lru") c = new LRUCache(cct); else if (type == "2q") c = new TwoQCache(cct); else assert(0 == "unrecognized cache type"); c->logger = logger; return c; } 从bluestore中可以看到 目前cache 分为两类,一类是lru,一类是2q。默认使用的是2q的实现。 bluestore中调用set_cache_shards 来初始化cache,在bluestore的构造函数中会调用 set_cache_shards(1); void BlueStore::set_cache_shards(unsigned num) { dout(10) << __func__ << " " << num << dendl; size_t old = cache_shards.size(); assert(num >= old); cache_shards.resize(num); for (unsigned i = old; i < num; ++i) { cache_shards[i] = Cache::create(cct, cct->_conf->bluestore_cache_type, logger); } } 从这段code 可以知道系统可以存在多个cache,具体是采用lru还是2q的话,是由ceph的cct->_conf->bluestore_cache_type 这个选项来决定的 int BlueStore::_create_collection( TransContext *txc, const coll_t &cid, unsigned bits, CollectionRef *c) { dout(15) << __func__ << " " << cid << " bits " << bits << dendl; int r; bufferlist bl; { RWLock::WLocker l(coll_lock); if (*c) { r = -EEXIST; goto out; } #bluestore在创建collection的时候制定了一个cache。 c->reset( new Collection( this, cache_shards[cid.hash_to_shard(cache_shards.size())], cid)); (*c)->cnode.bits = bits; coll_map[cid] = *c; } } BlueStore::Collection::Collection(BlueStore *ns, Cache *c, coll_t cid) : store(ns), cache(c), cid(cid), lock("BlueStore::Collection::lock", true, false), exists(true), onode_map(c) { } 从Collection的构造函数可以看到这里将cache赋值给onode_map BlueStore::OnodeRef BlueStore::Collection::get_onode( const ghobject_t& oid, bool create) { OnodeRef o = onode_map.lookup(oid); if (o) return o; mempool::bluestore_cache_other::string key; get_object_key(store->cct, oid, &key); return onode_map.add(oid, o); } 这样在get_onode 中在读取get_onode的时候首先在onode_map中查找,如果有的话,就直接返回了,没有在cache中找到的话 ,则找到后加入到cache中 与此同时在bluestore中有新建一个线程来定义回收cache占用的memory void *BlueStore::MempoolThread::entry() { Mutex::Locker l(lock); while (!stop) { for (auto i : store->cache_shards) { #调用2q的trim函数来回收内存 i->trim(shard_target, store->cache_meta_ratio, store->cache_data_ratio, bytes_per_onode); } store->_update_cache_logger(); utime_t wait; wait += store->cct->_conf->bluestore_cache_trim_interval; #定期wakeup 唤醒来执行trim cond.WaitInterval(lock, wait); } stop = false; return NULL; } void BlueStore::TwoQCache::_trim(uint64_t onode_max, uint64_t buffer_max) { dout(20) << __func__ << " onodes " << onode_lru.size() << " / " << onode_max << " buffers " << buffer_bytes << " / " << buffer_max << dendl; // onodes #如果cache占用的size小于最大的size,就不用回收了 int num = onode_lru.size() - onode_max; if (num <= 0) return; // don't even try }
bluestore使用的cache
猜你喜欢
转载自blog.csdn.net/tiantao2012/article/details/80180461
今日推荐
周排行