Previous projects have been useful to the Redis Keys command to get some key, this command in the database particularly large case will block for a long time, so there is a great security risk, so this time to optimize.
The official website recommends using the Scan command instead. So I used ...
The following is the code that uses the scan command to match the corresponding mode key:
$redis = new Redis (), $redis->connect (' localhost ', 6379), $iterator = null;while ($keys = $redis->scan ($iterator, ' Test* ') { foreach ($keys as $key) { echo $key. Php_eol;} }
This code should be OK? This is from the JetBrains company's software phpstorm code hints library picked out, only add the pattern parameters, but the results are problematic.
With the keys command you can get the set "Test1″," Test2″,....., "Test5″ these 5 keys, but with scan there is nothing to output.
......
............
..................
After a multi-party analysis, it turns out that the scan command has a problem with the return value.
In fact, the official Redis document also explicitly said that the scan command each iteration of the time, it is possible to return empty, but this is not the end of the flag, but when the value of the returned iteration is "0″" is the end.
Therefore, the above code in the iteration, if there is no key return, $keys is an empty array, so the while loop is naturally interrupted, so there is no output.
This is especially true when key is particularly high in Redis, which rarely happens when key is only a few hundred times, but it is almost certainly true when key reaches tens of millions.
To reduce the occurrence of this condition, you can set the third parameter count of the scan function to a larger number. But this is not the fundamental solution to this problem, there are two basic approaches:
1.setOption
Use the SetOption function to set the behavior of the iteration. The following is the sample code:
$redis = new Redis (); $redis->connect (' localhost ', 6379); $redis->setoption (Redis::opt_scan,redis::scan_retry) ; $iterator = null;while ($keys = $redis->scan ($iterator, ' test* ')) { foreach ($keys as $key) { echo $key. Php_eol;} }
Compared with the above code, just a setoption operation, what is the function of this operation? This operation is to tell the redis extension that when the scan command is executed, the returned result set is empty, the function does not return, but proceeds directly to the Scan command, of course, these steps are automatically completed by the extension, when the scan function returns, or return False, that is, the end of the iteration, A key that matches the pattern pattern is not found, or a matching key is returned, but no longer returns an empty array.
2.while (True)
The way the above is done automatically by PHP extensions, we can also change the style to achieve the same effect.
$redis = new Redis (), $redis->connect (' localhost ', 6379), $iterator = Null;while (true) {$keys = $redis->scan ($it Erator, ' test* '); if ($keys = = = False) {//end of iteration, no key return matching pattern was found; } foreach ($keys as $key) {echo $key. Php_eol; }}