Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
6500fabf
Commit
6500fabf
authored
Aug 06, 2013
by
antirez
Browse files
Some activeExpireCycle() refactoring.
parent
d398f388
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/redis.c
View file @
6500fabf
...
...
@@ -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
_EXPIRE
LOOKUPS
_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
_EXPIRE
LOOKUPS
_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)) {
...
...
src/redis.h
View file @
6500fabf
...
...
@@ -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 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment