Redis Server-assisted Client side caching

레디스 서버 교육 신청 레디스 정기점검/기술지원
Redis Technical Support
레디스 엔터프라이즈 서버
Redis Enterprise Server

Redis Server-assisted Client side caching

개요 槪要 Outline

레디스 서버는 고성능(high performance)입니다만, 클라이언트(애플리케이션)에서 필요할 때마다 매번 레디스 서버로 부터 가져오는 것보다 한번 가져온 데이터를 계속 사용할 수 있다면 훨씬 더 나은 성능을 제공할 수 있을 것입니다.   이 경우 해결해야 할 문제는 다른 클라이언트가 해당 데이터를 변경했을 때 클라이언트는 해당 데이터가 변경되었는지를 어떻게 아느냐하는 것입니다. 레디스 서버 입장에서는 변경된 데이터를 조회해서 가지고 있는 클라이언트들에게 데이터가 변경되었음을 알려주는 효율적인 방법이 있어야 합니다.
레디스는 pub/sub 기능을 이용해서 캐싱을 사용하는 클라이언트에 알림을 보냅니다.
이 기능은 버전 6.0부터 사용할 수 있습니다.

설명 說明 Explanation

클라이언트와 서버의 처리 절차를 설명합니다.
  1. 클라이언트는 캐시를 시작한다고 서버에게 알린다.
    Client 4: client tracking on
  2. 서버는 클라이언트가 캐시를 시작했음을 기록한다.
    Server: tracking enable
  3. 클라이언트는 키 값이 변경되었을 때 알림을 받기 위해 subscribe 한다.
    Client 4: subscribe __redis__:invalidate   <- channel name
  4. 클라이언트가 읽기(조회) 명령을 실행한다.
    Client 4: get key (XXX)
  5. 서버는 명령이 읽기(조회)이고 클라이언트가 케시 중이면 서버는 해당 키를 기록한다.
    Server: remember client id, key
  6. 다른 클라이언트가 캐시하고 있는 키를 변경한다.
    Client 5: set key YYY
  7. 서버는 캐시하고 있는 키가 변경되었음을 인지하고 해당 키 값을 캐시하고 있는 클라이언트들에게 알림을 보낸다.
    Server: publish __redis__:invalidate (key hash value)
  8. 클라이언트는 해당 키 값이 변경되었다는 알림을 받고 적절한 처리를 한다.
    Client 4: get message invalidate (key hash value)

서버 내부 데이터 구조와 처리 방법

  • 서버는 1천6백만개(16,777,216)의 값을 가질 수 있는 TrackingTable(array)을 생성합니다. 이것은 메모리 128mb를 사용합니다. Info memory로 확인 가능.
  • 키에 CRC64(key)를 적용해서 16백만개 중 하나의 값을 얻습니다. 이 값이 100이면 TrackingTable[100]에 기수 트리(rax: radix tree) 데이터 구조를 만들고 client-id를 저장합니다. 키를 저장하지는 않습니다. 키는 CRC64() 값으로 대치되는 것입니다. 키의 CRC 값이 중복되지 않도록 큰 배열(16백만개)을 사용합니다.
  • 모든 키에 변경(write) 명령이 실행되면 slot=CRC64(key)를 이용해서 TrackingTable[slot] 확인해서 있으면 해당 클라이언트들에 메시지를 보내고 클라이언트들을 지웁니다. raxFree(TrackingTable[slot]).
  • 키를 저장하지 않는 이유: 키를 저장하면 그만큼 메모리가 소요됩니다. 키가 크다면 해당하는 큰 메모리가 필요합니다. 그러면 캐시되는 키 크기에 따라 레디스 서버는 많은 메모리를 사용하게 됩니다. 그래서 키를 저장하지 않고 기본 사용 메모리(128mb)에서 크게 증가하지 않도록 16백만개 배열을 사용하고 각 배열값에는 클라이언트 id만 저장합니다. 클라이언트 id는 숫자이므로 고정된 크기를 갖습니다.
  • 키를 저장하지 않아서 발생할 수 있는 문제점: key1와 key2가 같은 CRC값이 나온다면 같은 slot에 저장될 것이고 key1이 변경되었을 때 key2를 캐시하고 있는 클라이언트들도 변경 메시지를 받을 것이다. 그러나 배열 크기가 1천 6백만개이므로 이런 경우는 매우 드물게 발생할 것이고, 키를 저장함므로써 사용되는 메모리를 고려했을 때 적절한 방법이라고 생각된다.

Event Notification과 비교

  • "config set notify-keyspace-events KA"로 설정하면 모든 키 이벤트에 대해서 알림을 받을 수 있다.
  • 클라이언트는 "subscribe __keyspace@0__:key"를 실행하고, "get key"를 실행한다.
  • 다른 클라이언트에서 "set key YYY"를 실행하면, subscribe한 클라이언트 "__keyspace@0__key set" 메시지를 받는다.
  • 클라이언트는 "unsubscribe __keyspace@0__:key"를 실행한다.
  • 키를 사용할 때마다 subscribe와 unsubscribe를 해주어야 한다.

관련 정보

  • tracking-table-max-fill 10: redis.conf에 설정하는 파라이터이다. 슬롯 1천 6백만개 중 10%만 사용하도록 설정한다. 이것은 메모리를 너무 많이 사용하지 않도록 하는 조치이다. 10%를 초과하면 임의 슬롯 100개 씩 메모리를 해제한다. 물론 해당 슬롯의 클라이언트들에게는 알림을 보낸다.
    0으로 설정하면 슬롯 1천 6백만개를 모두 사용할 수 있다. 디폴트 값은 10이다.
  • flushdb 또는 flushall을 했을 경우 클라이언트는 -1 메시지를 받는다.
  • flushall이고 캐시하는 클라이언트가 없으면 TrackingTable이 사용하는 메모리를 해제합니다.

<< Event Notification Redis Server Threads >>

조회수 :

Email 답글이 올라오면 이메일로 알려드리겠습니다.