태그 보관물: redis

redis

Redis를 사용하여 패턴과 일치하는 키를 원자 적으로 삭제하는 방법 prefix:<numeric_id>해시가 있습니다. 때때로 나는 그것들을

내 Redis DB에는 많은 prefix:<numeric_id>해시가 있습니다.

때때로 나는 그것들을 모두 원자 적으로 제거하고 싶습니다. 분산 잠금 메커니즘을 사용하지 않고 어떻게해야합니까?



답변

redis 2.6.0부터는 원자 적으로 실행되는 lua 스크립트를 실행할 수 있습니다. 한 번도 쓴 적이 없지만 다음과 같이 보일 것입니다.

EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]

경고 : Redis 문서에서 알 수 있듯이 성능 문제로 인해 keys
명령은 프로덕션 환경에서 일반 작업에 사용해서는 안되며이 명령은 디버깅 및 특수 작업에 사용됩니다. 더 읽어보기

EVAL 문서를 참조하십시오 .


답변

bash에서 실행하십시오.

redis-cli KEYS "prefix:*" | xargs redis-cli DEL

최신 정보

알아 들었어. 이 방법은 어떻습니까 : 현재 추가 증분 접두사를 저장하고 모든 키에 추가하십시오. 예를 들면 다음과 같습니다.

다음과 같은 값이 있습니다.

prefix_prefix_actuall = 2
prefix:2:1 = 4
prefix:2:2 = 10

데이터를 제거해야 할 경우 prefix_actuall을 먼저 변경 (예 : set prefix_prefix_actuall = 3)하여 응용 프로그램이 키 prefix : 3 : 1 및 prefix : 3 : 2에 새 데이터를 씁니다. 그런 다음 접두사 : 2 : 1 및 접두사 : 2 : 2에서 이전 값을 안전하게 가져오고 이전 키를 제거 할 수 있습니다.


답변

다음은 Lua에서 구현 된 완전 작동 및 원자 버전의 와일드 카드 삭제입니다. 네트워크 연결이 훨씬 적어 xargs 버전보다 훨씬 빠르게 실행되며 완전히 원자 적이므로 완료 될 때까지 redis에 대한 다른 요청을 차단합니다. Redis 2.6.0 이상에서 키를 원자 적으로 삭제하려면 다음과 같이하십시오.

redis-cli -n [some_db] -h [some_host_name] EVAL "return redis.call('DEL', unpack(redis.call('KEYS', ARGV[1] .. '*')))" 0 prefix:

이것은이 질문에 대한 그의 대답에서 @mcdizzle의 아이디어의 작동하는 버전입니다. 아이디어 100 %가 그에게갑니다.

편집 : 아래의 Kikito의 의견에 따라 Redis 서버의 여유 메모리보다 삭제할 ​​키가 더 많으면 “포장을 풀기에는 너무 많은 요소”오류가 발생 합니다. 이 경우 다음을 수행하십시오.

for _,k in ipairs(redis.call('keys', ARGV[1])) do
    redis.call('del', k)
end

키키 토가 제안한대로.


답변

면책 조항 : 다음 솔루션 원 자성을 제공 하지 않습니다 .

V2.8 시작 당신은 정말 사용하려는 SCAN KEYS [1] 대신 명령을 사용합니다. 다음 Bash 스크립트는 패턴별로 키를 삭제하는 방법을 보여줍니다.

#!/bin/bash

if [ $# -ne 3 ]
then
  echo "Delete keys from Redis matching a pattern using SCAN & DEL"
  echo "Usage: $0 <host> <port> <pattern>"
  exit 1
fi

cursor=-1
keys=""

while [ $cursor -ne 0 ]; do
  if [ $cursor -eq -1 ]
  then
    cursor=0
  fi

  reply=`redis-cli -h $1 -p $2 SCAN $cursor MATCH $3`
  cursor=`expr "$reply" : '\([0-9]*[0-9 ]\)'`
  keys=${reply##[0-9]*[0-9 ]}
  redis-cli -h $1 -p $2 DEL $keys
done

[1] KEYS 는 DoS를 초래할 수있는 위험한 명령입니다. 다음은 설명서 페이지에서 인용 한 것입니다.

경고 : KEYS는 매우주의해서 프로덕션 환경에서만 사용해야하는 명령으로 간주하십시오. 큰 데이터베이스에 대해 실행될 때 성능이 저하 될 수 있습니다. 이 명령은 키 스페이스 레이아웃 변경과 같은 디버깅 및 특수 작업을위한 것입니다. 일반 응용 프로그램 코드에서 키를 사용하지 마십시오. 키 공간의 하위 세트에서 키를 찾는 방법을 찾고 있다면 세트 사용을 고려하십시오.

업데이트 : 동일한 기본 효과에 대한 하나의 라이너-

$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL

답변

다른 답변을 파싱하는 데 어려움이있는 사람들을 위해 :

eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0

대체 key:*:pattern자신의 패턴과이 점을 입력 redis-cli하고 당신은 갈 수 있습니다.

신용 출처 : http://redis.io/commands/del


답변

redis 3.2.8에서 아래 명령을 사용하고 있습니다.

redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL

키 패턴 검색과 관련된 추가 도움말은 여기 ( https://redis.io/commands/keys) 에서 얻을 수 있습니다 . 같은 사용자의 요구 사항에 따라 사용자의 편리 글로브 스타일의 패턴을 사용 *YOUR_KEY_PREFIX*하거나 YOUR_KEY_PREFIX??또는 기타.

그리고 아래 중 하나보다 Redis PHP 라이브러리를 통합 한 사람 이 도움이 될 것입니다.

flushRedisMultipleHashKeyUsingPattern("*YOUR_KEY_PATTERN*"); //function call

function flushRedisMultipleHashKeyUsingPattern($pattern='')
        {
            if($pattern==''){
                return true;
            }

            $redisObj = $this->redis;
            $getHashes = $redisObj->keys($pattern);
            if(!empty($getHashes)){
                $response = call_user_func_array(array(&$redisObj, 'del'), $getHashes); //setting all keys as parameter of "del" function. Using this we can achieve $redisObj->del("key1","key2);
            }
        }

감사합니다 🙂


답변

@mcdizle의 솔루션이 작동하지 않습니다. 한 항목에 대해서만 작동합니다.

이것은 프리픽스가 동일한 모든 키에 적용됩니다.

EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 prefix*

참고 : ‘접두사’를 키 접두사로 바꿔야합니다.