summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2012-05-11 19:17:31 +0200
committerantirez <antirez@gmail.com>2012-05-12 09:33:24 +0200
commit3a401464e9c42fafeaa9405db60d10b3256aca51 (patch)
tree59aae143cef173f2e5eceae7522788fa5e8f1f5c
parent064223107e3ce2a8cae6e35245bb1037ff5b984c (diff)
downloadredis-3a401464e9c42fafeaa9405db60d10b3256aca51.tar.gz
More incremental active expired keys collection process.
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.
-rw-r--r--src/redis.c9
-rw-r--r--src/redis.h1
2 files changed, 9 insertions, 1 deletions
diff --git a/src/redis.c b/src/redis.c
index 0a12ccd2e..4cc378e24 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -609,9 +609,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%
@@ -640,6 +641,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);
}
}
diff --git a/src/redis.h b/src/redis.h
index 281c08787..b842b5f79 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -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