Optimizations: RocksDB perf optimizations
This commit is contained in:
parent
0215edb4bf
commit
39e1776a74
@ -36,6 +36,19 @@ KVStore::KVStore(std::filesystem::path storage) : pimpl_(std::make_unique<impl>(
|
||||
pimpl_->db.reset(db);
|
||||
}
|
||||
|
||||
KVStore::KVStore(std::filesystem::path storage, rocksdb::Options db_options) : pimpl_(std::make_unique<impl>()) {
|
||||
pimpl_->storage = storage;
|
||||
pimpl_->options = std::move(db_options);
|
||||
if (!utils::EnsureDir(pimpl_->storage))
|
||||
throw KVStoreError("Folder for the key-value store " + pimpl_->storage.string() + " couldn't be initialized!");
|
||||
rocksdb::DB *db = nullptr;
|
||||
auto s = rocksdb::DB::Open(pimpl_->options, storage.c_str(), &db);
|
||||
if (!s.ok())
|
||||
throw KVStoreError("RocksDB couldn't be initialized inside " + storage.string() + " -- " +
|
||||
std::string(s.ToString()));
|
||||
pimpl_->db.reset(db);
|
||||
}
|
||||
|
||||
KVStore::~KVStore() {
|
||||
if (pimpl_ == nullptr) return;
|
||||
spdlog::debug("Destroying KVStore at {}", pimpl_->storage.string());
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rocksdb/options.h>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@ -43,6 +44,7 @@ class KVStore final {
|
||||
* storage directory because that will lead to undefined behaviour.
|
||||
*/
|
||||
explicit KVStore(std::filesystem::path storage);
|
||||
explicit KVStore(std::filesystem::path storage, rocksdb::Options db_options);
|
||||
|
||||
KVStore(const KVStore &other) = delete;
|
||||
KVStore(KVStore &&other);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "storage/v2/durability/durability.hpp"
|
||||
#include "system/system.hpp"
|
||||
#include "telemetry/telemetry.hpp"
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
#include "utils/signals.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
#include "utils/system_info.hpp"
|
||||
@ -145,6 +146,8 @@ int main(int argc, char **argv) {
|
||||
// Unhandled exception handler init.
|
||||
std::set_terminate(&memgraph::utils::TerminateHandler);
|
||||
|
||||
memgraph::utils::OnScopeExit deinit_pds([]() { memgraph::storage::PDS::Deinit(); });
|
||||
|
||||
// Initialize Python
|
||||
auto *program_name = Py_DecodeLocale(argv[0], nullptr);
|
||||
MG_ASSERT(program_name);
|
||||
|
@ -52,6 +52,9 @@ struct Edge {
|
||||
bool deleted;
|
||||
// uint8_t PAD;
|
||||
// uint16_t PAD;
|
||||
|
||||
bool has_prop;
|
||||
|
||||
class HotFixMove {
|
||||
public:
|
||||
HotFixMove() {}
|
||||
@ -77,20 +80,19 @@ struct Edge {
|
||||
Gid HotFixForGID() const { return Gid::FromUint(gid.AsUint() + (1 << 31)); }
|
||||
|
||||
PropertyValue GetProperty(PropertyId property) const {
|
||||
if (deleted) return {};
|
||||
if (!has_prop) return {};
|
||||
const auto prop = PDS::get()->Get(HotFixForGID(), property);
|
||||
if (prop) return *prop;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool SetProperty(PropertyId property, const PropertyValue &value) {
|
||||
if (deleted) return {};
|
||||
if (!has_prop) return {};
|
||||
return PDS::get()->Set(HotFixForGID(), property, value);
|
||||
}
|
||||
|
||||
template <typename TContainer>
|
||||
bool InitProperties(const TContainer &properties) {
|
||||
if (deleted) return {};
|
||||
auto *pds = PDS::get();
|
||||
for (const auto &[property, value] : properties) {
|
||||
if (value.IsNull()) {
|
||||
@ -99,23 +101,26 @@ struct Edge {
|
||||
if (!pds->Set(HotFixForGID(), property, value)) {
|
||||
return false;
|
||||
}
|
||||
has_prop = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClearProperties() {
|
||||
if (!has_prop) return;
|
||||
has_prop = false;
|
||||
auto *pds = PDS::get();
|
||||
pds->Clear(HotFixForGID());
|
||||
}
|
||||
|
||||
std::map<PropertyId, PropertyValue> Properties() {
|
||||
if (deleted) return {};
|
||||
if (!has_prop) return {};
|
||||
return PDS::get()->Get(HotFixForGID());
|
||||
}
|
||||
|
||||
std::vector<std::tuple<PropertyId, PropertyValue, PropertyValue>> UpdateProperties(
|
||||
std::map<PropertyId, PropertyValue> &properties) {
|
||||
if (deleted) return {};
|
||||
if (!has_prop && properties.empty()) return {};
|
||||
auto old_properties = Properties();
|
||||
ClearProperties();
|
||||
|
||||
@ -140,7 +145,7 @@ struct Edge {
|
||||
}
|
||||
|
||||
uint64_t PropertySize(PropertyId property) const {
|
||||
if (deleted) return {};
|
||||
if (!has_prop) return {};
|
||||
return PDS::get()->GetSize(HotFixForGID(), property);
|
||||
}
|
||||
};
|
||||
|
@ -11,22 +11,32 @@
|
||||
|
||||
#include "storage/v2/property_disk_store.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "storage/v2/temporal.hpp"
|
||||
#include "utils/cast.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include <rocksdb/filter_policy.h>
|
||||
#include <rocksdb/memtablerep.h>
|
||||
#include <rocksdb/options.h>
|
||||
#include <rocksdb/slice_transform.h>
|
||||
#include <rocksdb/statistics.h>
|
||||
#include <rocksdb/table.h>
|
||||
|
||||
namespace memgraph::storage {
|
||||
|
||||
PDS *PDS::ptr_ = nullptr;
|
||||
|
||||
PDS::PDS(std::filesystem::path root)
|
||||
: kvstore_{root / "pds", std::invoke([]() {
|
||||
rocksdb::Options options;
|
||||
rocksdb::BlockBasedTableOptions table_options;
|
||||
table_options.block_cache = rocksdb::NewLRUCache(128 * 1024 * 1024);
|
||||
table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(sizeof(storage::Gid)));
|
||||
options.table_factory.reset(rocksdb::NewBlockBasedTableFactory(table_options));
|
||||
options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(sizeof(storage::Gid)));
|
||||
options.max_background_jobs = 4;
|
||||
options.enable_pipelined_write = true;
|
||||
options.avoid_unnecessary_blocking_io = true;
|
||||
|
||||
options.create_if_missing = true;
|
||||
|
||||
return options;
|
||||
})} {}
|
||||
|
||||
} // namespace memgraph::storage
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rocksdb/options.h>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <json/json.hpp>
|
||||
@ -34,6 +35,8 @@ class PDS {
|
||||
if (ptr_ == nullptr) ptr_ = new PDS(root);
|
||||
}
|
||||
|
||||
static void Deinit() { delete ptr_; }
|
||||
|
||||
static PDS *get() {
|
||||
if (ptr_ == nullptr) {
|
||||
ptr_ = new PDS("/tmp");
|
||||
@ -126,7 +129,7 @@ class PDS {
|
||||
// kvstore::KVStore::iterator Itr() {}
|
||||
|
||||
private:
|
||||
PDS(std::filesystem::path root) : kvstore_{root / "pds"} {}
|
||||
PDS(std::filesystem::path root);
|
||||
kvstore::KVStore kvstore_;
|
||||
static PDS *ptr_;
|
||||
};
|
||||
|
@ -130,6 +130,7 @@ struct Vertex {
|
||||
|
||||
void ClearProperties() {
|
||||
if (!has_prop) return;
|
||||
has_prop = false;
|
||||
auto *pds = PDS::get();
|
||||
pds->Clear(gid);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user