Skip to content

Commit

Permalink
Merge pull request #19581 from adamemerson/wip-cache-on-the-barrelhead
Browse files Browse the repository at this point in the history
Cache on the barrelhead
  • Loading branch information
mattbenjamin committed Jan 2, 2018
2 parents 2d0a5dc + d997f65 commit 05bcf0c
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 109 deletions.
8 changes: 4 additions & 4 deletions src/common/options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5617,14 +5617,14 @@ std::vector<Option> get_rgw_options() {
.set_default(10_min)
.set_description(""),

Option("rgw_bucket_info_cache_expiry_interval", Option::TYPE_UINT,
Option("rgw_cache_expiry_interval", Option::TYPE_UINT,
Option::LEVEL_ADVANCED)
.set_default(15_min)
.set_description("Number of seconds before entries in the bucket info "
"cache are assumed stale and re-fetched. Zero is never.")
.set_description("Number of seconds before entries in the cache are "
"assumed stale and re-fetched. Zero is never.")
.add_tag("performance")
.add_service("rgw")
.set_long_description("The Rados Gateway stores metadata about buckets in "
.set_long_description("The Rados Gateway stores metadata and objects in "
"an internal cache. This should be kept consistent "
"by the OSD's relaying notify events between "
"multiple watching RGW processes. In the event "
Expand Down
73 changes: 35 additions & 38 deletions src/rgw/rgw_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ int ObjectCache::get(string& name, ObjectCacheInfo& info, uint32_t mask, rgw_cac
return -ENOENT;
}

map<string, ObjectCacheEntry>::iterator iter = cache_map.find(name);
if (iter == cache_map.end()) {
auto iter = cache_map.find(name);
if (iter == cache_map.end() ||
(expiry.count() &&
(ceph::coarse_mono_clock::now() - iter->second.info.time_added) > expiry)) {
ldout(cct, 10) << "cache get: name=" << name << " : miss" << dendl;
if(perfcounter) perfcounter->inc(l_rgw_cache_miss);
if (perfcounter)
perfcounter->inc(l_rgw_cache_miss);
return -ENOENT;
}

Expand Down Expand Up @@ -68,48 +71,44 @@ int ObjectCache::get(string& name, ObjectCacheInfo& info, uint32_t mask, rgw_cac
return 0;
}

bool ObjectCache::chain_cache_entry(list<rgw_cache_entry_info *>& cache_info_entries, RGWChainedCache::Entry *chained_entry)
bool ObjectCache::chain_cache_entry(std::initializer_list<rgw_cache_entry_info*> cache_info_entries,
RGWChainedCache::Entry *chained_entry)
{
RWLock::WLocker l(lock);

if (!enabled) {
return false;
}

list<rgw_cache_entry_info *>::iterator citer;

list<ObjectCacheEntry *> cache_entry_list;

std::vector<ObjectCacheEntry*> entries;
entries.reserve(cache_info_entries.size());
/* first verify that all entries are still valid */
for (citer = cache_info_entries.begin(); citer != cache_info_entries.end(); ++citer) {
rgw_cache_entry_info *cache_info = *citer;

ldout(cct, 10) << "chain_cache_entry: cache_locator=" << cache_info->cache_locator << dendl;
map<string, ObjectCacheEntry>::iterator iter = cache_map.find(cache_info->cache_locator);
for (auto cache_info : cache_info_entries) {
ldout(cct, 10) << "chain_cache_entry: cache_locator="
<< cache_info->cache_locator << dendl;
auto iter = cache_map.find(cache_info->cache_locator);
if (iter == cache_map.end()) {
ldout(cct, 20) << "chain_cache_entry: couldn't find cache locator" << dendl;
return false;
}

ObjectCacheEntry *entry = &iter->second;
auto entry = &iter->second;

if (entry->gen != cache_info->gen) {
ldout(cct, 20) << "chain_cache_entry: entry.gen (" << entry->gen << ") != cache_info.gen (" << cache_info->gen << ")" << dendl;
ldout(cct, 20) << "chain_cache_entry: entry.gen (" << entry->gen
<< ") != cache_info.gen (" << cache_info->gen << ")"
<< dendl;
return false;
}

cache_entry_list.push_back(entry);
entries.push_back(entry);
}


chained_entry->cache->chain_cb(chained_entry->key, chained_entry->data);

list<ObjectCacheEntry *>::iterator liter;

for (liter = cache_entry_list.begin(); liter != cache_entry_list.end(); ++liter) {
ObjectCacheEntry *entry = *liter;

entry->chained_entries.push_back(make_pair(chained_entry->cache, chained_entry->key));
for (auto entry : entries) {
entry->chained_entries.push_back(make_pair(chained_entry->cache,
chained_entry->key));
}

return true;
Expand All @@ -125,7 +124,7 @@ void ObjectCache::put(string& name, ObjectCacheInfo& info, rgw_cache_entry_info

ldout(cct, 10) << "cache put: name=" << name << " info.flags=0x"
<< std::hex << info.flags << std::dec << dendl;
map<string, ObjectCacheEntry>::iterator iter = cache_map.find(name);
auto iter = cache_map.find(name);
if (iter == cache_map.end()) {
ObjectCacheEntry entry;
entry.lru_iter = lru.end();
Expand All @@ -135,8 +134,6 @@ void ObjectCache::put(string& name, ObjectCacheInfo& info, rgw_cache_entry_info
ObjectCacheEntry& entry = iter->second;
ObjectCacheInfo& target = entry.info;

invalidate_lru(entry);

entry.chained_entries.clear();
entry.gen++;

Expand Down Expand Up @@ -196,35 +193,34 @@ void ObjectCache::remove(string& name)
return;
}

map<string, ObjectCacheEntry>::iterator iter = cache_map.find(name);
auto iter = cache_map.find(name);
if (iter == cache_map.end())
return;

ldout(cct, 10) << "removing " << name << " from cache" << dendl;
ObjectCacheEntry& entry = iter->second;

for (list<pair<RGWChainedCache *, string> >::iterator iiter = entry.chained_entries.begin();
iiter != entry.chained_entries.end(); ++iiter) {
RGWChainedCache *chained_cache = iiter->first;
chained_cache->invalidate(iiter->second);
for (auto& kv : entry.chained_entries) {
kv.first->invalidate(kv.second);
}

remove_lru(name, iter->second.lru_iter);
cache_map.erase(iter);
}

void ObjectCache::touch_lru(string& name, ObjectCacheEntry& entry, std::list<string>::iterator& lru_iter)
void ObjectCache::touch_lru(string& name, ObjectCacheEntry& entry,
std::deque<string>::iterator& lru_iter)
{
while (lru_size > (size_t)cct->_conf->rgw_cache_lru_size) {
list<string>::iterator iter = lru.begin();
auto iter = lru.begin();
if ((*iter).compare(name) == 0) {
/*
* if the entry we're touching happens to be at the lru end, don't remove it,
* lru shrinking can wait for next time
*/
break;
}
map<string, ObjectCacheEntry>::iterator map_iter = cache_map.find(*iter);
auto map_iter = cache_map.find(*iter);
ldout(cct, 10) << "removing entry: name=" << *iter << " from cache LRU" << dendl;
if (map_iter != cache_map.end()) {
ObjectCacheEntry& entry = map_iter->second;
Expand Down Expand Up @@ -252,7 +248,8 @@ void ObjectCache::touch_lru(string& name, ObjectCacheEntry& entry, std::list<str
entry.lru_promotion_ts = lru_counter;
}

void ObjectCache::remove_lru(string& name, std::list<string>::iterator& lru_iter)
void ObjectCache::remove_lru(string& name,
std::deque<string>::iterator& lru_iter)
{
if (lru_iter == lru.end())
return;
Expand All @@ -264,7 +261,7 @@ void ObjectCache::remove_lru(string& name, std::list<string>::iterator& lru_iter

void ObjectCache::invalidate_lru(ObjectCacheEntry& entry)
{
for (list<pair<RGWChainedCache *, string> >::iterator iter = entry.chained_entries.begin();
for (auto iter = entry.chained_entries.begin();
iter != entry.chained_entries.end(); ++iter) {
RGWChainedCache *chained_cache = iter->first;
chained_cache->invalidate(iter->second);
Expand Down Expand Up @@ -298,8 +295,8 @@ void ObjectCache::do_invalidate_all()
lru_counter = 0;
lru_window = 0;

for (list<RGWChainedCache *>::iterator iter = chained_cache.begin(); iter != chained_cache.end(); ++iter) {
(*iter)->invalidate_all();
for (auto& cache : chained_cache) {
cache->invalidate_all();
}
}

Expand Down
46 changes: 28 additions & 18 deletions src/rgw/rgw_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "rgw_rados.h"
#include <string>
#include <map>
#include <unordered_map>
#include "include/types.h"
#include "include/utime.h"
#include "include/assert.h"
Expand Down Expand Up @@ -49,16 +50,17 @@ struct ObjectMetaInfo {
WRITE_CLASS_ENCODER(ObjectMetaInfo)

struct ObjectCacheInfo {
int status;
uint32_t flags;
uint64_t epoch;
int status = 0;
uint32_t flags = 0;
uint64_t epoch = 0;
bufferlist data;
map<string, bufferlist> xattrs;
map<string, bufferlist> rm_xattrs;
ObjectMetaInfo meta;
obj_version version;
obj_version version = {};
ceph::coarse_mono_time time_added = ceph::coarse_mono_clock::now();

ObjectCacheInfo() : status(0), flags(0), epoch(0), version() {}
ObjectCacheInfo() = default;

void encode(bufferlist& bl) const {
ENCODE_START(5, 3, bl);
Expand Down Expand Up @@ -126,29 +128,31 @@ WRITE_CLASS_ENCODER(RGWCacheNotifyInfo)

struct ObjectCacheEntry {
ObjectCacheInfo info;
std::list<string>::iterator lru_iter;
std::deque<string>::iterator lru_iter;
uint64_t lru_promotion_ts;
uint64_t gen;
std::list<pair<RGWChainedCache *, string> > chained_entries;
std::vector<pair<RGWChainedCache *, string> > chained_entries;

ObjectCacheEntry() : lru_promotion_ts(0), gen(0) {}
};

class ObjectCache {
std::map<string, ObjectCacheEntry> cache_map;
std::list<string> lru;
std::unordered_map<string, ObjectCacheEntry> cache_map;
std::deque<string> lru;
unsigned long lru_size;
unsigned long lru_counter;
unsigned long lru_window;
RWLock lock;
CephContext *cct;

list<RGWChainedCache *> chained_cache;
vector<RGWChainedCache *> chained_cache;

bool enabled;
ceph::timespan expiry;

void touch_lru(string& name, ObjectCacheEntry& entry, std::list<string>::iterator& lru_iter);
void remove_lru(string& name, std::list<string>::iterator& lru_iter);
void touch_lru(string& name, ObjectCacheEntry& entry,
std::deque<string>::iterator& lru_iter);
void remove_lru(string& name, std::deque<string>::iterator& lru_iter);
void invalidate_lru(ObjectCacheEntry& entry);

void do_invalidate_all();
Expand All @@ -160,8 +164,11 @@ class ObjectCache {
void set_ctx(CephContext *_cct) {
cct = _cct;
lru_window = cct->_conf->rgw_cache_lru_size / 2;
expiry = std::chrono::seconds(cct->_conf->get_val<uint64_t>(
"rgw_cache_expiry_interval"));
}
bool chain_cache_entry(list<rgw_cache_entry_info *>& cache_info_entries, RGWChainedCache::Entry *chained_entry);
bool chain_cache_entry(std::initializer_list<rgw_cache_entry_info*> cache_info_entries,
RGWChainedCache::Entry *chained_entry);

void set_enabled(bool status);

Expand Down Expand Up @@ -236,14 +243,15 @@ class RGWCache : public T
RGWObjVersionTracker *objv_tracker, rgw_raw_obj& obj,
bufferlist& bl, off_t ofs, off_t end,
map<string, bufferlist> *attrs,
rgw_cache_entry_info *cache_info) override;
rgw_cache_entry_info *cache_info,
boost::optional<obj_version> refresh_version = boost::none) override;

int raw_obj_stat(rgw_raw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch, map<string, bufferlist> *attrs,
bufferlist *first_chunk, RGWObjVersionTracker *objv_tracker) override;

int delete_system_obj(rgw_raw_obj& obj, RGWObjVersionTracker *objv_tracker) override;

bool chain_cache_entry(list<rgw_cache_entry_info *>& cache_info_entries, RGWChainedCache::Entry *chained_entry) override {
bool chain_cache_entry(std::initializer_list<rgw_cache_entry_info *> cache_info_entries, RGWChainedCache::Entry *chained_entry) override {
return cache.chain_cache_entry(cache_info_entries, chained_entry);
}
};
Expand Down Expand Up @@ -281,7 +289,8 @@ int RGWCache<T>::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::R
RGWObjVersionTracker *objv_tracker, rgw_raw_obj& obj,
bufferlist& obl, off_t ofs, off_t end,
map<string, bufferlist> *attrs,
rgw_cache_entry_info *cache_info)
rgw_cache_entry_info *cache_info,
boost::optional<obj_version> refresh_version)
{
rgw_pool pool;
string oid;
Expand All @@ -298,8 +307,9 @@ int RGWCache<T>::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::R
flags |= CACHE_FLAG_OBJV;
if (attrs)
flags |= CACHE_FLAG_XATTRS;

if (cache.get(name, info, flags, cache_info) == 0) {

if ((cache.get(name, info, flags, cache_info) == 0) &&
(!refresh_version || !info.version.compare(&(*refresh_version)))) {
if (info.status < 0)
return info.status;

Expand Down

0 comments on commit 05bcf0c

Please sign in to comment.