2017-10-28 15 views
4

redis 키와 값을 처리하기 위해 아래 bash 스크립트를 작성했습니다. 내 Redis에 약 45 ~ 50 백만 건의 열쇠가 있습니다. 모든 값을 검색하고 일부 처리를 수행하려고합니다. 그렇게하기 위해 아래 스크립트는 1 백만 건의 키를 처리하는 데 1 시간이 걸립니다. 5 천만 건의 열쇠를 처리하려면 50 시간이 걸릴 것이고, 그 일을하고 싶지는 않습니다. 누군가가 제안을 해줄 수 있다면 나는 그 스크립트를 최적화하도록 누군가를 기쁘게 도와 줄 수있다.50 만 개의 키를 처리하기 위해 redis cli 스크립트를 최적화하는 방법

내 레디 스 키와 값의 패턴 :

Keys - 123.item.media 
Values - 93839,abc,98,829 | 38282,yiw,282,282 | 8922,dux,382,993 | 

Keys - 234.item.media 
Values - 2122,eww,92,211 | 8332,uei,902,872 | 9039,uns,892,782 | 

Keys - 839.item.media 
Values - 7822,nkp,77,002 | 7821,mko,999,822 | 

아래 스크립트에서 나는 내 모든 키를 전달하고 내가 각 키에 대해 얼마나 많은 기록을 계산하고있다. 예를 들어 -이 키 (123.item.media)에는 3 개의 레코드가 있고 여기에는 (839.media) 두 개의 레코드가 있습니다.

그래서 보브 키와 값의 경우, 출력은 다음과 같아야합니다 총 개수 : 8

같은 방법으로 내가 50 개 수백만 키에 대한 일을 해요 - 너무 많은 시간을하고있다.

내 코드 :

#!/bin/sh 
cursor=-1 
keys="" 
recordCount=0 
while [ $cursor -ne 0 ]; 
do 
     if [ $cursor -eq -1 ] 
     then 
     cursor=0 
    fi 
    reply=`redis-cli SCAN $cursor MATCH "*" COUNT 100` 
    #echo $reply 
    cursor=`expr "$reply" : '\([0-9]*[0-9 ]\)'` 
    keys=${reply#[0-9]*[[:space:]]} 
    for i in $keys 
    do 
    #echo $i 
    #echo $keys 
    value=$(redis-cli GET $i) 
    temCount=`echo $value | awk -F\| '{print NF}'` 
    #echo $temCount 
    recordCount=`expr ${temCount} + ${recordCount}` 
    done 
done 

echo "Total Count: " $recordCount 

사전에 도움을 주셔서 감사합니다!

+0

C, C++, Python, Perl, PHP 등을 사용하여 모든 명령에 대해 새로운 프로세스와 연결을 생성하므로 다른 언어로이 작업을 수행하십시오. –

답변

2

Bash 내장 명령으로 수행 할 수있는 산술과 같은 간단한 작업 일지라도 반복문에서 너무 많은 시간을 분기하고 있습니다. 몇 백만 번 실행되는 루프에서 이러한 일이 발생하면 속도가 느려집니다. 예를 들어 :

  • cursor=$(expr "$reply" : '\([0-9]*[0-9 ]\)')
  • temCount=$(echo $value | awk -F\| '{print NF}')
  • recordCount=$(expr ${temCount} + ${recordCount})

나는 레디 스 전문가가 아니다. 레디 스-CLI의 내 피상적 인 이해를 바탕으로,이 작업을 수행 할 수 있습니다 :

redis-cli --scan | sort -u > all.keys 
while read -r key; 
    value=$(redis-cli get "$key") 
    # do your processing 
done < all.keys 

을이 일을 가속화하지 않으면 다음 생각은 몇 천 개 라인의 덩어리로 all.keys 파일을 분할하고 실행하는 것입니다 키의 각 하위 집합에 대한 병렬 루프. 이 속도가 충분히 빠르지 않으면 mget 명령을 탐색하고 루프를 변경하여 값을 하나씩 가져 오도록 설정하는 것이 좋습니다.

또한 Bash가 최선의 선택이 아닐 수도 있습니다. 파이썬이나 루비에서 더 좋은 방법이 있다고 확신합니다.

1

많은 시간이 라인 당 5 천만 키 위해 5 천만 네트워크 호출 낭비지고 : 말

value=$(redis-cli GET $i) 

대량 쿼리를 수행하려면, 당신은 그냥 목록에서 GET 명령을 추가 할 수 있습니다 1000으로 설정하고 --pipe 옵션을 사용하여 일괄 쿼리를 수행합니다. 대량 삽입의

--pipe    Transfer raw Redis protocol from stdin to server. 
    --pipe-timeout <n> In --pipe mode, abort with error if after sending all data. 
        no reply is received within <n> seconds. 

예는 대량 비슷한 라인에 읽고 유도 할 수있다, 레디 스 공식 문서에 here 주어집니다.

이것은 분명히 필요한 부스트를 제공하고 스크립트를 50 시간 대신 2 시간으로 변환합니다. 대량 목록의 값을 1000,10000 또는 100000으로 조정하여 가치 데이터 크기에 따라 가장 적합한 것이 무엇인지 확인하십시오.