>  기사  >  데이터 베이스  >  모든 키를 순회하는 Redis 방법

모든 키를 순회하는 Redis 방법

尚
앞으로
2020-04-21 09:06:526998검색

Redis 키 명령은 Redis 키를 관리하는 데 사용됩니다. 이 기사에서는 Redis의 모든 키를 탐색하는 두 가지 방법인 KEYS 패턴과 SCAN 커서를 소개합니다. 이것이 여러분에게 도움이 되기를 바랍니다.

모든 키를 순회하는 Redis 방법

Redis의 모든 키 또는 지정된 모드의 키를 순회해야 할 때 가장 먼저 떠오르는 것은 KEYS 명령입니다.

KEYS pattern

공식 웹사이트에는 KEYS 명령에 대한 팁이 있습니다. KEYS는 매우 예를 들어 Redis는 1 수백만 개의 키가 있는 데이터베이스에서 쿼리를 실행하는 데 필요한 시간은 40밀리초입니다. 그러나 대규모 데이터베이스에서 이를 사용하면 여전히 성능 문제가 발생할 수 있습니다. 데이터 세트에서 특정 KEYS를 찾아야 하는 경우 대신 Redis의 컬렉션 구조 SETS를 사용하는 것이 좋습니다.

KEYS 명령은 사용이 매우 간단합니다.

redis> MSET one 1 two 2 three 3 four 4
OK
redis> KEYS *o*
1) "four"
2) "one"
3) "two"
redis> KEYS t??
1) "two"
redis> KEYS *
1) "four"
2) "three"
3) "one"
4) "two"
redis>

하지만 KEYS 명령은 일치하는 모든 키를 한 번에 반환하므로 Redis에 키가 너무 많으면 메모리 소비와 Redis 서버에 숨겨진 위험이 있습니다.

Redis 2.8 이상에서는 다음을 제공합니다. 더 좋은 키 탐색 명령 SCAN. 이 명령의 기본 형식:

SCAN cursor [MATCH pattern] [COUNT count]

SCAN은 실행될 때마다 적은 수의 요소만 반환하므로 KEYS나 서버를 차단하지 않고 프로덕션 환경에서 사용할 수 있습니다. SMEMBERS 명령에 문제가 있습니다.

SCAN 명령은 커서 기반 반복자입니다. 즉, 명령이 호출될 때마다 이전 반복 프로세스를 계속하려면 이전 호출에서 반환된 커서를 호출의 커서 매개 변수로 사용해야 합니다.

SCAN 명령의 커서 매개 변수(예: 커서 )를 0으로 설정하면 서버는 새로운 반복을 시작하고, 서버가 사용자에게 0 값의 커서를 반환하면 반복이 종료되었음을 의미합니다.

간단한 반복 데모:

redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

위의 예에서 첫 번째 반복에서는 0을 커서로 사용하여 새 반복의 시작을 나타냅니다. 두 번째 반복에서는 첫 번째 반복에서 반환된 커서 17을 새 반복 매개변수로 사용합니다.

분명히 SCAN 명령의 반환 값은 두 요소를 포함하는 배열입니다. 첫 번째 배열 요소는 다음 반복에 사용되는 새 커서이고 두 번째 배열 요소는 모든 반복 요소를 포함합니다.

참고: 반환된 커서가 반드시 증가하는 것은 아닙니다. 반환된 커서는 이전 커서보다 작을 수 있습니다.

SCAN 명령이 두 번째로 호출되면 명령은 커서 0을 반환합니다. 이는 반복이 종료되고 전체 데이터 세트가 완전히 통과되었음을 나타냅니다.

전체 반복: 0을 커서로 사용하여 새 반복을 시작하고 명령이 커서 0을 반환할 때까지 SCAN 명령을 계속 호출합니다. 이 프로세스를 완전 순회라고 합니다.

SCAN 증분 반복 명령은 각 실행이 지정된 수의 요소를 반환한다고 보장하지 않으며 심지어 0개의 요소를 반환할 수도 있습니다. 그러나 명령에 의해 반환된 커서가 0이 아닌 한 애플리케이션은 반복을 다음과 같이 처리해서는 안 됩니다. 마치다.

그러나 명령으로 반환되는 요소 수는 항상 특정 규칙을 준수합니다. 대규모 데이터 세트의 경우 증분 반복 명령은 매번 최대 수십 개의 요소를 반환할 수 있으며, 충분히 작은 데이터 세트의 경우 모든 키가 반환될 수 있습니다. 한 번의 반복으로 반환

