Limit the *SCAN command dictScan iterations

*SCAN will cause redis server to hang for seconds
after millions of keys was deleted by SCAN/DEL pairs
This commit is contained in:
xiaost 2014-09-09 17:53:30 +08:00
parent b892ea70ae
commit acfc19633d

View File

@ -493,6 +493,11 @@ void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) {
if (ht) {
void *privdata[2];
/* We set the max number of iterations to ten times the specified
* COUNT, so if the hash table is in a pathological state (very
* sparsely populated) we avoid to block too much time at the cost
* of returning no or very few elements. */
long maxiterations = count*10;
/* We pass two pointers to the callback: the list to which it will
* add new elements, and the object containing the dictionary so that
@ -501,7 +506,9 @@ void scanGenericCommand(redisClient *c, robj *o, unsigned long cursor) {
privdata[1] = o;
do {
cursor = dictScan(ht, cursor, scanCallback, privdata);
} while (cursor && listLength(keys) < (unsigned long)count);
} while (cursor &&
maxiterations-- &&
listLength(keys) < (unsigned long)count);
} else if (o->type == REDIS_SET) {
int pos = 0;
int64_t ll;