diff --git a/src/redis.c b/src/redis.c index d4d91f176f6d833f8771b32368388d60776526a9..77c26b97ef033a5841d0423713d9a9ab340bd01f 100644 --- a/src/redis.c +++ b/src/redis.c @@ -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); } } diff --git a/src/redis.h b/src/redis.h index 2b54c709d60bead3dcadf5141b6609f640c5e2a0..8ac842479d9c835291f9ec48026a84cb701ed5c6 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