Skip to content

Commit 84b01f6

Browse files
committedNov 18, 2019
Expire cycle: introduce configurable effort.
·
8.2-m016.0-rc1
1 parent 2766805 commit 84b01f6

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed
 

‎src/expire.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
109109
* of already expired keys in the database is estimated to be lower than
110110
* a given percentage, in order to avoid doing too much work to gain too
111111
* little memory.
112+
*
113+
* The configured expire "effort" will modify the baseline parameters in
114+
* order to do more work in both the fast and slow expire cycles.
112115
*/
113116

114117
#define ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP 20 /* Keys for each DB loop. */
@@ -118,6 +121,21 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
118121
we do extra efforts. */
119122

120123
void activeExpireCycle(int type) {
124+
/* Adjust the running parameters according to the configured expire
125+
* effort. The default effort is 1, and the maximum configurable effort
126+
* is 10. */
127+
unsigned long
128+
effort = server.active_expire_effort,
129+
config_keys_per_loop = ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP +
130+
ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP/4*effort,
131+
config_cycle_fast_duration = ACTIVE_EXPIRE_CYCLE_FAST_DURATION *
132+
ACTIVE_EXPIRE_CYCLE_FAST_DURATION/4*effort,
133+
config_cycle_slow_time_perc = ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC +
134+
2*effort,
135+
config_cycle_acceptable_stale = ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE-
136+
effort;
137+
if (config_cycle_acceptable_stale < 1) config_cycle_acceptable_stale = 1;
138+
121139
/* This function has some global state in order to continue the work
122140
* incrementally across calls. */
123141
static unsigned int current_db = 0; /* Last DB tested. */
@@ -138,10 +156,11 @@ void activeExpireCycle(int type) {
138156
* for time limit, unless the percentage of estimated stale keys is
139157
* too high. Also never repeat a fast cycle for the same period
140158
* as the fast cycle total duration itself. */
141-
if (!timelimit_exit && server.stat_expired_stale_perc <
142-
ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE) return;
159+
if (!timelimit_exit &&
160+
server.stat_expired_stale_perc < config_cycle_acceptable_stale)
161+
return;
143162

144-
if (start < last_fast_cycle + ACTIVE_EXPIRE_CYCLE_FAST_DURATION*2)
163+
if (start < last_fast_cycle + (long long)config_cycle_fast_duration*2)
145164
return;
146165

147166
last_fast_cycle = start;
@@ -157,16 +176,16 @@ void activeExpireCycle(int type) {
157176
if (dbs_per_call > server.dbnum || timelimit_exit)
158177
dbs_per_call = server.dbnum;
159178

160-
/* We can use at max ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC percentage of CPU
179+
/* We can use at max 'config_cycle_slow_time_perc' percentage of CPU
161180
* time per iteration. Since this function gets called with a frequency of
162181
* server.hz times per second, the following is the max amount of
163182
* microseconds we can spend in this function. */
164-
timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;
183+
timelimit = config_cycle_slow_time_perc*1000000/server.hz/100;
165184
timelimit_exit = 0;
166185
if (timelimit <= 0) timelimit = 1;
167186

168187
if (type == ACTIVE_EXPIRE_CYCLE_FAST)
169-
timelimit = ACTIVE_EXPIRE_CYCLE_FAST_DURATION; /* in microseconds. */
188+
timelimit = config_cycle_fast_duration; /* in microseconds. */
170189

171190
/* Accumulate some global stats as we expire keys, to have some idea
172191
* about the number of keys that are already logically expired, but still
@@ -214,8 +233,8 @@ void activeExpireCycle(int type) {
214233
ttl_sum = 0;
215234
ttl_samples = 0;
216235

217-
if (num > ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP)
218-
num = ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP;
236+
if (num > config_keys_per_loop)
237+
num = config_keys_per_loop;
219238

220239
/* Here we access the low level representation of the hash table
221240
* for speed concerns: this makes this code coupled with dict.c,
@@ -277,7 +296,7 @@ void activeExpireCycle(int type) {
277296
/* We don't repeat the cycle for the current database if there are
278297
* an acceptable amount of stale keys (logically expired but yet
279298
* not reclained). */
280-
} while ((expired*100/sampled) > ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE);
299+
} while ((expired*100/sampled) > config_cycle_acceptable_stale);
281300
}
282301

283302
elapsed = ustime()-start;

‎src/server.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,7 @@ void initServerConfig(void) {
22942294
server.maxidletime = CONFIG_DEFAULT_CLIENT_TIMEOUT;
22952295
server.tcpkeepalive = CONFIG_DEFAULT_TCP_KEEPALIVE;
22962296
server.active_expire_enabled = 1;
2297+
server.active_expire_effort = CONFIG_DEFAULT_ACTIVE_EXPIRE_EFFORT;
22972298
server.jemalloc_bg_thread = 1;
22982299
server.active_defrag_enabled = CONFIG_DEFAULT_ACTIVE_DEFRAG;
22992300
server.active_defrag_ignore_bytes = CONFIG_DEFAULT_DEFRAG_IGNORE_BYTES;

‎src/server.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ typedef long long ustime_t; /* microsecond time type. */
179179
#define CONFIG_DEFAULT_DEFRAG_MAX_SCAN_FIELDS 1000 /* keys with more than 1000 fields will be processed separately */
180180
#define CONFIG_DEFAULT_PROTO_MAX_BULK_LEN (512ll*1024*1024) /* Bulk request max size */
181181
#define CONFIG_DEFAULT_TRACKING_TABLE_MAX_FILL 10 /* 10% tracking table max fill. */
182+
#define CONFIG_DEFAULT_ACTIVE_EXPIRE_EFFORT 1 /* From 1 to 10. */
182183

183184
#define ACTIVE_EXPIRE_CYCLE_SLOW 0
184185
#define ACTIVE_EXPIRE_CYCLE_FAST 1
@@ -1204,6 +1205,7 @@ struct redisServer {
12041205
int maxidletime; /* Client timeout in seconds */
12051206
int tcpkeepalive; /* Set SO_KEEPALIVE if non-zero. */
12061207
int active_expire_enabled; /* Can be disabled for testing purposes. */
1208+
int active_expire_effort; /* From 1 (default) to 10, active effort. */
12071209
int active_defrag_enabled;
12081210
int jemalloc_bg_thread; /* Enable jemalloc background thread */
12091211
size_t active_defrag_ignore_bytes; /* minimum amount of fragmentation waste to start active defrag */

0 commit comments

Comments
 (0)
Please sign in to comment.