mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 09:00:51 +00:00
freeMemoryIfNeeded(): improve code and lazyfree handling.
1. Refactor memory overhead computation into a function. 2. Every 10 keys evicted, check if memory usage already reached the target value directly, since we otherwise don't count all the memory reclaimed by the background thread right now.
This commit is contained in:
parent
9b05aafb50
commit
cd90389b30
61
src/evict.c
61
src/evict.c
@ -336,11 +336,34 @@ unsigned long LFUDecrAndReturn(robj *o) {
|
|||||||
* server when there is data to add in order to make space if needed.
|
* server when there is data to add in order to make space if needed.
|
||||||
* --------------------------------------------------------------------------*/
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* We don't want to count AOF buffers and slaves output buffers as
|
||||||
|
* used memory: the eviction should use mostly data size. This function
|
||||||
|
* returns the sum of AOF and slaves buffer. */
|
||||||
|
size_t freeMemoryGetNotCountedMemory(void) {
|
||||||
|
size_t overhead = 0;
|
||||||
|
int slaves = listLength(server.slaves);
|
||||||
|
|
||||||
|
if (slaves) {
|
||||||
|
listIter li;
|
||||||
|
listNode *ln;
|
||||||
|
|
||||||
|
listRewind(server.slaves,&li);
|
||||||
|
while((ln = listNext(&li))) {
|
||||||
|
client *slave = listNodeValue(ln);
|
||||||
|
overhead += getClientOutputBufferMemoryUsage(slave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (server.aof_state != AOF_OFF) {
|
||||||
|
overhead += sdslen(server.aof_buf)+aofRewriteBufferSize();
|
||||||
|
}
|
||||||
|
return overhead;
|
||||||
|
}
|
||||||
|
|
||||||
int freeMemoryIfNeeded(void) {
|
int freeMemoryIfNeeded(void) {
|
||||||
size_t mem_reported, mem_used, mem_tofree, mem_freed;
|
size_t mem_reported, mem_used, mem_tofree, mem_freed;
|
||||||
int slaves = listLength(server.slaves);
|
|
||||||
mstime_t latency, eviction_latency;
|
mstime_t latency, eviction_latency;
|
||||||
long long delta;
|
long long delta;
|
||||||
|
int slaves = listLength(server.slaves);
|
||||||
|
|
||||||
/* 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. */
|
||||||
@ -350,24 +373,8 @@ int freeMemoryIfNeeded(void) {
|
|||||||
/* Remove the size of slaves output buffers and AOF buffer from the
|
/* Remove the size of slaves output buffers and AOF buffer from the
|
||||||
* count of used memory. */
|
* count of used memory. */
|
||||||
mem_used = mem_reported;
|
mem_used = mem_reported;
|
||||||
if (slaves) {
|
size_t overhead = freeMemoryGetNotCountedMemory();
|
||||||
listIter li;
|
mem_used = (mem_used > overhead) ? mem_used-overhead : 0;
|
||||||
listNode *ln;
|
|
||||||
|
|
||||||
listRewind(server.slaves,&li);
|
|
||||||
while((ln = listNext(&li))) {
|
|
||||||
client *slave = listNodeValue(ln);
|
|
||||||
unsigned long obuf_bytes = getClientOutputBufferMemoryUsage(slave);
|
|
||||||
if (obuf_bytes > mem_used)
|
|
||||||
mem_used = 0;
|
|
||||||
else
|
|
||||||
mem_used -= obuf_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (server.aof_state != AOF_OFF) {
|
|
||||||
mem_used -= sdslen(server.aof_buf);
|
|
||||||
mem_used -= aofRewriteBufferSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we are still over the memory limit. */
|
/* Check if we are still over the memory limit. */
|
||||||
if (mem_used <= server.maxmemory) return C_OK;
|
if (mem_used <= server.maxmemory) return C_OK;
|
||||||
@ -498,6 +505,22 @@ int freeMemoryIfNeeded(void) {
|
|||||||
* deliver data to the slaves fast enough, so we force the
|
* deliver data to the slaves fast enough, so we force the
|
||||||
* transmission here inside the loop. */
|
* transmission here inside the loop. */
|
||||||
if (slaves) flushSlavesOutputBuffers();
|
if (slaves) flushSlavesOutputBuffers();
|
||||||
|
|
||||||
|
/* Normally our stop condition is the ability to release
|
||||||
|
* a fixed, pre-computed amount of memory. However when we
|
||||||
|
* are deleting objects in another thread, it's better to
|
||||||
|
* check, from time to time, if we already reached our target
|
||||||
|
* memory, since the "mem_freed" amount is computed only
|
||||||
|
* across the dbAsyncDelete() call, while the thread can
|
||||||
|
* release the memory all the time. */
|
||||||
|
if (server.lazyfree_lazy_eviction && !(keys_freed % 16)) {
|
||||||
|
overhead = freeMemoryGetNotCountedMemory();
|
||||||
|
mem_used = zmalloc_used_memory();
|
||||||
|
mem_used = (mem_used > overhead) ? mem_used-overhead : 0;
|
||||||
|
if (mem_used <= server.maxmemory) {
|
||||||
|
mem_freed = mem_tofree;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keys_freed) {
|
if (!keys_freed) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user