ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Redis] 복수 개의 명령어를 한 번에 처리하는 Command - MULTI, EXEC, DISCARD, WATCH
    공부 이야기/REDIS 2024. 6. 9. 17:38

    1. Redis는 Spring JPA의 Transactional 기능처럼 여러 개의 연속된 명령어를 하나의 명령어로 묶는 기능을 지원한다.

    2. 하나로 묶으면 중간에 다른 클라이언트의 요청을 차단할 수 있다.

    3. ACID의 원자성을 높일 수 있는 방법이지만 싱글 쓰레드 기반의 Redis에서는 신중하게 써야할 것 같다.

    4. 명령어

    > MULTI
    OK
    > INCR foo
    QUEUED
    > INCR bar
    QUEUED
    > EXEC
    1) (integer) 1
    2) (integer) 1

    - 시작은 MULTI 명령어로 시작한다. Redis 서버는 OK를 응답한다.

    - 지정한 명령어를 순차적으로 수행한다. Redis 서버는 Queued를 응답한다. 큐에 추가했다는 의미인 듯하다.

    - EXEC 명령어로 큐에 저장한 명령어를 호출한다. Redis 서버는 배열 형태로 응답을 반환하며, 각 요소는 트랜잭션 내의 단일 명령에 대한 응답이다.

    5. 트랜잭션 중에는 두 가지 유형의 명령 오류가 발생할 수 있다.

    - 명령이 큐에 추가되지 못할 수 있다. 이는 EXEC가 호출되기 에 오류가 발생한다. 예를 들어, 명령이 문법적으로 잘못되었거나 (매개변수 수가 잘못되었거나, 잘못된 명령 이름 등), 메모리 부족 등의 심각한 조건이 발생 (서버가 maxmemory 지시어로 메모리 제한을 설정한 경우).

    - EXEC가 호출된 명령이 실패할 수 있다. 예를 들어, 잘못된 값 유형의 키에 대해 작업을 수행한 경우 (예: 문자열 값에 대해 리스트 작업을 호출한 경우).

    - 명령어 수행 중 실패 예시. EXEC 호출 후 세 번째 OP에 대한 에러 메시지를 보여준다.

    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    MULTI
    +OK
    SET a abc
    +QUEUED
    LPOP a
    +QUEUED
    EXEC
    *2
    +OK
    -WRONGTYPE Operation against a key holding the wrong kind of value

    6. Redis 2.6.5부터는 명령 누적 중 오류를 감지하고, EXEC 동안 오류를 반환하여 트랜잭션을 실행하지 않고 버림

    7. Redis는 트랜잭션 롤백 기능을 지원해주지 않는다. 기능 구현이 복잡하기 때문이다. (RDBMS와의 차이점)

    8. 명령어 집합 중에서 하나의 명령어가 실패해도 다른 명령어는 수행된다는 뜻이다.

    9. 7번, 8번의 이유 때문에 트랜잭션 처리는 RDBMS를 사용하거나 서버 프로그램에서 구현(관리)하는 것이 효과적으로 보인다.

    10. DISCARD

    > SET foo 1
    OK
    > MULTI
    OK
    > INCR foo
    QUEUED
    > DISCARD
    OK
    > GET foo
    "1"

    - 큐에 추가하는 도중, DISCARD 명령어를 수행하면 모든 명령어 수행을 취소한다.

    - 트랜잭션 원자성을 구현하기 위해서 명령어 하나씩 수행하면서 QUEUED 응답을 받으면 넘어가고 그렇지 않은 경우 DISCARD 명령어를 호출하는 방식을 사용할 수는 있다.

    - 하지만 이 방식을 사용하면 굳이 트랜잭션을 하나로 묶었던 수고와 편리성을 포기하는 셈이다.

    11. WATCH

    - EXEC를 조건부로 만드는 명령어로 Redis에게 WATCH된 키가 수정되지 않은 경우에만 트랜잭션을 수행하도록 요청한다.

    - 낙관적 잠금에 사용한다.

    WATCH mykey
    val = GET mykey
    val = val + 1
    MULTI
    SET mykey $val
    EXEC

    - mykey 키에 다른 사용자에 의해 값이 수정되면 MULTI~EXEC 명령은 호출되지 않는다.

    - mykey 키를 수정하기 위해서 먼저 락 획득 및 잠금을 하는 방법(비관적 잠금)이 일반적인데 위 방식을 사용하면 동시성을 높이면서 데이터 정합성을 지킬 수 있다.

    12. MULTI/EXEC 내부에서 사용되는 키는 expire 될 수 있다.

    13. EXPIRE 키 카운터수 명령어로 retention을 재조정할 수 있다.

Designed by Tistory.