1 #ifndef __REDIS_CLUSTER_H 2 #define __REDIS_CLUSTER_H 3 4 /*----------------------------------------------------------------------------- 5 * Redis cluster data structures, defines, exported API. 6 *----------------------------------------------------------------------------*/ 7 8 #define REDIS_CLUSTER_SLOTS 16384 9 #define REDIS_CLUSTER_OK 0 /* Everything looks ok */ 10 #define REDIS_CLUSTER_FAIL 1 /* The cluster can't work */ 11 #define REDIS_CLUSTER_NAMELEN 40 /* sha1 hex length */ 12 #define REDIS_CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ 13 #define REDIS_CLUSTER_IPLEN INET6_ADDRSTRLEN /* IPv6 address string length */ 14 15 /* The following defines are amunt of time, sometimes expressed as 16 * multiplicators of the node timeout value (when ending with MULT). */ 17 #define REDIS_CLUSTER_DEFAULT_NODE_TIMEOUT 15000 18 #define REDIS_CLUSTER_FAIL_REPORT_VALIDITY_MULT 2 /* Fail report validity. */ 19 #define REDIS_CLUSTER_FAIL_UNDO_TIME_MULT 2 /* Undo fail if master is back. */ 20 #define REDIS_CLUSTER_FAIL_UNDO_TIME_ADD 10 /* Some additional time. */ 21 #define REDIS_CLUSTER_SLAVE_VALIDITY_MULT 10 /* Slave data validity. */ 22 #define REDIS_CLUSTER_FAILOVER_AUTH_RETRY_MULT 4 /* Auth request retry time. */ 23 #define REDIS_CLUSTER_FAILOVER_DELAY 5 /* Seconds */ 24 #define REDIS_CLUSTER_DEFAULT_MIGRATION_BARRIER 1 25 #define REDIS_CLUSTER_MF_TIMEOUT 5000 /* Milliseconds to do a manual failover. */ 26 #define REDIS_CLUSTER_MF_PAUSE_MULT 2 /* Master pause manual failover mult. */ 27 28 struct clusterNode; 29 30 /* clusterLink encapsulates everything needed to talk with a remote node. */ 31 typedef struct clusterLink { 32 mstime_t ctime; /* Link creation time */ 33 int fd; /* TCP socket file descriptor */ 34 sds sndbuf; /* Packet send buffer */ 35 sds rcvbuf; /* Packet reception buffer */ 36 struct clusterNode *node; /* Node related to this link if any, or NULL */ 37 } clusterLink; 38 39 /* Cluster node flags and macros. */ 40 #define REDIS_NODE_MASTER 1 /* The node is a master */ 41 #define REDIS_NODE_SLAVE 2 /* The node is a slave */ 42 #define REDIS_NODE_PFAIL 4 /* Failure? Need acknowledge */ 43 #define REDIS_NODE_FAIL 8 /* The node is believed to be malfunctioning */ 44 #define REDIS_NODE_MYSELF 16 /* This node is myself */ 45 #define REDIS_NODE_HANDSHAKE 32 /* We have still to exchange the first ping */ 46 #define REDIS_NODE_NOADDR 64 /* We don't know the address of this node */ 47 #define REDIS_NODE_MEET 128 /* Send a MEET message to this node */ 48 #define REDIS_NODE_PROMOTED 256 /* Master was a slave propoted by failover */ 49 #define REDIS_NODE_NULL_NAME "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" 50 51 #define nodeIsMaster(n) ((n)->flags & REDIS_NODE_MASTER) 52 #define nodeIsSlave(n) ((n)->flags & REDIS_NODE_SLAVE) 53 #define nodeInHandshake(n) ((n)->flags & REDIS_NODE_HANDSHAKE) 54 #define nodeHasAddr(n) (!((n)->flags & REDIS_NODE_NOADDR)) 55 #define nodeWithoutAddr(n) ((n)->flags & REDIS_NODE_NOADDR) 56 #define nodeTimedOut(n) ((n)->flags & REDIS_NODE_PFAIL) 57 #define nodeFailed(n) ((n)->flags & REDIS_NODE_FAIL) 58 59 /* This structure represent elements of node->fail_reports. */ 60 struct clusterNodeFailReport { 61 struct clusterNode *node; /* Node reporting the failure condition. */ 62 mstime_t time; /* Time of the last report from this node. */ 63 } typedef clusterNodeFailReport; 64 65 struct clusterNode { 66 mstime_t ctime; /* Node object creation time. */ 67 char name[REDIS_CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ 68 int flags; /* REDIS_NODE_... */ 69 uint64_t configEpoch; /* Last configEpoch observed for this node */ 70 unsigned char slots[REDIS_CLUSTER_SLOTS/8]; /* slots handled by this node */ 71 int numslots; /* Number of slots handled by this node */ 72 int numslaves; /* Number of slave nodes, if this is a master */ 73 struct clusterNode **slaves; /* pointers to slave nodes */ 74 struct clusterNode *slaveof; /* pointer to the master node */ 75 mstime_t ping_sent; /* Unix time we sent latest ping */ 76 mstime_t pong_received; /* Unix time we received the pong */ 77 mstime_t fail_time; /* Unix time when FAIL flag was set */ 78 mstime_t voted_time; /* Last time we voted for a slave of this master */ 79 mstime_t repl_offset_time; /* Unix time we received offset for this node */ 80 long long repl_offset; /* Last known repl offset for this node. */ 81 char ip[REDIS_IP_STR_LEN]; /* Latest known IP address of this node */ 82 int port; /* Latest known port of this node */ 83 clusterLink *link; /* TCP/IP link with this node */ 84 list *fail_reports; /* List of nodes signaling this as failing */ 85 }; 86 typedef struct clusterNode clusterNode; 87 88 typedef struct clusterState { 89 clusterNode *myself; /* This node */ 90 uint64_t currentEpoch; 91 int state; /* REDIS_CLUSTER_OK, REDIS_CLUSTER_FAIL, ... */ 92 int size; /* Num of master nodes with at least one slot */ 93 dict *nodes; /* Hash table of name -> clusterNode structures */ 94 dict *nodes_black_list; /* Nodes we don't re-add for a few seconds. */ 95 clusterNode *migrating_slots_to[REDIS_CLUSTER_SLOTS]; 96 clusterNode *importing_slots_from[REDIS_CLUSTER_SLOTS]; 97 clusterNode *slots[REDIS_CLUSTER_SLOTS]; 98 zskiplist *slots_to_keys; 99 /* The following fields are used to take the slave state on elections. */ 100 mstime_t failover_auth_time; /* Time of previous or next election. */ 101 int failover_auth_count; /* Number of votes received so far. */ 102 int failover_auth_sent; /* True if we already asked for votes. */ 103 int failover_auth_rank; /* This slave rank for current auth request. */ 104 uint64_t failover_auth_epoch; /* Epoch of the current election. */ 105 /* Manual failover state in common. */ 106 mstime_t mf_end; /* Manual failover time limit (ms unixtime). 107 It is zero if there is no MF in progress. */ 108 /* Manual failover state of master. */ 109 clusterNode *mf_slave; /* Slave performing the manual failover. */ 110 /* Manual failover state of slave. */ 111 long long mf_master_offset; /* Master offset the slave needs to start MF 112 or zero if stil not received. */ 113 int mf_can_start; /* If non-zero signal that the manual failover 114 can start requesting masters vote. */ 115 /* The followign fields are uesd by masters to take state on elections. */ 116 uint64_t last_vote_epoch; /* Epoch of the last vote granted. */ 117 int todo_before_sleep; /* Things to do in clusterBeforeSleep(). */ 118 long long stats_bus_messages_sent; /* Num of msg sent via cluster bus. */ 119 long long stats_bus_messages_received; /* Num of msg rcvd via cluster bus.*/ 120 } clusterState; 121 122 /* clusterState todo_before_sleep flags. */ 123 #define CLUSTER_TODO_HANDLE_FAILOVER (1<<0) 124 #define CLUSTER_TODO_UPDATE_STATE (1<<1) 125 #define CLUSTER_TODO_SAVE_CONFIG (1<<2) 126 #define CLUSTER_TODO_FSYNC_CONFIG (1<<3) 127 128 /* Redis cluster messages header */ 129 130 /* Note that the PING, PONG and MEET messages are actually the same exact 131 * kind of packet. PONG is the reply to ping, in the exact format as a PING, 132 * while MEET is a special PING that forces the receiver to add the sender 133 * as a node (if it is not already in the list). */ 134 #define CLUSTERMSG_TYPE_PING 0 /* Ping */ 135 #define CLUSTERMSG_TYPE_PONG 1 /* Pong (reply to Ping) */ 136 #define CLUSTERMSG_TYPE_MEET 2 /* Meet "let's join" message */ 137 #define CLUSTERMSG_TYPE_FAIL 3 /* Mark node xxx as failing */ 138 #define CLUSTERMSG_TYPE_PUBLISH 4 /* Pub/Sub Publish propagation */ 139 #define CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST 5 /* May I failover? */ 140 #define CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 6 /* Yes, you have my vote */ 141 #define CLUSTERMSG_TYPE_UPDATE 7 /* Another node slots configuration */ 142 #define CLUSTERMSG_TYPE_MFSTART 8 /* Pause clients for manual failover */ 143 144 /* Initially we don't know our "name", but we'll find it once we connect 145 * to the first node, using the getsockname() function. Then we'll use this 146 * address for all the next messages. */ 147 typedef struct { 148 char nodename[REDIS_CLUSTER_NAMELEN]; 149 uint32_t ping_sent; 150 uint32_t pong_received; 151 char ip[16]; /* IP address last time it was seen */ 152 uint16_t port; /* port last time it was seen */ 153 uint16_t flags; 154 uint32_t notused; /* for 64 bit alignment */ 155 } clusterMsgDataGossip; 156 157 typedef struct { 158 char nodename[REDIS_CLUSTER_NAMELEN]; 159 } clusterMsgDataFail; 160 161 typedef struct { 162 uint32_t channel_len; 163 uint32_t message_len; 164 unsigned char bulk_data[8]; /* defined as 8 just for alignment concerns. */ 165 } clusterMsgDataPublish; 166 167 typedef struct { 168 uint64_t configEpoch; /* Config epoch of the specified instance. */ 169 char nodename[REDIS_CLUSTER_NAMELEN]; /* Name of the slots owner. */ 170 unsigned char slots[REDIS_CLUSTER_SLOTS/8]; /* Slots bitmap. */ 171 } clusterMsgDataUpdate; 172 173 union clusterMsgData { 174 /* PING, MEET and PONG */ 175 struct { 176 /* Array of N clusterMsgDataGossip structures */ 177 clusterMsgDataGossip gossip[1]; 178 } ping; 179 180 /* FAIL */ 181 struct { 182 clusterMsgDataFail about; 183 } fail; 184 185 /* PUBLISH */ 186 struct { 187 clusterMsgDataPublish msg; 188 } publish; 189 190 /* UPDATE */ 191 struct { 192 clusterMsgDataUpdate nodecfg; 193 } update; 194 }; 195 196 197 typedef struct { 198 char sig[4]; /* Siganture "RCmb" (Redis Cluster message bus). */ 199 uint32_t totlen; /* Total length of this message */ 200 uint16_t ver; /* Protocol version, currently set to 0. */ 201 uint16_t notused0; /* 2 bytes not used. */ 202 uint16_t type; /* Message type */ 203 uint16_t count; /* Only used for some kind of messages. */ 204 uint64_t currentEpoch; /* The epoch accordingly to the sending node. */ 205 uint64_t configEpoch; /* The config epoch if it's a master, or the last 206 epoch advertised by its master if it is a 207 slave. */ 208 uint64_t offset; /* Master replication offset if node is a master or 209 processed replication offset if node is a slave. */ 210 char sender[REDIS_CLUSTER_NAMELEN]; /* Name of the sender node */ 211 unsigned char myslots[REDIS_CLUSTER_SLOTS/8]; 212 char slaveof[REDIS_CLUSTER_NAMELEN]; 213 char notused1[32]; /* 32 bytes reserved for future usage. */ 214 uint16_t port; /* Sender TCP base port */ 215 uint16_t flags; /* Sender node flags */ 216 unsigned char state; /* Cluster state from the POV of the sender */ 217 unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ 218 union clusterMsgData data; 219 } clusterMsg; 220 221 #define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg)-sizeof(union clusterMsgData)) 222 223 /* Message flags better specify the packet content or are used to 224 * provide some information about the node state. */ 225 #define CLUSTERMSG_FLAG0_PAUSED (1<<0) /* Master paused for manual failover. */ 226 #define CLUSTERMSG_FLAG0_FORCEACK (1<<1) /* Give ACK to AUTH_REQUEST even if 227 master is up. */ 228 229 /* ---------------------- API exported outside cluster.c -------------------- */ 230 clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask); 231 232 #endif /* __REDIS_CLUSTER_H */ 233