-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add non-volatile cache to reduce the cost of storage (#1099)
* runnable navycache add nvm cache lookup draft done add some comments rename file and add comments finish core funcs unit test done adjust the dram size and now nvm cache test can pass return nullptr when itemhandle is nullptr on Lookup() changed the interface multiple rocksdb share the same secondary instance on the same node for debug set the default secondary cache size to 0 to meta will not use it change gflag type add UUL add bucket power and lock power to conf move impl from CahcelibLRU.h to cpp and clean * type and config * remove comment * cmake * add override * change the default cache file size to 0 * set cache size unsigned long * rebase and add comments * rebase Co-authored-by: Sophie <[email protected]>
- Loading branch information
1 parent
592cd96
commit c20297f
Showing
23 changed files
with
830 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* Copyright (c) 2022 vesoft inc. All rights reserved. | ||
* | ||
* This source code is licensed under Apache 2.0 License. | ||
*/ | ||
|
||
#include "common/base/CacheLibLRU.h" | ||
|
||
#include <folly/DynamicConverter.h> | ||
#include <folly/dynamic.h> | ||
|
||
namespace nebula { | ||
|
||
nebula::cpp2::ErrorCode CacheLibLRU::initializeCache() { | ||
VLOG(4) << "Using the following cache config" | ||
<< folly::toPrettyJson(folly::toDynamic(allocConfig_.serialize())); | ||
try { | ||
allocConfig_.validate(); // will throw if bad config | ||
nebulaCache_ = std::make_unique<Cache>(allocConfig_); | ||
} catch (const std::exception& e) { | ||
// We do not stop the service. Users should refer to the log to determine whether to restart | ||
// the service. | ||
LOG(ERROR) << "Cache configuration error: " << e.what(); | ||
return nebula::cpp2::ErrorCode::E_UNKNOWN; | ||
} | ||
|
||
return nebula::cpp2::ErrorCode::SUCCEEDED; | ||
} | ||
|
||
nebula::cpp2::ErrorCode CacheLibLRU::addPool(std::string poolName, uint32_t poolSize) { | ||
if (poolIdMap_.find(poolName) != poolIdMap_.end()) { | ||
LOG(ERROR) << "Cache pool creation error. Cache pool exists: " << poolName.data(); | ||
return nebula::cpp2::ErrorCode::E_EXISTED; | ||
} | ||
try { | ||
auto poolId = nebulaCache_->addPool(poolName, poolSize * 1024UL * 1024UL); | ||
poolIdMap_[poolName] = poolId; | ||
} catch (const std::exception& e) { | ||
LOG(ERROR) << "Adding cache pool error: " << e.what(); | ||
return nebula::cpp2::ErrorCode::E_NOT_ENOUGH_SPACE; | ||
} | ||
return nebula::cpp2::ErrorCode::SUCCEEDED; | ||
} | ||
|
||
nebula::cpp2::ErrorCode CacheLibLRU::get(const std::string& key, std::string* value) { | ||
folly::SharedMutex::ReadHolder rHolder(lock_); | ||
auto itemHandle = nebulaCache_->find(key); | ||
if (itemHandle) { | ||
value->assign(reinterpret_cast<const char*>(itemHandle->getMemory()), itemHandle->getSize()); | ||
return nebula::cpp2::ErrorCode::SUCCEEDED; | ||
} | ||
VLOG(4) << "Cache miss: " << key << " Not Found"; | ||
return nebula::cpp2::ErrorCode::E_CACHE_MISS; | ||
} | ||
|
||
Cache::ItemHandle CacheLibLRU::find(const std::string& key) { | ||
return nebulaCache_->find(key); | ||
} | ||
|
||
nebula::cpp2::ErrorCode CacheLibLRU::put(const std::string& key, | ||
const std::string& value, | ||
std::string poolName, | ||
uint32_t ttl) { | ||
if (poolIdMap_.find(poolName) == poolIdMap_.end()) { | ||
LOG(ERROR) << "Cache write error. Pool does not exist: " << poolName.data(); | ||
return nebula::cpp2::ErrorCode::E_POOL_NOT_FOUND; | ||
} | ||
auto itemHandle = nebulaCache_->allocate(poolIdMap_[poolName], key, value.size(), ttl); | ||
if (!itemHandle) { | ||
LOG(ERROR) << "Cache write error. Too many pending writes."; | ||
return nebula::cpp2::ErrorCode::E_CACHE_WRITE_FAILURE; | ||
} | ||
|
||
{ | ||
folly::SharedMutex::WriteHolder wHolder(lock_); | ||
std::memcpy(itemHandle->getMemory(), value.data(), value.size()); | ||
nebulaCache_->insertOrReplace(itemHandle); | ||
} | ||
return nebula::cpp2::ErrorCode::SUCCEEDED; | ||
} | ||
|
||
ErrorOr<nebula::cpp2::ErrorCode, Cache::ItemHandle> CacheLibLRU::allocateItem( | ||
const std::string& key, size_t size, std::string poolName, uint32_t ttl) { | ||
if (poolIdMap_.find(poolName) == poolIdMap_.end()) { | ||
LOG(ERROR) << "Cache write error. Pool does not exist: " << poolName; | ||
return nebula::cpp2::ErrorCode::E_POOL_NOT_FOUND; | ||
} | ||
auto itemHandle = nebulaCache_->allocate(poolIdMap_[poolName], key, size, ttl); | ||
if (!itemHandle) { | ||
LOG(ERROR) << "Cache write error. Too many pending writes."; | ||
return nebula::cpp2::ErrorCode::E_CACHE_WRITE_FAILURE; | ||
} | ||
return itemHandle; | ||
} | ||
|
||
Cache::ItemHandle CacheLibLRU::insertOrReplace(Cache::ItemHandle& handle) { | ||
return nebulaCache_->insertOrReplace(handle); | ||
} | ||
|
||
void CacheLibLRU::erase(const std::string& key) { | ||
nebulaCache_->remove(key); | ||
} | ||
|
||
nebula::cpp2::ErrorCode CacheLibLRU::invalidateItem(const std::string& key) { | ||
folly::SharedMutex::WriteHolder wHolder(lock_); | ||
VLOG(4) << "Invalidate vertex key: " << folly::hexlify(key); | ||
nebulaCache_->remove(key); | ||
return nebula::cpp2::ErrorCode::SUCCEEDED; | ||
} | ||
|
||
nebula::cpp2::ErrorCode CacheLibLRU::invalidateItems(const std::vector<std::string>& keys) { | ||
folly::SharedMutex::WriteHolder wHolder(lock_); | ||
for (auto key : keys) { | ||
VLOG(4) << "Invalidate vertex key: " << folly::hexlify(key); | ||
nebulaCache_->remove(key); | ||
} | ||
return nebula::cpp2::ErrorCode::SUCCEEDED; | ||
} | ||
|
||
ErrorOr<nebula::cpp2::ErrorCode, uint64_t> CacheLibLRU::getConfiguredPoolSize( | ||
const std::string& poolName) { | ||
if (poolIdMap_.find(poolName) == poolIdMap_.end()) { | ||
LOG(ERROR) << "Get cache pool size error. Pool does not exist: " << poolName.data(); | ||
return nebula::cpp2::ErrorCode::E_POOL_NOT_FOUND; | ||
} | ||
return nebulaCache_->getPoolStats(poolIdMap_[poolName]).poolSize; | ||
} | ||
|
||
ErrorOr<nebula::cpp2::ErrorCode, uint64_t> CacheLibLRU::getPoolCacheHitCount( | ||
const std::string& poolName) { | ||
if (poolIdMap_.find(poolName) == poolIdMap_.end()) { | ||
LOG(ERROR) << "Get cache hit count error. Pool does not exist: " << poolName.data(); | ||
return nebula::cpp2::ErrorCode::E_POOL_NOT_FOUND; | ||
} | ||
return nebulaCache_->getPoolStats(poolIdMap_[poolName]).numPoolGetHits; | ||
} | ||
|
||
} // namespace nebula |
Oops, something went wrong.