Skip to content

Commit

Permalink
Update to maxmemory_soft_scale
Browse files Browse the repository at this point in the history
  • Loading branch information
hwware committed Nov 3, 2024
1 parent fe7fcd1 commit 01fd9d2
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 37 deletions.
22 changes: 11 additions & 11 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -2509,18 +2509,18 @@ static int updateReplBacklogSize(const char **err) {
return 1;
}

/* Adjusts `maxmemory_reserved_scale` to ensure it remains within the valid range of 10 to 60, if set.
* Once adjusted, the available memory is recalculated to reflect the new reserved memory. */
static int updateMaxmemoryReserved(const char **err) {
/* Adjusts `maxmemory_soft_scale` to ensure it remains within the valid range of 10 to 60, if set.
* Once adjusted, the available memory is recalculated to reflect the new soft maxmemory. */
static int updateMaxmemorySoftScale(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;
if (server.maxmemory_soft_scale) {
if (server.maxmemory_soft_scale < 10) {
server.maxmemory_soft_scale = 10;
} else if (server.maxmemory_soft_scale > 60) {
server.maxmemory_soft_scale = 60;
}
}
updateMaxAvailableMemory();
updateSoftMaxmemoryValue();
return 1;
}

Expand All @@ -2535,7 +2535,7 @@ static int updateMaxmemory(const char **err) {
"depending on the maxmemory-policy.",
server.maxmemory, used);
}
updateMaxAvailableMemory();
updateSoftMaxmemoryValue();
startEvictionTimeProc();
}
return 1;
Expand Down Expand Up @@ -3235,7 +3235,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-soft-scale", NULL, MODIFIABLE_CONFIG, 0, 100, server.maxmemory_soft_scale, 0, INTEGER_CONFIG, NULL, updateMaxmemorySoftScale),
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
13 changes: 6 additions & 7 deletions src/evict.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,12 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev
if (total) *total = mem_reported;

/* We may return ASAP if there is no need to compute the level. */
if (!server.maxmemory_available) {
if (!server.maxmemory_soft) {
if (level) *level = 0;
return C_OK;
}

if (mem_reported <= server.maxmemory_available && !level) return C_OK;
if (mem_reported <= server.maxmemory_soft && !level) return C_OK;

/* Remove the size of replicas output buffers and AOF buffer from the
* count of used memory. */
Expand All @@ -416,13 +416,13 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev
*level = (float)mem_used / (float)server.maxmemory;
}

if (mem_reported <= server.maxmemory_available) return C_OK;
if (mem_reported <= server.maxmemory_soft) return C_OK;

/* Check if we are still over the memory limit. */
if (mem_used <= server.maxmemory_available) return C_OK;
if (mem_used <= server.maxmemory_soft) return C_OK;

/* Compute how much memory we need to free. */
mem_tofree = mem_used - server.maxmemory_available;
mem_tofree = mem_used - server.maxmemory_soft;

if (logical) *logical = mem_used;
if (tofree) *tofree = mem_tofree;
Expand Down Expand Up @@ -729,7 +729,7 @@ int performEvictions(void) {
}
}
/* at this point, the memory is OK, or we have reached the time limit */
if (server.maxmemory_reserved_scale && server.maxmemory_available) {
if (server.maxmemory_soft_scale) {
size_t mem_used = zmalloc_used_memory();
size_t overhead = freeMemoryGetNotCountedMemory();
mem_used = (mem_used > overhead) ? mem_used - overhead : 0;
Expand All @@ -740,7 +740,6 @@ int performEvictions(void) {
}
result = (isEvictionProcRunning) ? EVICT_RUNNING : EVICT_OK;


cant_free:
if (result == EVICT_FAIL) {
/* At this point, we have run out of evictable items. It's possible
Expand Down
12 changes: 6 additions & 6 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2712,7 +2712,7 @@ void initServer(void) {
resetReplicationBuffer();

if (server.maxmemory) {
updateMaxAvailableMemory();
updateSoftMaxmemoryValue();
}

/* Make sure the locale is set on startup based on the config file. */
Expand Down Expand Up @@ -5625,7 +5625,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];
char maxmemory_soft_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 @@ -5647,7 +5647,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);
bytesToHuman(maxmemory_soft_hmem, sizeof(maxmemory_soft_hmem), server.maxmemory_soft);

if (sections++) info = sdscat(info, "\r\n");
info = sdscatprintf(
Expand Down Expand Up @@ -5686,9 +5686,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,
"maxmemory_soft_scale:%d\r\n", server.maxmemory_soft_scale,
"maxmemory_soft:%lld\r\n", server.maxmemory_soft,
"maxmemory_soft_human:%s\r\n", maxmemory_soft_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
8 changes: 4 additions & 4 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -2097,8 +2097,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; /* Percent of the maxmemory value */
unsigned long long maxmemory_available; /* Max memory to store data */
int maxmemory_soft_scale; /* Percent of the soft maxmemory value */
unsigned long long maxmemory_soft; /* Soft maxmemory value to store data */
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 Expand Up @@ -3033,8 +3033,8 @@ void trimStringObjectIfNeeded(robj *o, int trim_small_values);
static inline int canUseSharedObject(void) {
return server.maxmemory == 0 || !(server.maxmemory_policy & MAXMEMORY_FLAG_NO_SHARED_INTEGERS);
}
static inline void updateMaxAvailableMemory(void) {
server.maxmemory_available = (unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale);
static inline void updateSoftMaxmemoryValue(void) {
server.maxmemory_soft = (unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_soft_scale);
}
#define sdsEncodedObject(objptr) (objptr->encoding == OBJ_ENCODING_RAW || objptr->encoding == OBJ_ENCODING_EMBSTR)

Expand Down
4 changes: 2 additions & 2 deletions tests/unit/maxmemory.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,13 @@ start_server {tags {"maxmemory" "external:skip"}} {

start_server {tags {"maxmemory external:skip"}} {

test "maxmemory-reserved-scale" {
test "maxmemory-soft-scale" {
r flushdb
r config set maxmemory 10mb
set current_dbsize 0

foreach scale_value {30 10 0} {
r config set maxmemory-reserved-scale $scale_value
r config set maxmemory-soft-scale $scale_value
# fill 20mb using 200 keys of 100kb
catch { for {set j 0} {$j < 200} {incr j} {
r setrange $j 100000 x
Expand Down
14 changes: 7 additions & 7 deletions valkey.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,13 @@ acllog-max-len 128
#
# maxmemory-policy noeviction

# `maxmemory-soft-scale` defines a "soft" maxmemory threshold as a scale of the `maxmemory` limit.
# When memory usage exceeds this scale, Valkey begins proactive key eviction. However, exceeding this
# threshold does not immediately reject new write commands; only the hard `maxmemory` limit will do so.
# This scale is specified as a percentage of `maxmemory`, with a valid range between 10 and 60.
#
# maxmemory-soft-scale 0

# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can tune it for speed or
# accuracy. By default the server will check five keys and pick the one that was
Expand Down Expand Up @@ -1248,13 +1255,6 @@ acllog-max-len 128
# in the system. It's a tradeoff between memory, CPU and latency.
#
# active-expire-effort 1
#
# This parameter allows Valkey to evict keys earlier. The value represents
# a percentage of the maxmemory limit, indicating how much memory the Valkey instance reserves
# without storing data.
# The default is 0, and the value can be set between 10 and 60.
#
# maxmemory-reserved-scale 0

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

Expand Down

0 comments on commit 01fd9d2

Please sign in to comment.