ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Key notification
    개발하면서/코드보면서 2013.02.12 23:42

    이 기능은 2013년 1월달에 unstable로 merge되었습니다.

    https://github.com/antirez/redis/commit/4cdbce341ebff64d392a42011f4a9258f8aa834f#src


    처음 시작할때는 2.6으로 했는데 하;;; 시간을 너무 끌었네요. 뭐든지 한번할때 왕창해야겠어요.

    간단하게 말하면, 이 기능의 요지는 key가 추가/수정/삭제가 되었을때 이벤트를 잡아서

    client한테 알려주는것입니다


    슬기로운 antirez는 redis에 있는 기능을 이용해서  간단하게 구현을 했습니다.

    이 글을 보시기전에 Pub/Sub을 보시고 오시면 더 좋겠습니다.


    key에 대해 이벤트(추가/수정/삭제)가 발생하면, 어떤키인지, 그리고 어떤 이벤트인지 두가지로 나뉩니다.
    체널명을

    __keyspace@[dbid]__:[key name] [event name], __keyevent@[dbid]__:[event name] [key name] 로 생성합니다.


    또 재미있는건 모든 자료구조(+ expire, evicted, generic)마다 flag를 두었다는 점입니다.
    redis.conf를 보면 아래 flag가 있습니다

    #  K     Keyspace events, published with __keyspace@<db>__ prefix.
    #  E     Keyevent events, published with __keyevent@<db>__ prefix.
    #  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
    #  $     String commands
    #  l     List commands
    #  s     Set commands
    #  h     Hash commands
    #  z     Sorted set commands
    #  x     Expired events (events generated every time a key expires)
    #  e     Evicted events (events generated when a key is evicted for maxmemory)
    #  A     Alias for g$lshzxe, so that the "AKE" string means all the events.


    redis.h

    /* Keyspace changes notification classes. Every class is associated with a
     * character for configuration purposes. */
    #define REDIS_NOTIFY_KEYSPACE (1<<0)    /* K */
    #define REDIS_NOTIFY_KEYEVENT (1<<1)    /* E */
    #define REDIS_NOTIFY_GENERIC (1<<2)     /* g */
    #define REDIS_NOTIFY_STRING (1<<3)      /* $ */
    #define REDIS_NOTIFY_LIST (1<<4)        /* l */
    #define REDIS_NOTIFY_SET (1<<5)         /* s */
    #define REDIS_NOTIFY_HASH (1<<6)        /* h */
    #define REDIS_NOTIFY_ZSET (1<<7)        /* z */
    #define REDIS_NOTIFY_EXPIRED (1<<8)     /* x */
    #define REDIS_NOTIFY_EVICTED (1<<9)     /* e */
    #define REDIS_NOTIFY_ALL (REDIS_NOTIFY_GENERIC | REDIS_NOTIFY_STRING | REDIS_NOTIFY_LIST |

    REDIS_NOTIFY_SET | REDIS_NOTIFY_HASH | REDIS_NOTIFY_ZSET |

    REDIS_NOTIFY_EXPIRED | REDIS_NOTIFY_EVICTED)      /* A */


    K, E는 위에서 말한 두가지이고, 'g$lshzxeA' 문자열을 가지고 골라먹는 재미가있습니다.

    [K | E | KE][g, $, L, s, h, z, x, e | A]


    하나 의문점이 드는게 있습니다. g의 expire와 x의 expire는 왜 두개나 있지? hdel을 하면 g에 걸리는거여,
    h에 걸리는거여?  등 중복될것같은 생각이 들었습니다.


    코드를 보면, expire명령어를 실행하면 g, expire가 되서 key가 지워지면 x,

    hash에 item이 지워지면 h, db의 key자체가 지워지면 g입니다.

    그리고 redis.io에서 얘기한게, 있지도 않은 키에대한 수정/삭제는 이벤트가 발생하지 않습니다.


    key가 추가/수정/삭제시 위의 flag랑 이벤트명, key명을 가지고 호출하는 함수는 notifyKeyspaceEvent 입니다.



    자 이젠 이 알람을 subscribe하면 됩니다
    redis.io 문서에서는 아래와 같이 하라고 합니다.

    $ redis-cli config set notify-keyspace-events KEA
    $ redis-cli --csv psubscribe '__key*__:*'
    Reading messages... (press Ctrl-C to quit)
    "psubscribe","__key*__:*",1


    성능은.....아무래도 느려지긴 할것 같습니다. 특히 __key*__:* 가......덜덜

    TAG

    댓글 0

Designed by Tistory.