mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 09:00:51 +00:00
Modules: context flags now include OOM flag.
Plus freeMemoryIfNeeded() refactoring to improve legibility. Please review this commit for sanity.
This commit is contained in:
parent
6888c1a10d
commit
f97efe0cac
68
src/evict.c
68
src/evict.c
@ -369,25 +369,22 @@ size_t freeMemoryGetNotCountedMemory(void) {
|
|||||||
return overhead;
|
return overhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is periodically called to see if there is memory to free
|
/* Get the memory status from the point of view of the maxmemory directive:
|
||||||
* according to the current "maxmemory" settings. In case we are over the
|
* if the memory used is under the maxmemory setting then C_OK is returned
|
||||||
* memory limit, the function will try to free some memory to return back
|
* and the 'total', 'lgoical', and 'tofree' values are not populated at all.
|
||||||
* under the limit.
|
* Otherwise, if we are over the memory limit, the function returns
|
||||||
|
* C_ERR and populates (if not NULL) the arguments by reference with the
|
||||||
|
* following meaning:
|
||||||
*
|
*
|
||||||
* The function returns C_OK if we are under the memory limit or if we
|
* 'total' total amount of bytes used.
|
||||||
* were over the limit, but the attempt to free memory was successful.
|
*
|
||||||
* Otehrwise if we are over the memory limit, but not enough memory
|
* 'logical' the amount of memory used minus the slaves/AOF buffers.
|
||||||
* was freed to return back under the limit, the function returns C_ERR. */
|
*
|
||||||
int freeMemoryIfNeeded(void) {
|
* 'tofree' the amount of memory that should be released
|
||||||
size_t mem_reported, mem_used, mem_tofree, mem_freed;
|
* in order to return back into the memory limits.
|
||||||
mstime_t latency, eviction_latency;
|
*/
|
||||||
long long delta;
|
int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree) {
|
||||||
int slaves = listLength(server.slaves);
|
size_t mem_reported, mem_used, mem_tofree;
|
||||||
|
|
||||||
/* When clients are paused the dataset should be static not just from the
|
|
||||||
* POV of clients not being able to write, but also from the POV of
|
|
||||||
* expires and evictions of keys not being performed. */
|
|
||||||
if (clientsArePaused()) return C_OK;
|
|
||||||
|
|
||||||
/* Check if we are over the memory usage limit. If we are not, no need
|
/* Check if we are over the memory usage limit. If we are not, no need
|
||||||
* to subtract the slaves output buffers. We can just return ASAP. */
|
* to subtract the slaves output buffers. We can just return ASAP. */
|
||||||
@ -405,6 +402,35 @@ int freeMemoryIfNeeded(void) {
|
|||||||
|
|
||||||
/* Compute how much memory we need to free. */
|
/* Compute how much memory we need to free. */
|
||||||
mem_tofree = mem_used - server.maxmemory;
|
mem_tofree = mem_used - server.maxmemory;
|
||||||
|
|
||||||
|
if (*total) *total = mem_reported;
|
||||||
|
if (*logical) *logical = mem_used;
|
||||||
|
if (*tofree) *tofree = mem_tofree;
|
||||||
|
|
||||||
|
return C_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is periodically called to see if there is memory to free
|
||||||
|
* according to the current "maxmemory" settings. In case we are over the
|
||||||
|
* memory limit, the function will try to free some memory to return back
|
||||||
|
* under the limit.
|
||||||
|
*
|
||||||
|
* The function returns C_OK if we are under the memory limit or if we
|
||||||
|
* were over the limit, but the attempt to free memory was successful.
|
||||||
|
* Otehrwise if we are over the memory limit, but not enough memory
|
||||||
|
* was freed to return back under the limit, the function returns C_ERR. */
|
||||||
|
int freeMemoryIfNeeded(void) {
|
||||||
|
size_t mem_reported, mem_tofree, mem_freed;
|
||||||
|
mstime_t latency, eviction_latency;
|
||||||
|
long long delta;
|
||||||
|
int slaves = listLength(server.slaves);
|
||||||
|
|
||||||
|
/* When clients are paused the dataset should be static not just from the
|
||||||
|
* POV of clients not being able to write, but also from the POV of
|
||||||
|
* expires and evictions of keys not being performed. */
|
||||||
|
if (clientsArePaused()) return C_OK;
|
||||||
|
if (getMaxmemoryState(&mem_reported,NULL,&mem_tofree) == C_OK) return C_OK;
|
||||||
|
|
||||||
mem_freed = 0;
|
mem_freed = 0;
|
||||||
|
|
||||||
if (server.maxmemory_policy == MAXMEMORY_NO_EVICTION)
|
if (server.maxmemory_policy == MAXMEMORY_NO_EVICTION)
|
||||||
@ -538,10 +564,8 @@ int freeMemoryIfNeeded(void) {
|
|||||||
* across the dbAsyncDelete() call, while the thread can
|
* across the dbAsyncDelete() call, while the thread can
|
||||||
* release the memory all the time. */
|
* release the memory all the time. */
|
||||||
if (server.lazyfree_lazy_eviction && !(keys_freed % 16)) {
|
if (server.lazyfree_lazy_eviction && !(keys_freed % 16)) {
|
||||||
overhead = freeMemoryGetNotCountedMemory();
|
if (getMaxmemoryState(NULL,NULL,NULL) == C_OK) {
|
||||||
mem_used = zmalloc_used_memory();
|
/* Let's satisfy our stop condition. */
|
||||||
mem_used = (mem_used > overhead) ? mem_used-overhead : 0;
|
|
||||||
if (mem_used <= server.maxmemory) {
|
|
||||||
mem_freed = mem_tofree;
|
mem_freed = mem_tofree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1327,6 +1327,9 @@ int RM_GetSelectedDb(RedisModuleCtx *ctx) {
|
|||||||
*
|
*
|
||||||
* * REDISMODULE_CTX_FLAGS_EVICT: Maxmemory is set and has an eviction
|
* * REDISMODULE_CTX_FLAGS_EVICT: Maxmemory is set and has an eviction
|
||||||
* policy that may delete keys
|
* policy that may delete keys
|
||||||
|
*
|
||||||
|
* * REDISMODULE_CTX_FLAGS_OOM: Redis is out of memory according to the
|
||||||
|
* maxmemory setting.
|
||||||
*/
|
*/
|
||||||
int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
||||||
|
|
||||||
@ -1365,6 +1368,11 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
|||||||
flags |= REDISMODULE_CTX_FLAGS_READONLY;
|
flags |= REDISMODULE_CTX_FLAGS_READONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* OOM flag. */
|
||||||
|
if (getMaxmemoryState(NULL,NULL,NULL) == C_ERR) {
|
||||||
|
flags |= REDISMODULE_CTX_FLAGS_OOM;
|
||||||
|
}
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,29 +58,31 @@
|
|||||||
#define REDISMODULE_HASH_CFIELDS (1<<2)
|
#define REDISMODULE_HASH_CFIELDS (1<<2)
|
||||||
#define REDISMODULE_HASH_EXISTS (1<<3)
|
#define REDISMODULE_HASH_EXISTS (1<<3)
|
||||||
|
|
||||||
/* Context Flags: Info about the current context returned by RM_GetContextFlags */
|
/* Context Flags: Info about the current context returned by
|
||||||
|
* RM_GetContextFlags(). */
|
||||||
|
|
||||||
/* The command is running in the context of a Lua script */
|
/* The command is running in the context of a Lua script */
|
||||||
#define REDISMODULE_CTX_FLAGS_LUA 0x0001
|
#define REDISMODULE_CTX_FLAGS_LUA (1<<0)
|
||||||
/* The command is running inside a Redis transaction */
|
/* The command is running inside a Redis transaction */
|
||||||
#define REDISMODULE_CTX_FLAGS_MULTI 0x0002
|
#define REDISMODULE_CTX_FLAGS_MULTI (1<<1)
|
||||||
/* The instance is a master */
|
/* The instance is a master */
|
||||||
#define REDISMODULE_CTX_FLAGS_MASTER 0x0004
|
#define REDISMODULE_CTX_FLAGS_MASTER (1<<2)
|
||||||
/* The instance is a slave */
|
/* The instance is a slave */
|
||||||
#define REDISMODULE_CTX_FLAGS_SLAVE 0x0008
|
#define REDISMODULE_CTX_FLAGS_SLAVE (1<<3)
|
||||||
/* The instance is read-only (usually meaning it's a slave as well) */
|
/* The instance is read-only (usually meaning it's a slave as well) */
|
||||||
#define REDISMODULE_CTX_FLAGS_READONLY 0x0010
|
#define REDISMODULE_CTX_FLAGS_READONLY (1<<4)
|
||||||
/* The instance is running in cluster mode */
|
/* The instance is running in cluster mode */
|
||||||
#define REDISMODULE_CTX_FLAGS_CLUSTER 0x0020
|
#define REDISMODULE_CTX_FLAGS_CLUSTER (1<<5)
|
||||||
/* The instance has AOF enabled */
|
/* The instance has AOF enabled */
|
||||||
#define REDISMODULE_CTX_FLAGS_AOF 0x0040 //
|
#define REDISMODULE_CTX_FLAGS_AOF (1<<6)
|
||||||
/* The instance has RDB enabled */
|
/* The instance has RDB enabled */
|
||||||
#define REDISMODULE_CTX_FLAGS_RDB 0x0080 //
|
#define REDISMODULE_CTX_FLAGS_RDB (1<<7)
|
||||||
/* The instance has Maxmemory set */
|
/* The instance has Maxmemory set */
|
||||||
#define REDISMODULE_CTX_FLAGS_MAXMEMORY 0x0100
|
#define REDISMODULE_CTX_FLAGS_MAXMEMORY (1<<8)
|
||||||
/* Maxmemory is set and has an eviction policy that may delete keys */
|
/* Maxmemory is set and has an eviction policy that may delete keys */
|
||||||
#define REDISMODULE_CTX_FLAGS_EVICT 0x0200
|
#define REDISMODULE_CTX_FLAGS_EVICT (1<<9)
|
||||||
|
/* Redis is out of memory according to the maxmemory flag. */
|
||||||
|
#define REDISMODULE_CTX_FLAGS_OOM (1<<10)
|
||||||
|
|
||||||
#define REDISMODULE_NOTIFY_GENERIC (1<<2) /* g */
|
#define REDISMODULE_NOTIFY_GENERIC (1<<2) /* g */
|
||||||
#define REDISMODULE_NOTIFY_STRING (1<<3) /* $ */
|
#define REDISMODULE_NOTIFY_STRING (1<<3) /* $ */
|
||||||
|
@ -1643,6 +1643,7 @@ int zslLexValueGteMin(sds value, zlexrangespec *spec);
|
|||||||
int zslLexValueLteMax(sds value, zlexrangespec *spec);
|
int zslLexValueLteMax(sds value, zlexrangespec *spec);
|
||||||
|
|
||||||
/* Core functions */
|
/* Core functions */
|
||||||
|
int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree);
|
||||||
int freeMemoryIfNeeded(void);
|
int freeMemoryIfNeeded(void);
|
||||||
int processCommand(client *c);
|
int processCommand(client *c);
|
||||||
void setupSignalHandlers(void);
|
void setupSignalHandlers(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user