summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-08-06 12:55:49 +0200
committerantirez <antirez@gmail.com>2013-08-06 12:55:49 +0200
commit6500fabfb881a7ffaadfbff74ab801c55d4591fc (patch)
tree7a2ba6227fad2c5e4c27ca272070268ba0f73803
parentd398f38879a3d29f74fd2cea61f9ae93a3a2af50 (diff)
downloadredis-6500fabfb881a7ffaadfbff74ab801c55d4591fc.tar.gz
Some activeExpireCycle() refactoring.
-rw-r--r--src/redis.c45
-rw-r--r--src/redis.h8
2 files changed, 32 insertions, 21 deletions
diff --git a/src/redis.c b/src/redis.c
index 67621bde9..d1dde4d1e 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -691,33 +691,37 @@ int activeExpireCycleTryExpire(redisDb *db, struct dictEntry *de, long long now)
* No more than REDIS_DBCRON_DBS_PER_CALL databases are tested at every
* iteration.
*
- * If fast is non-zero the function will try to run a "fast" expire cycle that
- * takes no longer than EXPIRE_FAST_CYCLE_DURATION microseconds, and is not
- * repeated again before the same amount of time.
- *
* This kind of call is used when Redis detects that timelimit_exit is
* true, so there is more work to do, and we do it more incrementally from
- * the beforeSleep() function of the event loop. */
-
-#define EXPIRE_FAST_CYCLE_DURATION 1000
+ * the beforeSleep() function of the event loop.
+ *
+ * Expire cycle type:
+ *
+ * If type is ACTIVE_EXPIRE_CYCLE_FAST the function will try to run a
+ * "fast" expire cycle that takes no longer than EXPIRE_FAST_CYCLE_DURATION
+ * microseconds, and is not repeated again before the same amount of time.
+ *
+ * If type is ACTIVE_EXPIRE_CYCLE_SLOW, that normal expire cycle is
+ * executed, where the time limit is a percentage of the REDIS_HZ period
+ * as specified by the REDIS_EXPIRELOOKUPS_TIME_PERC define. */
-void activeExpireCycle(int fast) {
+void activeExpireCycle(int type) {
/* This function has some global state in order to continue the work
* incrementally across calls. */
static unsigned int current_db = 0; /* Last DB tested. */
static int timelimit_exit = 0; /* Time limit hit in previous call? */
+ static long long last_fast_cycle = 0; /* When last fast cycle ran. */
unsigned int j, iteration = 0;
unsigned int dbs_per_call = REDIS_DBCRON_DBS_PER_CALL;
long long start = ustime(), timelimit;
- static long long last_fast_cycle = 0;
- if (fast) {
+ if (type == ACTIVE_EXPIRE_CYCLE_FAST) {
/* Don't start a fast cycle if the previous cycle did not exited
* for time limt. Also don't repeat a fast cycle for the same period
* as the fast cycle total duration itself. */
if (!timelimit_exit) return;
- if (start < last_fast_cycle + EXPIRE_FAST_CYCLE_DURATION) return;
+ if (start < last_fast_cycle + ACTIVE_EXPIRE_CYCLE_FAST_DURATION) return;
last_fast_cycle = start;
}
@@ -731,15 +735,16 @@ void activeExpireCycle(int fast) {
if (dbs_per_call > server.dbnum || timelimit_exit)
dbs_per_call = server.dbnum;
- /* We can use at max REDIS_EXPIRELOOKUPS_TIME_PERC percentage of CPU time
+ /* We can use at max ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC percentage of CPU time
* per iteration. Since this function gets called with a frequency of
* server.hz times per second, the following is the max amount of
* microseconds we can spend in this function. */
- timelimit = 1000000*REDIS_EXPIRELOOKUPS_TIME_PERC/server.hz/100;
+ timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;
timelimit_exit = 0;
if (timelimit <= 0) timelimit = 1;
- if (fast) timelimit = EXPIRE_FAST_CYCLE_DURATION; /* in microseconds. */
+ if (type == ACTIVE_EXPIRE_CYCLE_FAST)
+ timelimit = ACTIVE_EXPIRE_CYCLE_FAST_DURATION; /* in microseconds. */
for (j = 0; j < dbs_per_call; j++) {
int expired;
@@ -770,8 +775,8 @@ void activeExpireCycle(int fast) {
/* The main collection cycle. Sample random keys among keys
* with an expire set, checking for expired ones. */
expired = 0;
- if (num > REDIS_EXPIRELOOKUPS_PER_CRON)
- num = REDIS_EXPIRELOOKUPS_PER_CRON;
+ if (num > ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP)
+ num = ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP;
while (num--) {
dictEntry *de;
@@ -788,7 +793,9 @@ void activeExpireCycle(int fast) {
timelimit_exit = 1;
}
if (timelimit_exit) return;
- } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4);
+ /* We don't repeat the cycle if there are less than 25% of keys
+ * found expired in the current DB. */
+ } while (expired > ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP/4);
}
}
@@ -908,7 +915,7 @@ void databasesCron(void) {
/* Expire keys by random sampling. Not required for slaves
* as master will synthesize DELs for us. */
if (server.active_expire_enabled && server.masterhost == NULL)
- activeExpireCycle(0);
+ activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);
/* Perform hash tables rehashing if needed, but only if there are no
* other processes saving the DB on disk. Otherwise rehashing is bad
@@ -1151,7 +1158,7 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
redisClient *c;
/* Run a fast expire cycle. */
- activeExpireCycle(1);
+ activeExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST);
/* Try to process pending commands for clients that were just unblocked. */
while (listLength(server.unblocked_clients)) {
diff --git a/src/redis.h b/src/redis.h
index 7f0ab64e3..9870a3130 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -74,8 +74,6 @@
#define REDIS_MAXIDLETIME 0 /* default client timeout: infinite */
#define REDIS_DEFAULT_DBNUM 16
#define REDIS_CONFIGLINE_MAX 1024
-#define REDIS_EXPIRELOOKUPS_PER_CRON 20 /* lookup 20 expires per loop */
-#define REDIS_EXPIRELOOKUPS_TIME_PERC 25 /* CPU max % for keys collection */
#define REDIS_DBCRON_DBS_PER_CALL 16
#define REDIS_MAX_WRITE_PER_EVENT (1024*64)
#define REDIS_SHARED_SELECT_CMDS 10
@@ -124,6 +122,12 @@
#define REDIS_PEER_ID_LEN (REDIS_IP_STR_LEN+32) /* Must be enough for ip:port */
#define REDIS_BINDADDR_MAX 16
+#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */
+#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */
+#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 /* CPU max % for keys collection */
+#define ACTIVE_EXPIRE_CYCLE_SLOW 0
+#define ACTIVE_EXPIRE_CYCLE_FAST 1
+
/* Protocol and I/O related defines */
#define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */
#define REDIS_IOBUF_LEN (1024*16) /* Generic I/O buffer size */