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
最新推荐文章于 2021-10-20 15:39:43 发布