COUNT 옵션

각 반복에서 반환되는 요소 수를 보장하지 않는 증분 반복 명령의 경우 COUNT 옵션을 사용하여 명령의 동작을 어느 정도 조정할 수 있습니다. COUNT 옵션의 목적은 사용자가 각 반복의 데이터 세트에서 반환되어야 하는 요소 수를 반복 명령에 알릴 수 있도록 하는 것입니다. COUNT 옵션을 사용하는 것은 증분 반복 명령에 대한 힌트와 동일합니다. 대부분의 경우 이 힌트는 반환 값 수를 제어하는 ​​데 더 효과적입니다.

참고: COUNT 옵션은 반환되는 키 수를 엄격하게 제어하지 않으며 대략적인 제약이라고만 말할 수 있습니다. 각 반복에 대해 동일한 COUNT 값을 사용할 필요는 없습니다. 사용자는 각 반복에서 필요에 따라 COUNT 값을 변경할 수 있습니다. 마지막 반복에서 반환된 커서를 다음 반복에 사용해야 한다는 점만 기억하세요.

MATCH 옵션

KEYS 명령과 마찬가지로 증분 반복 명령은 MATCH 매개변수를 제공하여 구현됩니다. glob 스타일 패턴 매개변수를 제공하여 명령은 주어진 패턴과 일치하는 요소만 반환합니다.

MATCH 옵션에 의한 요소의 패턴 매칭은 명령이 데이터 세트에서 요소를 검색한 후 클라이언트로 요소를 반환하기 전까지 수행되므로 반복된 데이터 세트에서 소수의 요소만 일치하는 경우 패턴을 적용한 경우 반복 명령은 요소를 반환하지 않고 여러 번 실행될 수 있습니다.

다음은 이 상황의 예입니다.

redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"
redis 127.0.0.1:6379>

보다시피 위 반복의 대부분은 어떤 요소도 반환하지 않습니다. 마지막 반복에서는 COUNT 옵션의 매개변수를 1000으로 설정하여 명령이 더 많은 요소를 반환하도록 명령이 이 반복에 대해 더 많은 요소를 검색하도록 강제합니다.

SCAN의 보안을 위해 프로덕션 환경에서는 모두 KEYS 대신 SCAN 명령을 사용하는 것을 권장합니다. 그러나 이 명령은 버전 2.8.0 이후에 추가되었으므로 이 버전보다 낮으면 주의하세요. Redis를 업그레이드해야 합니다.

다음은 PHP 코드를 사용하여 SCAN 명령의 사용을 보여줍니다.

<?php
 
$redis = new Redis();
 
$redis->connect(&#39;127.0.0.1&#39;, 6379);
 
 
/* 设置遍历的特性为不重复查找,该情况下扩展只会scan一次,所以可能会返回空集合 */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_NORETRY);
 
$it = NULL;
$pattern = &#39;*&#39;;
$count = 50;  // 每次遍历50条,注意是遍历50条,遍历出来的50条key还要去匹配你的模式,所以并不等于就能够取出50条key
 
do
{
    $keysArr = $redis->scan($it, $pattern, $count);
 
    if ($keysArr)
    {
        foreach ($keysArr as $key)
        {
            echo $key . "\n";
        }
    }
 
} while ($it > 0);   //每次调用 Scan会自动改变 $it 值,当$it = 0时 这次遍历结束 退出循环
 
 
echo &#39;---------------------------------------------------------------------------------&#39; . "\n";
 
 
/* 设置扩展在一次scan没有查找出记录时 进行重复的scan 直到查询出结果或者遍历结束为止 */
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
 
$it = NULL;
$pattern = &#39;*&#39;;
$count = 50;  // 每次遍历50条,注意是遍历50条,遍历出来的50条key还要去匹配你的模式,所以并不等于就能够取出50条key
 
//这种用法下我们只需要简单判断返回结果是否为空即可, 如果为空说明遍历结束
while ($keysArr = $redis->scan($it, $pattern, $count))
{
    foreach ($keysArr as $key)
    {
        echo $key . "\n";
    }
}

실행 결과:

[root@localhost php]# /usr/local/php/bin/php scan.php 
bm
bm2
h1
name
bit
bm1
places
cities
hhl
---------------------------------------------------------------------------------
bm
bm2
h1
name
bit
bm1
places
cities
hhl

注意:如果php执行报错 请升级到较新版本的Redis扩展。

更多redis知识请关注redis入门教程栏目。

위 내용은 모든 키를 순회하는 Redis 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제