From b177bc3b92d9519d38ff6e9e5a5638792945a7f4 Mon Sep 17 00:00:00 2001 From: hwware Date: Tue, 10 Jan 2023 20:52:05 +0000 Subject: [PATCH 1/4] add new parameter --- src/config.c | 15 +++++++++++++++ src/evict.c | 32 ++++++++++++++++++++++++++------ src/server.c | 11 +++++++++++ src/server.h | 2 ++ 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/config.c b/src/config.c index 9de4ecd41b6..2dfecc8d1f5 100644 --- a/src/config.c +++ b/src/config.c @@ -2463,6 +2463,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_reserved = (unsigned long long)server.maxmemory / 100.0 * server.maxmemory_reserved_scale; + return 1; +} + static int updateMaxmemory(const char **err) { UNUSED(err); if (server.maxmemory) { @@ -2470,6 +2483,7 @@ static int updateMaxmemory(const char **err) { if (server.maxmemory < used) { serverLog(LL_WARNING,"WARNING: the new maxmemory value set via CONFIG SET (%llu) is smaller than the current memory usage (%zu). This will result in key eviction and/or the inability to accept new write commands depending on the maxmemory-policy.", server.maxmemory, used); } + server.maxmemory_reserved = (unsigned long long)server.maxmemory / 100.0 * server.maxmemory_reserved_scale; startEvictionTimeProc(); } return 1; @@ -3124,6 +3138,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.slave_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, INT_MAX, 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 */ diff --git a/src/evict.c b/src/evict.c index 41712b926b1..92dfaec4b9a 100644 --- a/src/evict.c +++ b/src/evict.c @@ -407,7 +407,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_reserved && !level) return C_OK; + } else if (mem_reported <= server.maxmemory && !level) + return C_OK; /* Remove the size of slaves output buffers and AOF buffer from the * count of used memory. */ @@ -416,15 +420,27 @@ 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_reserved; + 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_reserved) 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_reserved) 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_reserved; + } else + mem_tofree = mem_used - server.maxmemory; if (logical) *logical = mem_used; if (tofree) *tofree = mem_tofree; @@ -547,7 +563,11 @@ int performEvictions(void) { long long delta; int slaves = listLength(server.slaves); int result = EVICT_FAIL; - + + serverLog(LL_WARNING,"-------------------------------------------------"); + serverLog(LL_WARNING,"Current maxmemory reserved scale is: %d",server.maxmemory_reserved_scale); + serverLog(LL_WARNING,"Current maxmemory reserved size is: %lld",server.maxmemory_reserved); + serverLog(LL_WARNING,"Current maxmemory is: %lld",server.maxmemory); if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL) == C_OK) { result = EVICT_OK; goto update_metrics; diff --git a/src/server.c b/src/server.c index 8b4ec28e497..973fce25616 100644 --- a/src/server.c +++ b/src/server.c @@ -2537,6 +2537,9 @@ void initServer(void) { server.reply_buffer_resizing_enabled = 1; server.client_mem_usage_buckets = NULL; resetReplicationBuffer(); + if (server.maxmemory && server.maxmemory_reserved_scale) { + server.maxmemory_reserved = (unsigned long long)server.maxmemory / 100.0 * 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) { @@ -5521,6 +5524,7 @@ sds genRedisInfoString(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_reserved_hmem[64]; size_t zmalloc_used = zmalloc_used_memory(); size_t total_system_mem = server.system_memory_size; const char *evict_policy = evictPolicyToString(); @@ -5543,6 +5547,7 @@ sds genRedisInfoString(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_reserved_hmem,sizeof(maxmemory_reserved_hmem),server.maxmemory_reserved); if (sections++) info = sdscat(info,"\r\n"); info = sdscatprintf(info, @@ -5579,6 +5584,9 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) { "maxmemory:%lld\r\n" "maxmemory_human:%s\r\n" "maxmemory_policy:%s\r\n" + "maxmemory_reserved_scale:%d\r\n" + "maxmemory_reserved:%lld\r\n" + "maxmemory_reserved_human:%s\r\n" "allocator_frag_ratio:%.2f\r\n" "allocator_frag_bytes:%zu\r\n" "allocator_rss_ratio:%.2f\r\n" @@ -5630,6 +5638,9 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) { server.maxmemory, maxmemory_hmem, evict_policy, + server.maxmemory_reserved_scale, + server.maxmemory_reserved, + maxmemory_reserved_hmem, mh->allocator_frag, mh->allocator_frag_bytes, mh->allocator_rss, diff --git a/src/server.h b/src/server.h index bf0a154593d..3b4471875e8 100644 --- a/src/server.h +++ b/src/server.h @@ -1830,6 +1830,8 @@ struct redisServer { 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_reserved; int maxmemory_eviction_tenacity;/* Aggressiveness of eviction processing */ int lfu_log_factor; /* LFU logarithmic counter factor. */ int lfu_decay_time; /* LFU counter decay factor. */ From c8971fa1fb35dc85e8c9a39b44b70c614a17138e Mon Sep 17 00:00:00 2001 From: hwware Date: Thu, 12 Jan 2023 15:50:08 +0000 Subject: [PATCH 2/4] update variable name to src/server.h --- redis.conf | 3 +++ src/config.c | 4 ++-- src/evict.c | 18 +++++++++--------- src/server.c | 14 +++++++------- src/server.h | 2 +- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/redis.conf b/redis.conf index 408d0c25800..6f1bed32dd3 100644 --- a/redis.conf +++ b/redis.conf @@ -1209,6 +1209,9 @@ acllog-max-len 128 # in the system. It's a tradeoff between memory, CPU and latency. # # active-expire-effort 1 +# +# maxmemory-reserved-scale 0 + ############################# LAZY FREEING #################################### diff --git a/src/config.c b/src/config.c index 2dfecc8d1f5..294517c8836 100644 --- a/src/config.c +++ b/src/config.c @@ -2472,7 +2472,7 @@ static int updateMaxmemoryReserved(const char **err){ server.maxmemory_reserved_scale = 60; } } - server.maxmemory_reserved = (unsigned long long)server.maxmemory / 100.0 * server.maxmemory_reserved_scale; + server.maxmemory_available= (unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale); return 1; } @@ -2483,7 +2483,7 @@ static int updateMaxmemory(const char **err) { if (server.maxmemory < used) { serverLog(LL_WARNING,"WARNING: the new maxmemory value set via CONFIG SET (%llu) is smaller than the current memory usage (%zu). This will result in key eviction and/or the inability to accept new write commands depending on the maxmemory-policy.", server.maxmemory, used); } - server.maxmemory_reserved = (unsigned long long)server.maxmemory / 100.0 * server.maxmemory_reserved_scale; + server.maxmemory_available= (unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale); startEvictionTimeProc(); } return 1; diff --git a/src/evict.c b/src/evict.c index 92dfaec4b9a..45a268ca1e6 100644 --- a/src/evict.c +++ b/src/evict.c @@ -409,7 +409,7 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev } if (server.maxmemory_reserved_scale) { - if (mem_reported <= server.maxmemory_reserved && !level) return C_OK; + if (mem_reported <= server.maxmemory_available && !level) return C_OK; } else if (mem_reported <= server.maxmemory && !level) return C_OK; @@ -422,23 +422,23 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev /* Compute the ratio of memory usage. */ if (level) { if (server.maxmemory_reserved_scale) - *level = (float)mem_used / (float)server.maxmemory_reserved; + *level = (float)mem_used / (float)server.maxmemory_available; else *level = (float)mem_used / (float)server.maxmemory; } if (server.maxmemory_reserved_scale) { - if (mem_reported <= server.maxmemory_reserved) return C_OK; + 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 (server.maxmemory_reserved_scale) { - if (mem_used <= server.maxmemory_reserved) return C_OK; + 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. */ if (server.maxmemory_reserved_scale) { - mem_tofree = mem_used - server.maxmemory_reserved; + mem_tofree = mem_used - server.maxmemory_available; } else mem_tofree = mem_used - server.maxmemory; @@ -564,10 +564,10 @@ int performEvictions(void) { int slaves = listLength(server.slaves); int result = EVICT_FAIL; - serverLog(LL_WARNING,"-------------------------------------------------"); - serverLog(LL_WARNING,"Current maxmemory reserved scale is: %d",server.maxmemory_reserved_scale); - serverLog(LL_WARNING,"Current maxmemory reserved size is: %lld",server.maxmemory_reserved); - serverLog(LL_WARNING,"Current maxmemory is: %lld",server.maxmemory); + //serverLog(LL_WARNING,"-------------------------------------------------"); + //serverLog(LL_WARNING,"Current maxmemory reserved scale is: %d",server.maxmemory_reserved_scale); + //serverLog(LL_WARNING,"Current maxmemory reserved size is: %lld",server.maxmemory_reserved); + //serverLog(LL_WARNING,"Current maxmemory is: %lld",server.maxmemory); if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL) == C_OK) { result = EVICT_OK; goto update_metrics; diff --git a/src/server.c b/src/server.c index 973fce25616..24640c9e6f7 100644 --- a/src/server.c +++ b/src/server.c @@ -2538,7 +2538,7 @@ void initServer(void) { server.client_mem_usage_buckets = NULL; resetReplicationBuffer(); if (server.maxmemory && server.maxmemory_reserved_scale) { - server.maxmemory_reserved = (unsigned long long)server.maxmemory / 100.0 * server.maxmemory_reserved_scale; + 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. */ @@ -5524,7 +5524,7 @@ sds genRedisInfoString(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_reserved_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(); @@ -5547,7 +5547,7 @@ sds genRedisInfoString(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_reserved_hmem,sizeof(maxmemory_reserved_hmem),server.maxmemory_reserved); + bytesToHuman(maxmemory_available_hmem,sizeof(maxmemory_available_hmem),server.maxmemory_available); if (sections++) info = sdscat(info,"\r\n"); info = sdscatprintf(info, @@ -5585,8 +5585,8 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) { "maxmemory_human:%s\r\n" "maxmemory_policy:%s\r\n" "maxmemory_reserved_scale:%d\r\n" - "maxmemory_reserved:%lld\r\n" - "maxmemory_reserved_human:%s\r\n" + "maxmemory_available:%lld\r\n" + "maxmemory_available_human:%s\r\n" "allocator_frag_ratio:%.2f\r\n" "allocator_frag_bytes:%zu\r\n" "allocator_rss_ratio:%.2f\r\n" @@ -5639,8 +5639,8 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) { maxmemory_hmem, evict_policy, server.maxmemory_reserved_scale, - server.maxmemory_reserved, - maxmemory_reserved_hmem, + server.maxmemory_available, + maxmemory_available_hmem, mh->allocator_frag, mh->allocator_frag_bytes, mh->allocator_rss, diff --git a/src/server.h b/src/server.h index 3b4471875e8..9d3bd9e1433 100644 --- a/src/server.h +++ b/src/server.h @@ -1831,7 +1831,7 @@ struct redisServer { int maxmemory_policy; /* Policy for key eviction */ int maxmemory_samples; /* Precision of random sampling */ int maxmemory_reserved_scale; - unsigned long long maxmemory_reserved; + 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. */ From 1139ea325d93b38df55a902309d356fc4d05c2ca Mon Sep 17 00:00:00 2001 From: hwware Date: Thu, 12 Jan 2023 19:47:03 +0000 Subject: [PATCH 3/4] update init condition --- src/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.c b/src/server.c index 24640c9e6f7..84a94289560 100644 --- a/src/server.c +++ b/src/server.c @@ -2537,7 +2537,7 @@ void initServer(void) { server.reply_buffer_resizing_enabled = 1; server.client_mem_usage_buckets = NULL; resetReplicationBuffer(); - if (server.maxmemory && server.maxmemory_reserved_scale) { + if (server.maxmemory) { server.maxmemory_available = (unsigned long long)server.maxmemory / 100.0 * (100 - server.maxmemory_reserved_scale); } From 8f83a6e0b6ac80b5f1efed6f7ad32f6cd9a4c4ed Mon Sep 17 00:00:00 2001 From: hwware Date: Tue, 24 Jan 2023 15:14:47 +0000 Subject: [PATCH 4/4] add comments in redis.conf --- redis.conf | 7 ++++++- src/config.c | 2 +- src/evict.c | 4 ---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/redis.conf b/redis.conf index 6f1bed32dd3..697b1848f94 100644 --- a/redis.conf +++ b/redis.conf @@ -1209,7 +1209,12 @@ acllog-max-len 128 # in the system. It's a tradeoff between memory, CPU and latency. # # active-expire-effort 1 -# +# +# It allows the redis to evict keys earlier. The value of this parameter represents +# percent of the maxmemory value. It means how much memory the redis 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 diff --git a/src/config.c b/src/config.c index 294517c8836..7aae22444d4 100644 --- a/src/config.c +++ b/src/config.c @@ -2463,7 +2463,7 @@ static int updateReplBacklogSize(const char **err) { return 1; } -static int updateMaxmemoryReserved(const char **err){ +static int updateMaxmemoryReserved(const char **err) { UNUSED(err); if (server.maxmemory_reserved_scale) { if (server.maxmemory_reserved_scale < 10) { diff --git a/src/evict.c b/src/evict.c index 45a268ca1e6..71209fb11be 100644 --- a/src/evict.c +++ b/src/evict.c @@ -564,10 +564,6 @@ int performEvictions(void) { int slaves = listLength(server.slaves); int result = EVICT_FAIL; - //serverLog(LL_WARNING,"-------------------------------------------------"); - //serverLog(LL_WARNING,"Current maxmemory reserved scale is: %d",server.maxmemory_reserved_scale); - //serverLog(LL_WARNING,"Current maxmemory reserved size is: %lld",server.maxmemory_reserved); - //serverLog(LL_WARNING,"Current maxmemory is: %lld",server.maxmemory); if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree,NULL) == C_OK) { result = EVICT_OK; goto update_metrics;