Skip to content

Instantly share code, notes, and snippets.

@antirez
Created February 21, 2017 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antirez/509c434be87e022bd5a063be83e8a77b to your computer and use it in GitHub Desktop.
Save antirez/509c434be87e022bd5a063be83e8a77b to your computer and use it in GitHub Desktop.
diff --git a/src/evict.c b/src/evict.c
index 802997c..24fb283 100644
--- a/src/evict.c
+++ b/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.
* --------------------------------------------------------------------------*/
+/* 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) {
size_t mem_reported, mem_used, mem_tofree, mem_freed;
- int slaves = listLength(server.slaves);
mstime_t latency, eviction_latency;
long long delta;
+ int slaves = listLength(server.slaves);
/* 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. */
@@ -350,23 +373,11 @@ int freeMemoryIfNeeded(void) {
/* Remove the size of slaves output buffers and AOF buffer from the
* count of used memory. */
mem_used = mem_reported;
- if (slaves) {
- listIter li;
- 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();
+ size_t overhead = freeMemoryGetNotCountedMemory();
+ if (mem_used > overhead) {
+ mem_used -= overhead;
+ } else {
+ mem_used = 0;
}
/* Check if we are still over the memory limit. */
@@ -498,6 +509,26 @@ int freeMemoryIfNeeded(void) {
* deliver data to the slaves fast enough, so we force the
* transmission here inside the loop. */
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 % 10)) {
+ overhead = freeMemoryGetNotCountedMemory();
+ mem_used = zmalloc_used_memory()-overhead;
+ if (mem_used > overhead) {
+ mem_used -= overhead;
+ } else {
+ mem_used = 0;
+ }
+ if (mem_used <= server.maxmemory) {
+ mem_freed = mem_tofree;
+ }
+ }
}
if (!keys_freed) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment