I'm trying to replace the keys function from predis for scan in order to increase the performance in some parsing that we do.
The problem is that when I do the scan operation it seems to fall into an infinite loop, which makes no sense because according to the redis documentation scan will return the iterator to 0 when it's done.
$it = null;
$keysFound = [];
do {
$redisKeys = $redis->scan($it,"*{$query}", 10);
if (!empty($keys)) {
array_merge($keysFound, $redisKeys);
}
} while($it != 0);
I just want to replace it so we don't do this
$keys = $redis->keys("*{$query}");
I have tried everything, please some help.
UPDATE Checking on the cli I see that it never finds the key and stays in loop even if I put the exact same key that I can see in redsmin.
127.0.0.1:6379> scan 122880 MATCH x_dashboard_dashboard_row_1005_251
1) "118784"
2) (empty list or set)
127.0.0.1:6379> scan 118784 MATCH x_dashboard_dashboard_row_1005_251
1) "18432"
2) (empty list or set)
127.0.0.1:6379> scan 18432 MATCH x_dashboard_dashboard_row_1005_251
1) "59392"
2) (empty list or set)
127.0.0.1:6379> scan 59392 MATCH x_dashboard_dashboard_row_1005_251
1) "63488"
2) (empty list or set)
127.0.0.1:6379> scan 63488 MATCH x_dashboard_dashboard_row_1005_251
1) "123904"
2) (empty list or set)
127.0.0.1:6379> scan 123904 MATCH x_dashboard_dashboard_row_1005_251
1) "19456"
2) (empty list or set)
127.0.0.1:6379> scan 19456 MATCH x_dashboard_dashboard_row_1005_251
1) "121856"
2) (empty list or set)
127.0.0.1:6379> scan 121856 MATCH x_dashboard_dashboard_row_1005_251
1) "115200"
2) (empty list or set)
127.0.0.1:6379> scan 115200 MATCH x_dashboard_dashboard_row_1005_251
1) "119296"
2) (empty list or set)
127.0.0.1:6379> scan 119296 MATCH x_dashboard_dashboard_row_1005_251
1) "109056"
2) (empty list or set)
127.0.0.1:6379>
Is there something that could be wrongly configured? I have never worked with redis before so I don't know if it could be wrong configuration related.
SOLVED The issue was that we have a very big amount of keys so increasing the COUNT value to a bigger amount gave the correct results.
If you want to do the scan yourself, then you need to capture the returned cursor from the response:
$it = null;
$keysFound = [];
do {
$response = $redis->scan($it,"*{$query}", 10);
$it = $response[0];
$redisKeys = $response[1];
if (!empty($keys)) {
array_merge($keysFound, $redisKeys);
}
} while($it != 0);
See https://redis.io/commands/scan to understand the response.
But take a look at the iterators, as you may be reinventing the wheel (taken from How to use SCAN with the MATCH option in Predis, added count
):
use Predis\Collection\Iterator;
$client = ...;
$pattern = 'foo*';
$count = 100;
foreach (new Iterator\Keyspace($client, $pattern, $count) as $key) {
...
}