1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-14 11:58:02 +00:00

fix: maxmemory flag support human-readable format (#476)

Signed-off-by: Leonardo Mello <lsvmello@gmail.com>
This commit is contained in:
Leonardo Mello 2022-11-10 14:59:58 -03:00 committed by GitHub
parent 97057cadcf
commit ac5bc59c34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 18 deletions

View file

@ -111,7 +111,7 @@ Dragonfly currently supports the following Redis-specific arguments:
* `port` redis connection port, default: 6379
* `bind` localhost to only allow locahost connections, Public IP ADDRESS , to allow connections **to that ip** address (aka from outside too)
* `requirepass` password for AUTH authentication, default: ""
* `maxmemory` Limit on maximum-memory (in bytes) that is used by the database.0 - means the program will automatically determine its maximum memory usage. default: 0
* `maxmemory` Limit on maximum-memory (in human-readble bytes) that is used by the database. 0 - means the program will automatically determine its maximum memory usage. default: 0
* `dir` - by default, dragonfly docker uses `/data` folder for snapshotting. the CLI uses: ""
You can use `-v` docker option to map it to your host folder.
* `dbfilename` the filename to save/load the DB. default: "dump";

View file

@ -123,26 +123,29 @@ bool ParseHumanReadableBytes(std::string_view str, int64_t* num_bytes) {
char* end;
double d = strtod(cstr, &end);
// If this didn't consume the entire string, fail.
if (end + 1 < str.end())
return false;
int64 scale = 1;
switch (*end) {
// Considers just the first character after the number
// so it matches: 1G, 1GB, 1GiB and 1Gigabytes
// NB: an int64 can only go up to <8 EB.
case 'E':
case 'e':
scale <<= 10; // Fall through...
ABSL_FALLTHROUGH_INTENDED;
case 'P':
case 'p':
scale <<= 10;
ABSL_FALLTHROUGH_INTENDED;
case 'T':
case 't':
scale <<= 10;
ABSL_FALLTHROUGH_INTENDED;
case 'G':
case 'g':
scale <<= 10;
ABSL_FALLTHROUGH_INTENDED;
case 'M':
case 'm':
scale <<= 10;
ABSL_FALLTHROUGH_INTENDED;
case 'K':
@ -150,6 +153,7 @@ bool ParseHumanReadableBytes(std::string_view str, int64_t* num_bytes) {
scale <<= 10;
ABSL_FALLTHROUGH_INTENDED;
case 'B':
case 'b':
case '\0':
break; // To here.
default:

View file

@ -22,6 +22,7 @@
#include "io/file.h"
#include "io/file_util.h"
#include "io/proc_reader.h"
#include "server/common.h"
#include "server/main_service.h"
#include "server/version.h"
#include "strings/human_readable.h"
@ -39,10 +40,32 @@
using namespace std;
struct MaxMemoryFlag {
MaxMemoryFlag() = default;
MaxMemoryFlag(const MaxMemoryFlag&) = default;
MaxMemoryFlag& operator=(const MaxMemoryFlag&) = default;
MaxMemoryFlag(int64_t v) : value(v) {
} // NOLINT
int64_t value;
};
bool AbslParseFlag(absl::string_view in, MaxMemoryFlag* flag, std::string* err) {
if (dfly::ParseHumanReadableBytes(in, &flag->value)) {
return true;
}
*err = "Use human-readable format, eg.: 1G, 1GB, 10GB";
return false;
}
std::string AbslUnparseFlag(const MaxMemoryFlag& flag) {
return strings::HumanReadableNumBytes(flag.value);
}
ABSL_DECLARE_FLAG(uint32_t, port);
ABSL_DECLARE_FLAG(uint32_t, dbnum);
ABSL_DECLARE_FLAG(uint32_t, memcache_port);
ABSL_DECLARE_FLAG(uint64_t, maxmemory);
ABSL_FLAG(bool, use_large_pages, false, "If true - uses large memory pages for allocations");
ABSL_FLAG(string, bind, "",
@ -52,10 +75,13 @@ ABSL_FLAG(string, pidfile, "", "If not empty - server writes its pid into the fi
ABSL_FLAG(string, unixsocket, "",
"If not empty - specifies path for the Unis socket that will "
"be used for listening for incoming connections.");
ABSL_FLAG(bool, force_epoll, false,
"If true - uses linux epoll engine underneath."
"Can fit for kernels older than 5.10.");
ABSL_FLAG(MaxMemoryFlag, maxmemory, MaxMemoryFlag(0),
"Limit on maximum-memory that is used by the database. "
"0 - means the program will automatically determine its maximum memory usage. "
"default: 0");
using namespace util;
using namespace facade;
@ -121,10 +147,10 @@ string NormalizePaths(std::string_view path) {
}
bool RunEngine(ProactorPool* pool, AcceptServer* acceptor) {
auto maxmemory = GetFlag(FLAGS_maxmemory);
if (maxmemory > 0 && maxmemory < pool->size() * 256_MB) {
LOG(ERROR) << "Max memory is less than 256MB per thread. Exiting...";
auto maxmemory = GetFlag(FLAGS_maxmemory).value;
if (maxmemory > 0 && (unsigned)maxmemory < pool->size() * 256_MB) {
LOG(ERROR) << "There are " << pool->size() << " threads, so "
<< HumanReadableNumBytes(pool->size() * 256_MB) << " are required. Exiting...";
return false;
}
@ -290,7 +316,7 @@ Usage: dragonfly [FLAGS]
}
}
if (GetFlag(FLAGS_maxmemory) == 0) {
if (GetFlag(FLAGS_maxmemory).value == 0) {
LOG(INFO) << "maxmemory has not been specified. Deciding myself....";
Result<MemInfoData> res = ReadMemInfo();
@ -298,12 +324,12 @@ Usage: dragonfly [FLAGS]
size_t maxmemory = size_t(0.8 * available);
LOG(INFO) << "Found " << HumanReadableNumBytes(available)
<< " available memory. Setting maxmemory to " << HumanReadableNumBytes(maxmemory);
absl::SetFlag(&FLAGS_maxmemory, maxmemory);
absl::SetFlag(&FLAGS_maxmemory, MaxMemoryFlag(maxmemory));
} else {
LOG(INFO) << "Max memory limit is: " << HumanReadableNumBytes(GetFlag(FLAGS_maxmemory));
LOG(INFO) << "Max memory limit is: " << HumanReadableNumBytes(GetFlag(FLAGS_maxmemory).value);
}
dfly::max_memory_limit = GetFlag(FLAGS_maxmemory);
dfly::max_memory_limit = GetFlag(FLAGS_maxmemory).value;
if (GetFlag(FLAGS_use_large_pages)) {
mi_option_enable(mi_option_large_os_pages);

View file

@ -42,9 +42,6 @@ using namespace std;
ABSL_FLAG(uint32_t, port, 6379, "Redis port");
ABSL_FLAG(uint32_t, memcache_port, 0, "Memcached port");
ABSL_FLAG(uint64_t, maxmemory, 0,
"Limit on maximum-memory that is used by the database."
"0 - means the program will automatically determine its maximum memory usage");
ABSL_DECLARE_FLAG(string, requirepass);