]> git.saurik.com Git - redis.git/commitdiff
More incremental active expired keys collection process.
authorantirez <antirez@gmail.com>
Fri, 11 May 2012 17:17:31 +0000 (19:17 +0200)
committerantirez <antirez@gmail.com>
Fri, 11 May 2012 17:17:31 +0000 (19:17 +0200)
If a large amonut of keys are all expiring about at the same time, the
"active" expired keys collection cycle used to block as far as the
percentage of already expired keys was >= 25% of the total population of
keys with an expire set.

This could block the server even for many seconds in order to reclaim
memory ASAP. The new algorithm uses at max a small amount of
milliseconds per cycle, even if this means reclaiming the memory less
promptly it also means a more responsive server.

src/redis.c
src/redis.h

index d4d91f176f6d833f8771b32368388d60776526a9..77c26b97ef033a5841d0423713d9a9ab340bd01f 100644 (file)
@@ -622,9 +622,10 @@ void updateDictResizePolicy(void) {
  * keys that can be removed from the keyspace. */
 void activeExpireCycle(void) {
     int j;
+    long long start = mstime();
 
     for (j = 0; j < server.dbnum; j++) {
-        int expired;
+        int expired, iteration = 0;
         redisDb *db = server.db+j;
 
         /* Continue to expire if at the end of the cycle more than 25%
@@ -653,6 +654,12 @@ void activeExpireCycle(void) {
                     server.stat_expiredkeys++;
                 }
             }
+            /* We can't block forever here even if there are many keys to
+             * expire. So after a given amount of milliseconds return to the
+             * caller waiting for the other active expire cycle. */
+            iteration++;
+            if ((iteration & 0xff) == 0 &&  /* & 0xff is the same as % 255 */
+                (mstime()-start) > REDIS_EXPIRELOOKUPS_TIME_LIMIT) return;
         } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4);
     }
 }
index 2b54c709d60bead3dcadf5141b6609f640c5e2a0..8ac842479d9c835291f9ec48026a84cb701ed5c6 100644 (file)
@@ -43,6 +43,7 @@
 #define REDIS_DEFAULT_DBNUM     16
 #define REDIS_CONFIGLINE_MAX    1024
 #define REDIS_EXPIRELOOKUPS_PER_CRON    10 /* lookup 10 expires per loop */
+#define REDIS_EXPIRELOOKUPS_TIME_LIMIT 25  /* Time limit in milliseconds */
 #define REDIS_MAX_WRITE_PER_EVENT (1024*64)
 #define REDIS_SHARED_SELECT_CMDS 10
 #define REDIS_SHARED_INTEGERS 10000