내 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*
참고 : ‘접두사’를 키 접두사로 바꿔야합니다.