anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

REDIS (6549B)

      1 Starting in Anope 1.9.9, Anope has Redis database support (https://redis.io/).
      2 This document explains the data structure used by Anope, and explains how
      3 keyspace notification works.
      4 
      5 This is not a tutorial on how to use Redis, see https://redis.io/documentation
      6 for that.
      7 
      8 Table of Contents
      9 -----------------
     10 1) Data structure
     11 2) Keyspace notifications
     12 3) Examples of modifying, deleting, and creating objects
     13 
     14 1) Data structure
     15 
     16     There are 4 key namespaces in Anope, they are:
     17 
     18         id -    The keys in id are used to atomically create object ids for new
     19                 objects. For example, if I were to create a new BotInfo I would first:
     20 
     21                 redis 127.0.0.1:6379> INCR id:BotInfo
     22 
     23                 To get the object ID of the new object.
     24 
     25         ids -   The keys in ids contain a set of all object ids of the given type.
     26                 For example:
     27 
     28                 redis 127.0.0.1:6379> SMEMBERS ids:BotInfo
     29 
     30                 Returns "1", "2", "3", "4", "5", "6", "7", "8" because I have 8 bots that
     31                 have IDs 1, 2, 3, 4, 5, 6, 7, and 8, respectively.
     32 
     33         hash -  The keys in hash are the actual objects, stored as hashes. For
     34                 example, if I had just looked up all BotInfo ids and wanted to iterate
     35                 over all of them, I would start by:
     36 
     37                 redis 127.0.0.1:6379> HGETALL hash:BotInfo:1
     38 
     39                 Which gets all keys and values from the hash of type BotInfo with id 1.
     40                 This may return:
     41 
     42                 "nick" -> "BotServ"
     43                 "user" -> "services"
     44                 "host" -> "services.anope.org"
     45                 "created" -> "1368704765"
     46 
     47         value - The keys in value only exist to aid looking up object IDs. They
     48                 are sets of object IDs and are used to map key+value pairs to objects.
     49                 For example:
     50 
     51                 redis 127.0.0.1:6379> SMEMBERS value:NickAlias:nick:Adam
     52 
     53                 Returns a set of object ids of NickAlias objects that have the key
     54                 'nick' set to the value 'Adam' in its hash. Clearly this can only
     55                 ever contain at most one object, since it is not possible to have
     56                 more than one registered nick with the same name, but other keys
     57                 will contain more than one, such as:
     58 
     59                 redis 127.0.0.1:6379> SMEMBERS value:NickCore:email:adam@anope.org
     60 
     61                 Which would return all accounts with the email "adam@anope.org".
     62 
     63                 redis 127.0.0.1:6379> SMEMBERS value:ChanAccess:mask:Adam
     64 
     65                 Which would return all access entries set on the account "Adam".
     66 
     67                 Behavior similar to SQL's AND, can be achieved using the
     68                 SINTER command, which does set intersection on one or more sets.
     69 
     70 2) Keyspace notifications
     71 
     72     Redis 2.7 (unstable) and 2.8 (stable) and newer support keyspace notifications
     73     (https://redis.io/topics/notifications). This allows Redis to notify Anope of
     74     any external changes to objects in the database. Once notified, Anope will
     75     immediately update the object. Otherwise, Anope keeps all objects in memory
     76     and will not regularly read from the database once started.
     77 
     78     You can use this to modify objects in Redis and have them immediately reflected
     79     back into Anope. Additionally you can use this feature to run multiple Anope
     80     instances simultaneously from the same database (see also, Redis database
     81     replication).
     82 
     83     To use keyspace notifications you MUST execute
     84 
     85     redis 127.0.0.1:6379> CONFIG SET notify-keyspace-events KA
     86     OK
     87 
     88     or set notify-keyspace-events in redis.conf properly. Anope always executes
     89     CONFIG SET when it first connects.
     90 
     91     If you do not enable keyspace events properly Anope will be UNABLE to see any
     92     object modifications you do.
     93 
     94     The key space ids and value are managed entirely by Anope, you do
     95     not (and should not) modify them. Once you modify the object (hash), Anope will
     96     update them for you to correctly reflect any changes made to the object.
     97 
     98     Finally, always use atomic operations. If you are inserting a new object with
     99     multiple commands, or inserting multiple objects at once, specifically if the
    100     objects depend on each other, you MUST use a transaction.
    101 
    102 3) Examples of modifying, deleting, and creating objects
    103 
    104    These examples will ONLY work if you meet the criteria in section 2.
    105 
    106     If I want to change the email account 'Adam' to 'Adam@anope.org', I would execute the following:
    107 
    108         redis 127.0.0.1:6379> SMEMBERS value:NickCore:display:Adam
    109 
    110         Which returns a value of "1", which is the object id I want to modify.
    111         Now to change the email:
    112 
    113         redis 127.0.0.1:6379> HSET hash:NickCore:1 email Adam@anope.org
    114 
    115         You can now see this in NickServ's INFO command:
    116         -NickServ-   Email address: Adam@anope.org
    117 
    118    If I want to drop the account "Adam", I would execute the following:
    119 
    120         redis 127.0.0.1:6379> SMEMBERS value:NickCore:display:Adam
    121 
    122         Which returns a value of "1". I would then check:
    123 
    124         redis 127.0.0.1:6379> SMEMBERS value:NickAlias:nc:Adam
    125 
    126         To see what nicknames depend on this account to exist, as I will
    127         have to remove those too. This returns the values "2", and "3".
    128 
    129         Finally, I can drop the nick using a transaction via:
    130 
    131         redis 127.0.0.1:6379> MULTI
    132         OK
    133         redis 127.0.0.1:6379> DEL hash:NickAlias:2
    134         QUEUED
    135         redis 127.0.0.1:6379> DEL hash:NickAlias:3
    136         QUEUED
    137         redis 127.0.0.1:6379> DEL hash:NickCore:1
    138         QUEUED
    139         redis 127.0.0.1:6379> EXEC
    140 
    141         Or alternatively simply:
    142 
    143         redis 127.0.0.1:6379> DEL hash:NickAlias:2 hash:NickAlias:3 hash:NickCore:1
    144 
    145   If I wanted to create a BotServ bot, I would execute the following:
    146 
    147         redis 127.0.0.1:6379> INCR id:BotInfo
    148 
    149         Which returns a new object ID for me, in this example it will be "8".
    150         Now I can create the object:
    151 
    152         HMSET hash:BotInfo:8 nick redis user redis host services.anope.org realname "Services for IRC Networks"
    153 
    154         Note if you are using HSET instead of HMSET you will need to use a transaction, as shown in the above example.
    155         If you are watching your services logs you will immediately see:
    156 
    157         USERS: redis!redis@services.anope.org (Services for IRC Networks) connected to the network (services.anope.org)
    158 
    159         And the bot redis will be in BotServ's bot list.
    160         Notice how ids:BotInfo and the value keys are updated automatically.