Skip to content

Commit

Permalink
Add maxmemory-reserved-scale parameter for evicting key earlier
Browse files Browse the repository at this point in the history
Signed-off-by: hwware <[email protected]>
  • Loading branch information
hwware committed Sep 9, 2024
1 parent 20d583f commit 8bf5d6c
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 5 deletions.
16 changes: 16 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -2471,6 +2471,19 @@ static int updateReplBacklogSize(const char **err) {
return 1;
}

static int updateMaxmemoryReserved(const char **err) {
UNUSED(err);
if (server.maxmemory_reserved_scale) {
if (server.maxmemory_reserved_scale < 10) {
server.maxmemory_reserved_scale = 10;
} else if (server.maxmemory_reserved_scale > 60) {
server.maxmemory_reserved_scale = 60;
}
}
server.maxmemory_available = (unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale);
return 1;
}

static int updateMaxmemory(const char **err) {
UNUSED(err);
if (server.maxmemory) {
Expand All @@ -2482,6 +2495,8 @@ static int updateMaxmemory(const char **err) {
"depending on the maxmemory-policy.",
server.maxmemory, used);
}
server.maxmemory_available =
(unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale);
startEvictionTimeProc();
}
return 1;
Expand Down Expand Up @@ -3181,6 +3196,7 @@ standardConfig static_configs[] = {
createIntConfig("lfu-decay-time", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.lfu_decay_time, 1, INTEGER_CONFIG, NULL, NULL),
createIntConfig("replica-priority", "slave-priority", MODIFIABLE_CONFIG, 0, INT_MAX, server.replica_priority, 100, INTEGER_CONFIG, NULL, NULL),
createIntConfig("repl-diskless-sync-delay", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.repl_diskless_sync_delay, 5, INTEGER_CONFIG, NULL, NULL),
createIntConfig("maxmemory-reserved-scale", NULL, MODIFIABLE_CONFIG, 0, 100, server.maxmemory_reserved_scale, 0, INTEGER_CONFIG, NULL, updateMaxmemoryReserved),
createIntConfig("maxmemory-samples", NULL, MODIFIABLE_CONFIG, 1, 64, server.maxmemory_samples, 5, INTEGER_CONFIG, NULL, NULL),
createIntConfig("maxmemory-eviction-tenacity", NULL, MODIFIABLE_CONFIG, 0, 100, server.maxmemory_eviction_tenacity, 10, INTEGER_CONFIG, NULL, NULL),
createIntConfig("timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.maxidletime, 0, INTEGER_CONFIG, NULL, NULL), /* Default client timeout: infinite */
Expand Down
28 changes: 23 additions & 5 deletions src/evict.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,11 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev
if (level) *level = 0;
return C_OK;
}
if (mem_reported <= server.maxmemory && !level) return C_OK;

if (server.maxmemory_reserved_scale) {
if (mem_reported <= server.maxmemory_available && !level) return C_OK;
} else if (mem_reported <= server.maxmemory && !level)
return C_OK;

/* Remove the size of replicas output buffers and AOF buffer from the
* count of used memory. */
Expand All @@ -411,15 +415,29 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev
mem_used = (mem_used > overhead) ? mem_used - overhead : 0;

/* Compute the ratio of memory usage. */
if (level) *level = (float)mem_used / (float)server.maxmemory;
if (level) {
if (server.maxmemory_reserved_scale)
*level = (float)mem_used / (float)server.maxmemory_available;
else
*level = (float)mem_used / (float)server.maxmemory;
}

if (mem_reported <= server.maxmemory) return C_OK;
if (server.maxmemory_reserved_scale) {
if (mem_reported <= server.maxmemory_available) return C_OK;
} else if (mem_reported <= server.maxmemory)
return C_OK;

/* Check if we are still over the memory limit. */
if (mem_used <= server.maxmemory) return C_OK;
if (server.maxmemory_reserved_scale) {
if (mem_used <= server.maxmemory_available) return C_OK;
} else if (mem_used <= server.maxmemory)
return C_OK;

/* Compute how much memory we need to free. */
mem_tofree = mem_used - server.maxmemory;
if (server.maxmemory_reserved_scale) {
mem_tofree = mem_used - server.maxmemory_available;
} else
mem_tofree = mem_used - server.maxmemory;

if (logical) *logical = mem_used;
if (tofree) *tofree = mem_tofree;
Expand Down
10 changes: 10 additions & 0 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2621,6 +2621,11 @@ void initServer(void) {
server.client_mem_usage_buckets = NULL;
resetReplicationBuffer();

if (server.maxmemory) {
server.maxmemory_available =
(unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale);
}

/* Make sure the locale is set on startup based on the config file. */
if (setlocale(LC_COLLATE, server.locale_collate) == NULL) {
serverLog(LL_WARNING, "Failed to configure LOCALE for invalid locale name.");
Expand Down Expand Up @@ -5517,6 +5522,7 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
char used_memory_scripts_hmem[64];
char used_memory_rss_hmem[64];
char maxmemory_hmem[64];
char maxmemory_available_hmem[64];
size_t zmalloc_used = zmalloc_used_memory();
size_t total_system_mem = server.system_memory_size;
const char *evict_policy = evictPolicyToString();
Expand All @@ -5538,6 +5544,7 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
bytesToHuman(used_memory_scripts_hmem, sizeof(used_memory_scripts_hmem), mh->lua_caches + mh->functions_caches);
bytesToHuman(used_memory_rss_hmem, sizeof(used_memory_rss_hmem), server.cron_malloc_stats.process_rss);
bytesToHuman(maxmemory_hmem, sizeof(maxmemory_hmem), server.maxmemory);
bytesToHuman(maxmemory_available_hmem, sizeof(maxmemory_available_hmem), server.maxmemory_available);

if (sections++) info = sdscat(info, "\r\n");
/* clang-format off */
Expand Down Expand Up @@ -5575,6 +5582,9 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
"maxmemory:%lld\r\n", server.maxmemory,
"maxmemory_human:%s\r\n", maxmemory_hmem,
"maxmemory_policy:%s\r\n", evict_policy,
"maxmemory_reserved_scale:%d\r\n",server.maxmemory_reserved_scale,
"maxmemory_available:%lld\r\n",server.maxmemory_available,
"maxmemory_available_human:%s\r\n",maxmemory_available_hmem,
"allocator_frag_ratio:%.2f\r\n", mh->allocator_frag,
"allocator_frag_bytes:%zu\r\n", mh->allocator_frag_bytes,
"allocator_rss_ratio:%.2f\r\n", mh->allocator_rss,
Expand Down
2 changes: 2 additions & 0 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,8 @@ struct valkeyServer {
ssize_t maxmemory_clients; /* Memory limit for total client buffers */
int maxmemory_policy; /* Policy for key eviction */
int maxmemory_samples; /* Precision of random sampling */
int maxmemory_reserved_scale;
unsigned long long maxmemory_available;
int maxmemory_eviction_tenacity; /* Aggressiveness of eviction processing */
int lfu_log_factor; /* LFU logarithmic counter factor. */
int lfu_decay_time; /* LFU counter decay factor. */
Expand Down
7 changes: 7 additions & 0 deletions valkey.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,13 @@ acllog-max-len 128
# in the system. It's a tradeoff between memory, CPU and latency.
#
# active-expire-effort 1
#
# It allows the valkey to evict keys earlier. The value of this parameter represents
# percent of the maxmemory value. It means how much memory the valkey instance want to hold
# not to store the data.
# Default is 0, and the value could be set between 10 to 60.
#
# maxmemory-reserved-scale 0

############################# LAZY FREEING ####################################

Expand Down

0 comments on commit 8bf5d6c

Please sign in to comment.