TT#63000 improve Redis SCAN increase and falloff

Instead of making the COUNT increase and falloff dependent on the number
of results produced, we make it dependent on the query run time. This is
to prevent Redis being blocked by extended consecutive SCAN queries.
Each individual query should not run longer than 100 ms, and we also add
a short pause before going to the next SCAN to give competing queries a
chance to run.

Change-Id: I6b88cacf795513cf3e0aeefc67fbedef8e1bb8c1
(cherry picked from commit 2a23b94027)
mr7.5.8
Richard Fuchs 5 years ago
parent 3ea2c4066f
commit d3c8ff6c0c

@ -58,3 +58,4 @@ upstream/tm-execute-TMCB_REQUEST_FWDED-cb-as-BRANCH_ROUTE-whe.patch
## backport from kamailio upstream (5.4)
upstream/ndb_redis-set-message-level-to-debug-on-exec.patch
sipwise/db_redis_skip_empty_keys.patch
sipwise/db_redis_graceful_scan.patch

@ -0,0 +1,52 @@
--- a/src/modules/db_redis/redis_dbase.c
+++ b/src/modules/db_redis/redis_dbase.c
@@ -754,7 +754,7 @@
int l;
-#undef USE_SCAN
+#define USE_SCAN
#ifdef USE_SCAN
@@ -762,6 +762,8 @@
unsigned long cursor = 0;
unsigned int match_count = match_count_start_val;
char match_count_str[16];
+ struct timeval start_tv, end_tv;
+ long tv_diff;
do {
snprintf(cursor_str, sizeof(cursor_str), "%lu", cursor);
@@ -796,7 +798,12 @@
goto err;
}
+ gettimeofday(&start_tv, NULL);
reply = db_redis_command_argv(con, query_v);
+ gettimeofday(&end_tv, NULL);
+ tv_diff = ((long long) end_tv.tv_sec * 1000LL + end_tv.tv_usec / 1000L)
+ - ((long long) start_tv.tv_sec * 1000LL + start_tv.tv_usec / 1000L);
+
db_redis_key_free(&query_v);
db_redis_check_reply(con, reply, err);
if (reply->type != REDIS_REPLY_ARRAY) {
@@ -870,11 +877,15 @@
}
#ifdef USE_SCAN
- // exponential increase and falloff, hovering around 1000 results
- if (keys_list->elements > 1300 && match_count > 500)
+ // exponential increase and falloff, not to exceed ~100 ms query run time
+ if (tv_diff > 50 && match_count > 10)
match_count /= 2;
- else if (keys_list->elements < 700 && match_count < 500000)
+ else if (tv_diff < 25 && match_count < 1000000)
match_count *= 2;
+ if (cursor > 0) {
+ // give other queries some time to run
+ usleep(100000);
+ }
#endif
db_redis_free_reply(&reply);
Loading…
Cancel
Save