메뉴

문서정보

BLPOP

BLPOP는 LPOP의 블록킹(blocking) 버전이다. LPOP는 리스트에 데이터가 없으면 즉시 nil을 반환한다. 메시지큐로 REDIS를 사용하는 애플리케이션에서 LPOP를 사용하면, 리스트에 데이터가 있는지를 검사하면서 루프를 돌게 된다.

BLPOP를 호출하면, 최소한 하나의 데이터가 준비될 때 까지, 블록킹된다. 그러다가 데이터가 준비되면, 명령 수행 끝내고 pop한 데이터를 반환한다. 루프를 돌면서 busy wait 상태에 있을 필요가 없다. 특히 메시지 큐 구현에 유리하다.

key로는 POP요청을 수행할 리스트의 이름을 사용한다. 하나 이상의 리스트에 대해서 POP요청을 할 수 있다. 마지막 매개변수로 timeout을 설정할 수 없다. timeout 시간동안 데이터가 준비되지 않으면 nil을 반환한다. timeout 값을 0으로 하면 무한정 기다린다.
BLPOP list1 list2 list3 0

클라이언트가 두 개 이상의 key에 대해서 BLPOP 연산을 수행할 수 있다. 만약 두 개 이상의 key에 대해서 데이터가 준비되면, 앞에 있는 하나의 key만 반환한다. 예를들어 BLPOP key1 key2 key3 key 4를 수행하고 key2와 key4에 데이터가 준비됐다면, key2만 반환한다. 한 번더 BLPOP를 수행해야지 key4 값을 가져올 수 있을 것이라고 생각할 수 있겠지만, 그 사이에 key1과 key2에 데이터가 준비된다면, 역시 뒤로 밀릴 것이다. 재수 없으면 오랜 시간 밀릴 수 있다. 주의해서 사용해야 한다.

두 개 이상의 클라이언트가 하나의 키에 대해서 BLPOP 연산을 수행할 수 있다. 데이터를 얻어서 unblock 하고, 다시 BLPOP를 호출할 경우 가장 낮은 priority를 가진다. 클라이언트에 적절히 데이터가 분산된다는 의미다.

LPUSH를 이용해서 두 개 이상의 데이터를 밀어 넣을 수 있다. REDIS 2.6이상 버전의 경우 리스트에는 c, b, a로 쌓이고, BLPOP를 수행하면 c를 가져오게 된다. 2.4 미만버전이라면 a를 먼저 가져오게 된다.

예제

> del list1 list2
(integer) 0
> RPUSH list1 a b c
(integer) 3
> BLPOP list1 list2 0
1) "list1"
2) "a"
> BLPOP list1 list2 0
1) "list1"
2) "b"
> BLPOP list1 list2 0
1) "list1"
2) "c"

응용 패턴 : Event notification

Redis SET 데이터를 기다리는 클라이언트가 있다고 가정해 보자. 이 클라이언트는 무한 루프를 돌면서 SPOP연산을 수행 할건데, SPOP는 블록킹 연산을 지원하지 않는다. BRPOP를 조합하면 블록킹 모드로 작동하도록 만들 수 있다.

클라이언트의 의사코드다.
LOOP forever
    WHILE SPOP(key) returns elements
        ... elements에 대한 연산을 한다 ...
    END
    BRPOP helper_key
END

서버측 의사코드다.
MULTI
SADD key element
LPUSH helper_key x
EXEC