diff --git a/src/debug.c b/src/debug.c index 42a73883d..4687fb6c0 100644 --- a/src/debug.c +++ b/src/debug.c @@ -722,6 +722,8 @@ void watchdogScheduleSignal(int period) { /* Enable the software watchdong with the specified period in milliseconds. */ void enableWatchdog(int period) { + int min_period; + if (server.watchdog_period == 0) { struct sigaction act; @@ -732,7 +734,11 @@ void enableWatchdog(int period) { act.sa_sigaction = watchdogSignalHandler; sigaction(SIGALRM, &act, NULL); } - if (period < 200) period = 200; /* We don't accept periods < 200 ms. */ + /* If the configured period is smaller than twice the timer period, it is + * too short for the software watchdog to work reliably. Fix it now + * if needed. */ + min_period = (1000/REDIS_HZ)*2; + if (period < min_period) period = min_period; watchdogScheduleSignal(period); /* Adjust the current timer. */ server.watchdog_period = period; } diff --git a/src/redis.c b/src/redis.c index bf36c84e6..45ed36c9d 100644 --- a/src/redis.c +++ b/src/redis.c @@ -594,10 +594,16 @@ void incrementallyRehash(void) { int j; for (j = 0; j < server.dbnum; j++) { + /* Keys dictionary */ if (dictIsRehashing(server.db[j].dict)) { dictRehashMilliseconds(server.db[j].dict,1); break; /* already used our millisecond for this loop... */ } + /* Expires */ + if (dictIsRehashing(server.db[j].expires)) { + dictRehashMilliseconds(server.db[j].expires,1); + break; /* already used our millisecond for this loop... */ + } } } @@ -622,13 +628,13 @@ void updateDictResizePolicy(void) { * keys that can be removed from the keyspace. */ void activeExpireCycle(void) { int j; - long long start = mstime(), timelimit; + long long start = ustime(), timelimit; /* We can use at max REDIS_EXPIRELOOKUPS_TIME_PERC percentage of CPU time * per iteration. Since this function gets called with a frequency of * REDIS_HZ times per second, the following is the max amount of - * milliseconds we can spend here: */ - timelimit = (1000/REDIS_HZ/100)*REDIS_EXPIRELOOKUPS_TIME_PERC; + * microseconds we can spend in this function. */ + timelimit = 1000000*REDIS_EXPIRELOOKUPS_TIME_PERC/REDIS_HZ/100; if (timelimit <= 0) timelimit = 1; for (j = 0; j < server.dbnum; j++) { @@ -638,9 +644,16 @@ void activeExpireCycle(void) { /* Continue to expire if at the end of the cycle more than 25% * of the keys were expired. */ do { - long num = dictSize(db->expires); + unsigned long num = dictSize(db->expires); + unsigned long slots = dictSlots(db->expires); long long now = mstime(); + /* When there are less than 1% filled slots getting random + * keys is expensive, so stop here waiting for better times... + * The dictionary will be resized asap. */ + if (num && slots > DICT_HT_INITIAL_SIZE && + (num*100/slots < 1)) break; + expired = 0; if (num > REDIS_EXPIRELOOKUPS_PER_CRON) num = REDIS_EXPIRELOOKUPS_PER_CRON; @@ -666,7 +679,7 @@ void activeExpireCycle(void) { * caller waiting for the other active expire cycle. */ iteration++; if ((iteration & 0xff) == 0 && /* Check once every 255 iterations */ - (mstime()-start) > timelimit) return; + (ustime()-start) > timelimit) return; } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4); } } @@ -869,7 +882,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { * a lot of memory movements in the parent will cause a lot of pages * copied. */ if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) { - run_with_period(1000) tryResizeHashTables(); + tryResizeHashTables(); if (server.activerehashing) incrementallyRehash(); } diff --git a/src/redis.h b/src/redis.h index dad8eb0c4..e279aab48 100644 --- a/src/redis.h +++ b/src/redis.h @@ -38,7 +38,7 @@ #define REDIS_ERR -1 /* Static server configuration */ -#define REDIS_HZ 10 /* Time interrupt calls/sec. */ +#define REDIS_HZ 100 /* Time interrupt calls/sec. */ #define REDIS_SERVERPORT 6379 /* TCP port */ #define REDIS_MAXIDLETIME 0 /* default client timeout: infinite */ #define REDIS_DEFAULT_DBNUM 16