ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Redis] 데이터 타입 - Stream
    공부 이야기/REDIS 2024. 6. 6. 15:00

    1. Periodical Data를 취급할 때 효과적인 데이터 타입

    - Periodical Data는 연속적인 주기를 갖는 데이터를 맨 마지막에 추가하는 특징이 있다.

    - Redis Stream 은 Append-Only 방식이다. Redis 5.0 버전에서 List를 사용해 Periodical Data를 처리했다고 한다.

    2. Redis는 각 스트림 항목에 대해 고유 ID를 생성한다.

    3. XADD 명령어로 스트림 데이터를 생성할 수 있다.

    XADD race:france * rider Castilla speed 30.2 position 1 location_id 1
    "1692632086370-0" # 생성된 ID로 시간+일련번호로 구성
    res1 = r.xadd(
        "race:france",
        {"rider": "Castilla", "speed": 30.2, "position": 1, "location_id": 1},
    )
    print(res1)  # >>> 1692629576966-0

    - race:france 부모키에 자식값을 K-V 형태로 추가한 예시

    4. Redis Stream은 Radix-Tree 구조로 관리된다. 따라서 삽입 연산 수행시 O(1)이 아닌 O(logN)의 시간 복잡도를 갖는다.

    5. Radix-Tree는 같은 공통 접두사(prefix)를 갖는 ID들을 묶고 다른 부분을 하위에 두는 구조를 갖는다.

    Redis Stream 은 시간(정수 ID)를 갖는다.

    6. Redis Stream은 시간을 정수값으로 변환한 ID를 갖기 때문에 문자열 검색보다 빠르다.

    7. 또한 시간은 기본적으로 오름차순으로 자동 정렬되어 있기 때문에 범위 검색에서도 이점을 갖는다.

    8. O(1) 시간 복잡도를 갖는 List 보다 append 연산이 느릴 수 있어도 검색과 메모리 관리는 효율적이기 때문에 Periodical Data를 취급할 때 선호된다.

    9. XRANGE 명령어를 이용해 범위 탐색 연산을 수행한다.

    > XRANGE race:france 1692632086370-0 + COUNT 2
    1) 1) "1692632086370-0"
       2) 1) "rider"
          2) "Castilla"
          3) "speed"
          4) "30.2"
          5) "position"
          6) "1"
          7) "location_id"
          8) "1"
    2) 1) "1692632094485-0"
       2) 1) "rider"
          2) "Norem"
          3) "speed"
          4) "28.8"
          5) "position"
          6) "3"
          7) "location_id"
          8) "1"

    - race:france 키에 대해 ID 값이 1692632086370-0 이후 2개의 데이터를 반환한다.

    -  XRANGE 의 시간 복잡도는 O(log(N))이고 하위 M개의 요소를 반환하는 O(M)이 추가된다.

    10. XREAD 연산을 이용해서 중간에 데이터가 UPDATE, INSERT 되는 것을 방지하는 Block 연산을 수행한다.

    > XREAD COUNT 100 BLOCK 300 STREAMS race:france $
    (nil)

    - 스트림 끝에서 시작하여 최대 100개의 새 스트림 항목을 읽고 항목이 기록되지 않는 경우 최대 300ms 동안 차단

    - Block 연산은 다른 클라이언트 요청의 동시성을 제한할 수 있기 때문에 최대 조회 시간을 지정해주는 것이 좋다.

    11. Redis Stream은 SCAN 연산을 지원하지 않는다. XRANGE 범위 연산은 6~7에서 말한 듯 매우 빠르게 진행되기 때문이다.

    12. 범위 탐색을 하는 동안은 다른 클라이언트 요청을 처리할 수 없지만, 결과를 반환하는 동안에는 다른 클라이언트 요청을 처리할 수 있다.

    13. 물론 범위가 무진장 크면 데이터베이스 응답이 지연될 수 있다.

    14. List에 비해 조회 연산이 빠르고, Sorted Set과는 다르게 중복 데이터를 구분할 수 있는 일련번호를 자동으로 만들어주고, Hash와 다르게 정렬된 데이터를 반환해준다는 점에서 적절한 상황에 사용한다면 매우 효과적일 수 있다.

    15. Consumer Group

    - Stream을 pub/sub 구조의 메시지 큐처럼 사용할 수 있다.

    - 컨슈머 를 지정해서 데이터를 읽을 수 있고, 컨슈머가 읽은 데이터를 제대로 처리했는지 확인할 수 있고(XACK), 만약 제대로 처리하지 못했다면 다른 컨슈머에게 할당해서 처리하는 방법(XCLAIM)을 제공한다.

    16. XGROUP 명령은 다음과 같은 기능이 있다.

    • 컨슈머 그룹 만들기
    • 컨슈머 그룹 삭제하기
    • 컨슈머  삭제하기
    • ID 재지정하기

    - 여러 컨슈머가 동일한 스트림/토픽에서 메시지를 병렬로 처리

    - 부하 분산과 내결함성을 위해 컨슈머 그룹을 사용

Designed by Tistory.