public function clear($prefix = '') { $prefix = $this->getNamespace() . $prefix . '*'; $it = null; self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY); while ($keys = self::$cache->scan($it, $prefix)) { self::$cache->delete($keys); } return true; }
public function testScan() { if (version_compare($this->version, "2.8.0", "lt")) { $this->markTestSkipped(); return; } // Key count $i_key_count = $this->get_keyspace_count('db0'); // Have scan retry $this->redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); // Scan them all $it = NULL; while ($arr_keys = $this->redis->scan($it)) { $i_key_count -= count($arr_keys); } // Should have iterated all keys $this->assertEquals(0, $i_key_count); // Unique keys, for pattern matching $str_uniq = uniqid() . '-' . uniqid(); for ($i = 0; $i < 10; $i++) { $this->redis->set($str_uniq . "::{$i}", "bar::{$i}"); } // Scan just these keys using a pattern match $it = NULL; while ($arr_keys = $this->redis->scan($it, "*{$str_uniq}*")) { $i -= count($arr_keys); } $this->assertEquals(0, $i); }
/** * Returns the resources found via the $data parameter * HOWEVER, it DOES allow wildcard searches * * @param $data * @param string $fields * * @return Collection|Model|null */ public function searchByWildcard($data, $fields = 'all') { $fields = $this->getFieldsForGet($fields); /** * If $this->indexes looks like ['id', 'email', 'password'] * and $data looks like ['name' => '*****@*****.**'] * then $indexes will end up looking something like: **_kenyon.jh@gmail.com_* */ $indexes = array_fill_keys($this->indexes, '*'); foreach ($data as $index => $value) { $indexes[$index] = str_replace(' ', '+', strtolower($value)); } $indexes = $this->hashName . ':*' . implode('_', $indexes); $foundKeys = []; /** * Redis only shows X entries at a time, and then gives the * cursor position of the next X. This is to prevent blocking * queries since it is single-threaded */ do { $cursorIndex = !isset($redisScan) ? 0 : $redisScan[0]; $redisScan = $this->redis->scan($cursorIndex, 'match', $indexes, 'count', 500); $foundKeys = array_merge($redisScan[1], $foundKeys); } while ($redisScan[0] != 0); switch (count($foundKeys)) { case 0: // If no keys were found, return NULL return NULL; case 1: // If only 1 match was found, return an instance of it $key = $this->redis->get($foundKeys[0]); return $this->get($key, $fields); default: // If multiple matches were found, return a collection of all of them $results = []; foreach ($foundKeys as $key) { $key = $this->redis->get($key); $results[] = $this->get($key, $fields); } return new Collection($results); } }
/** * @param int &$it * @param string $pattern * @param int $count * @return array|FALSE */ public function scan(&$it, $pattern = NULL, $count = NULL) { return parent::scan($it, $pattern, $count); }
echo "\nCopying data from Redis({$r_host}:{$r_port}[{$r_db}]) to SSDB({$s_host}, {$s_port})...\n"; if (scan_command_available()) { echo "Using SCAN.\n"; } else { echo "Using KEYS.\n"; } $count = 0; $total = 0; $entries = 0; echo "==============\n"; // check if phpredis and redis-server supports SCAN if (scan_command_available()) { $total = $redis->dbsize(); $it = NULL; $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); while ($keys = $redis->scan($it)) { copy_keys($keys); } } else { $keys = $redis->keys('*'); $total = count($keys); copy_keys($keys); } echo date('Y-m-d H:i:s') . " {$total} keys, {$entries} entries copied.\n"; echo "==============\n"; echo "Done.\n"; echo "\n"; function copy_keys($keys) { global $redis, $ssdb, $count, $total, $entries; foreach ($keys as $key) {
$pip->incr('b'); $pip->del('a'); $ret = $pip->exec(); var_dump($ret); exit; $ret = $redis->incr('test-num2')->incr('test-num2')->exec(); exit('aa' . $redis->get('test-num2')); $redis->multi(Redis::PIPELINE); for ($i = 0; $i < 10000; $i++) { $redis->incr('test-num')->include('test-num2'); } $redis->exec(); exit; $it = null; $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); while ($ret = $redis->scan($it, 'test*', 3)) { foreach ($ret as $item) { echo $item . PHP_EOL; } } exit; $key1 = 'key-list1'; $key2 = 'key-list2'; $timeout = 0; try { while ($item = $redis->brPop($key1, $key2, $timeout)) { var_dump($item); /* array(2) { [0]=> string(9) "key-list1" list name [1]=> string(1) "a" item value
* 如果下一页游标cursor不为0的话,也即没有到底的话: * 1.如果匹配到了,则返回匹配到的内容 * 2.如果没有匹配到,会继续接着往下一页寻找,函数不会有返回值 * 直到游标返回0,结束查找 * * 总结: * * 最大的区别就是php中的scan如果在下一页没有匹配到内容,则不会返回 * 直到找到匹配到的内容,才会返回值。 * 而redis服务器的scan每次都会根据你设定好的count值返回这次寻找的结果. */ $redis = new Redis(); $redis->connect('127.0.0.1', '6381', 20); $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); $match = 'the:key:you:wang:*'; $count = 10000; // 1 $result = $redis - scan($it, $match, $count); echo $it; var_dump($result); exit; // 2 while ($keys = $redis->scan($it, $match, $count)) { print_r($keys); // get the keys,so can do what you want // mostly use the scan result to del keys // because the redis CMD "keys" is terrible. // on "keys" cmd could hang on the whole redis server... // so replace the "keys" cmd with the "scan" $redis->del($keys); }
/** * {@inheritDoc} * * @link https://github.com/phpredis/phpredis#scan */ protected function _getAllKeys() { $iterator = null; $keys = []; // Retry when we get no keys back $this->_connection->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY); while ($scanned_keys = $this->_connection->scan($iterator)) { $keys += $scanned_keys; } return $keys; }