Loi Dang
Loi Dang

Reputation: 378

SCAN command performance with phpredis

I'm replacing KEYS with SCAN using phpredis.

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
$it = NULL;
while($arr_keys = $redis->scan($it, "mykey:*", 10000)) {
    foreach($arr_keys as $str_key) {
        echo "Here is a key: $str_key\n";
    }
}

According to redis documentation, I use SCAN to paginate searches to avoid disadvantage of using KEYS.
But in practice, using above code costs me 3 times lower than using just a single $redis->keys()
So I'm wondering if I've done something wrong, or I have to pay speed to avoid KEYS's threat?

Note that I totally have 400K+ keys in my db, and 4 mykey:* keys

Upvotes: 4

Views: 5217

Answers (2)

jmto
jmto

Reputation: 301

A word of caution of using the example:

$it = NULL;
while($arr_keys = $redis->scan($it, "mykey:*", 10000)) {
    foreach($arr_keys as $str_key) {
        echo "Here is a key: $str_key\n";
    }
}

That can return empty array's if none of the 10000 keys scanned matches and then it will give up, and you didn't get all the keys you wanted! I would recommend doing more like this:

$it = null;
do
{
    $arr_keys = $redis->scan($it, $key, 10000);
    if (is_array($arr_keys) && !empty($arr_keys))
    {
        foreach ($arr_keys as $str_key)
        {
            echo "Here is a key: $str_key\n";
        }
    }
} while ($arr_keys !== false);

And why it takes so long, 400k+ keys, 10000, that's 40 scan requests to redis, if it's not on the local machine, add latency for every 40 redis query to your speed.

Upvotes: 6

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64923

Since using keys in production environments is just forbidden because it blocks the entire server while iterating global space keys, then, there's no discussion here about use or not to use keys.

In the other hand, if you want to speed up things, you should go further with Redis: you should index your data.

I doubt that these 400K keys couldn't be categorized in sets or sorted sets, or even hashes, so when you need a particular subset of your 400K-keys-database you could run any scan-equivalent command against a set of 1K items, instead of 400K.

Redis is about indexing data. If not, you're using it like just a simple key-value store.

Upvotes: 5

Related Questions