All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Macros | Typedefs | Enumerations | Functions
cluster.c File Reference
#include "redis.h"
#include "cluster.h"
#include "crc16.h"
#include <freeradius-devel/rad_assert.h>
+ Include dependency graph for cluster.c:

Go to the source code of this file.

Data Structures

struct  cluster_key_slot
 Indexes in the cluster_node_t array for a single key slot. More...
 
struct  cluster_node_conf
 Configuration for a single node. More...
 
struct  cluster_nodes_live
 Live nodes data, used to perform weighted random selection of alternative nodes. More...
 
struct  cluster_nodes_live.node
 
struct  fr_redis_cluster
 A redis cluster. More...
 
struct  fr_redis_cluster_node
 A Redis cluster node. More...
 

Macros

#define CLOSED_PERIOD   10000
 How recently must the closed have. More...
 
#define CLOSED_WEIGHT   1
 What weight to give to nodes that. More...
 
#define FAILED_PERIOD   10000
 How recently must the spawn failure. More...
 
#define FAILED_WEIGHT   1
 What weight to give to nodes that. More...
 
#define KEY_SLOTS   16384
 Maximum number of keyslots (should not change). More...
 
#define MAX_SLAVES   5
 Maximum number of slaves associated. More...
 
#define pthread_mutex_destroy(_x)
 
#define pthread_mutex_init(_x, _y)
 
#define pthread_mutex_lock(_x)
 
#define pthread_mutex_unlock(_x)
 
#define RELEASED_MIN_WEIGHT   1000
 Minimum weight to assign to node. More...
 
#define RELEASED_PERIOD   10000
 Period after which we don't care. More...
 
#define SET_ACTIVE(_node)
 
#define SET_ADDR(_addr, _map)
 
#define SET_INACTIVE(_node)
 

Typedefs

typedef struct cluster_key_slot cluster_key_slot_t
 Indexes in the cluster_node_t array for a single key slot. More...
 
typedef struct cluster_node_conf cluster_node_addr_t
 Configuration for a single node. More...
 
typedef struct
fr_redis_cluster_node 
cluster_node_t
 A Redis cluster node. More...
 
typedef struct cluster_nodes_live cluster_nodes_live_t
 Live nodes data, used to perform weighted random selection of alternative nodes. More...
 

Enumerations

enum  cluster_rcode_t {
  CLUSTER_OP_IGNORED = 1,
  CLUSTER_OP_SUCCESS = 0,
  CLUSTER_OP_FAILED = -1,
  CLUSTER_OP_NO_CONNECTION = -2,
  CLUSTER_OP_BAD_INPUT = -3
}
 Return values for internal functions. More...
 

Functions

static int _cluster_conn_free (fr_redis_conn_t *conn)
 Callback for freeing a Redis connection. More...
 
static int _cluster_node_cmp (void const *a, void const *b)
 Compare two redis nodes to check equality. More...
 
static void _cluster_node_conf_apply (void *opaque)
 Reconnect callback to apply new pool config. More...
 
static int _cluster_pool_walk (void *context, void *data)
 Walk all used pools adding them to the live node list. More...
 
static int _cluster_version_walk (void *context, void *data)
 Walk all used pools checking their versions. More...
 
static uint16_t cluster_key_hash (uint8_t const *key, size_t key_len)
 Resolve key to key slot. More...
 
static cluster_rcode_t cluster_map_apply (fr_redis_cluster_t *cluster, redisReply *reply)
 Apply a cluster map received from a cluster node. More...
 
static cluster_rcode_t cluster_map_get (redisReply **out, fr_redis_conn_t *conn)
 Learn a new cluster layout by querying the node that issued the -MOVE. More...
 
static int cluster_map_node_validate (redisReply *node, int map_idx, int node_idx)
 Validate a cluster map node entry. More...
 
static cluster_rcode_t cluster_node_conf_from_redirect (uint16_t *key_slot, cluster_node_addr_t *node_addr, redisReply *redirect)
 Parse a -MOVED or -ASK redirect. More...
 
static cluster_rcode_t cluster_node_connect (fr_redis_cluster_t *cluster, cluster_node_t *node)
 Establish a connection to a cluster node. More...
 
static int cluster_node_find_live (cluster_node_t **live_node, fr_redis_conn_t **live_conn, REQUEST *request, fr_redis_cluster_t *cluster, cluster_node_t *skip)
 Attempt to find a live pool in the cluster. More...
 
static cluster_rcode_t cluster_node_ping (REQUEST *request, cluster_node_t *node, fr_redis_conn_t *conn)
 Issue a ping request against a cluster node. More...
 
static int cluster_node_pool_health (struct timeval const *now, fr_connection_pool_state_t const *state)
 Try to determine the health of a cluster node passively by examining its pool state. More...
 
static cluster_rcode_t cluster_redirect (cluster_node_t **out, fr_redis_cluster_t *cluster, redisReply *reply)
 Retrieve or associate a node with the server indicated in the redirect. More...
 
static cluster_rcode_t cluster_remap (REQUEST *request, fr_redis_cluster_t *cluster, fr_redis_conn_t *conn)
 Perform a runtime remap of the cluster. More...
 
static cluster_key_slot_tcluster_slot_by_key (fr_redis_cluster_t *cluster, REQUEST *request, uint8_t const *key, size_t key_len)
 Implements the key slot selection scheme used by freeradius. More...
 
fr_redis_cluster_tfr_redis_cluster_alloc (TALLOC_CTX *ctx, CONF_SECTION *module, fr_redis_conf_t *conf)
 Allocate and initialise a new cluster structure. More...
 
void * fr_redis_cluster_conn_create (TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
 Create a new connection to a Redis node. More...
 
bool fr_redis_cluster_min_version (fr_redis_cluster_t *cluster, char const *min_version)
 Check if members of the cluster are above a certain version. More...
 
int fr_redis_cluster_pool_by_node_addr (fr_connection_pool_t **pool, fr_redis_cluster_t *cluster, fr_ipaddr_t *ipaddr, uint16_t port, bool create)
 Get the pool associated with a node in the cluster. More...
 
fr_redis_rcode_t fr_redis_cluster_state_init (fr_redis_cluster_state_t *state, fr_redis_conn_t **conn, fr_redis_cluster_t *cluster, REQUEST *request, uint8_t const *key, size_t key_len, bool read_only)
 Resolve a key to a pool, and reserve a connection in that pool. More...
 
fr_redis_rcode_t fr_redis_cluster_state_next (fr_redis_cluster_state_t *state, fr_redis_conn_t **conn, fr_redis_cluster_t *cluster, REQUEST *request, fr_redis_rcode_t status, redisReply **reply)
 Get the next connection to attempt a command against. More...
 

Data Structure Documentation

struct cluster_key_slot

Indexes in the cluster_node_t array for a single key slot.

When dealing with 16K entries, space is a concern. It's significantly more memory efficient to use 8bit indexes than 64bit pointers for each of the key slot to node mappings.

Definition at line 244 of file cluster.c.

Data Fields
uint8_t master R/W node (master) for this key slot.
uint8_t slave[MAX_SLAVES] R/O node (slave) for this key slot.
uint8_t slave_num Number of slaves associated with this key slot.
struct cluster_node_conf

Configuration for a single node.

Definition at line 214 of file cluster.c.

+ Collaboration diagram for cluster_node_conf:
Data Fields
fr_ipaddr_t ipaddr IP Address of Redis cluster node.
uint16_t port Port of Redis cluster node.
struct cluster_nodes_live

Live nodes data, used to perform weighted random selection of alternative nodes.

Definition at line 202 of file cluster.c.

Data Fields
uint8_t next Next index in live.
struct cluster_nodes_live node[UINT8_MAX-1] Array of live node IDs (and weights).
uint8_t skip
struct cluster_nodes_live.node

Definition at line 203 of file cluster.c.

Data Fields
unsigned int cumulative Cumulative weight.
uint8_t id Node ID.
fr_connection_pool_state_t const * pool_state Connection pool stats.
struct fr_redis_cluster

A redis cluster.

Holds all the structures and collections of nodes, to represent a Redis cluster.

Definition at line 254 of file cluster.c.

+ Collaboration diagram for fr_redis_cluster:
Data Fields
fr_redis_conf_t * conf Base configuration data such as the database number and passwords.
fr_fifo_t * free_nodes Queue of free nodes (or nodes waiting to be reused).
cluster_key_slot_t key_slot[KEY_SLOTS] Lookup table of slots to pools.
cluster_key_slot_t key_slot_pending[KEY_SLOTS] Pending key slot table.
time_t last_updated Last time the cluster mappings were updated.
CONF_SECTION * module Module configuration.
cluster_node_t * node Structure containing a node id, its address and a pool of its connections.
bool remap_needed Set true if at least one cluster node is definitely unreachable.

Set false on successful remap.

bool remapping True when cluster is being remapped.
rbtree_t * used_nodes Tree of used nodes.
struct fr_redis_cluster_node

A Redis cluster node.

Passed as opaque data to pools which open connection to nodes.

Definition at line 223 of file cluster.c.

+ Collaboration diagram for fr_redis_cluster_node:
Data Fields
bool active Whether this node is in the active node set.
cluster_node_addr_t addr Current node address.
fr_redis_conf_t * conf Commmon configuration (database number, password, etc..).
uint8_t id Node ID (index in node array).
char name[INET6_ADDRSTRLEN] Buffer to hold IP + port.

text for debug messages.

cluster_node_addr_t pending_addr New node address to be applied when the pool is reconnected.
fr_connection_pool_t * pool Pool associated with this node.

Macro Definition Documentation

#define CLOSED_PERIOD   10000

How recently must the closed have.

occurred for us to care.

Definition at line 171 of file cluster.c.

#define CLOSED_WEIGHT   1

What weight to give to nodes that.

had a connection closed recently.

Definition at line 174 of file cluster.c.

#define FAILED_PERIOD   10000

How recently must the spawn failure.

occurred for us to care.

Definition at line 177 of file cluster.c.

#define FAILED_WEIGHT   1

What weight to give to nodes that.

had a spawn failure recently.

Definition at line 180 of file cluster.c.

#define KEY_SLOTS   16384

Maximum number of keyslots (should not change).

Definition at line 163 of file cluster.c.

#define MAX_SLAVES   5

Maximum number of slaves associated.

with a keyslot.

Definition at line 165 of file cluster.c.

#define pthread_mutex_destroy (   _x)

Definition at line 158 of file cluster.c.

#define pthread_mutex_init (   _x,
  _y 
)

Definition at line 157 of file cluster.c.

#define pthread_mutex_lock (   _x)

Definition at line 159 of file cluster.c.

#define pthread_mutex_unlock (   _x)

Definition at line 160 of file cluster.c.

#define RELEASED_MIN_WEIGHT   1000

Minimum weight to assign to node.

Definition at line 187 of file cluster.c.

#define RELEASED_PERIOD   10000

Period after which we don't care.

about when the last connection was released.

Definition at line 183 of file cluster.c.

#define SET_ACTIVE (   _node)
Value:
do { \
(_node)->active = true; \
rbtree_insert(cluster->used_nodes, _node); \
fr_fifo_pop(cluster->free_nodes); \
active[(_node)->id] = true; \
rollback[r++] = (_node)->id; \
} while (0)
void * fr_fifo_pop(fr_fifo_t *fi)
Definition: fifo.c:92
bool rbtree_insert(rbtree_t *tree, void *data)
Definition: rbtree.c:329
static int r
Definition: rbmonkey.c:66
#define SET_ADDR (   _addr,
  _map 
)
Value:
do { \
int _ret; \
_ret = fr_inet_pton(&_addr.ipaddr, _map->element[0]->str, _map->element[0]->len, AF_UNSPEC, false, true);\
rad_assert(_ret == 0);\
_addr.port = _map->element[1]->integer; \
} while (0)
#define rad_assert(expr)
Definition: rad_assert.h:38
int fr_inet_pton(fr_ipaddr_t *out, char const *value, ssize_t inlen, int af, bool resolve, bool mask)
Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser...
Definition: inet.c:564
#define SET_INACTIVE (   _node)
Value:
do { \
(_node)->active = false; \
rbtree_deletebydata(cluster->used_nodes, _node); \
fr_fifo_push(cluster->free_nodes, _node); \
} while (0)
bool rbtree_deletebydata(rbtree_t *tree, void const *data)
Delete a node from the tree, based on given data, which MUST have come from rbtree_finddata().
Definition: rbtree.c:496
int fr_fifo_push(fr_fifo_t *fi, void *data)
Definition: fifo.c:79

Typedef Documentation

Indexes in the cluster_node_t array for a single key slot.

When dealing with 16K entries, space is a concern. It's significantly more memory efficient to use 8bit indexes than 64bit pointers for each of the key slot to node mappings.

Configuration for a single node.

A Redis cluster node.

Passed as opaque data to pools which open connection to nodes.

Live nodes data, used to perform weighted random selection of alternative nodes.

Enumeration Type Documentation

Return values for internal functions.

Enumerator
CLUSTER_OP_IGNORED 

Operation ignored.

CLUSTER_OP_SUCCESS 

Operation completed successfully.

CLUSTER_OP_FAILED 

Operation failed.

CLUSTER_OP_NO_CONNECTION 

Operation failed because we couldn't find a live connection.

CLUSTER_OP_BAD_INPUT 

Validation error.

Definition at line 191 of file cluster.c.

Function Documentation

static int _cluster_conn_free ( fr_redis_conn_t conn)
static

Callback for freeing a Redis connection.

Parameters
[in]connto free.
Returns
0.

Definition at line 1399 of file cluster.c.

+ Here is the caller graph for this function:

static int _cluster_node_cmp ( void const *  a,
void const *  b 
)
static

Compare two redis nodes to check equality.

Parameters
[in]afirst node.
[in]bsecond node.
Returns
  • 0 if nodes are equal.
  • +1 if nodes are unequal.
  • -1 if nodes are unequal.

Definition at line 315 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void _cluster_node_conf_apply ( void *  opaque)
static

Reconnect callback to apply new pool config.

Parameters
[in]opaquedata passed to the connection pool.

Definition at line 335 of file cluster.c.

+ Here is the caller graph for this function:

static int _cluster_pool_walk ( void *  context,
void *  data 
)
static

Walk all used pools adding them to the live node list.

Parameters
contextWhere to write the node we found.
datanode to check.
Returns
  • 0 continue walking.
  • -1 found suitable node.

Definition at line 1127 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int _cluster_version_walk ( void *  context,
void *  data 
)
static

Walk all used pools checking their versions.

Parameters
contextWhere to write the node we found.
datanode to check.
Returns
  • 0 continue walking.
  • -1 found suitable node.

Definition at line 1992 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static uint16_t cluster_key_hash ( uint8_t const *  key,
size_t  key_len 
)
static

Resolve key to key slot.

Identical to the example implementation, except it uses memchr which will be faster, and isn't so needlessly complex.

Parameters
[in]keyto resolve.
[in]key_lenlength of key.
Returns
key slot index for the key.

Definition at line 288 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_map_apply ( fr_redis_cluster_t cluster,
redisReply *  reply 
)
static

Apply a cluster map received from a cluster node.

Note
Errors may be retrieved with fr_strerror().
Must be called with the cluster mutex held.

Key slot range structure

  [0] -> key slot range 0
      [0] -> key_slot_start
      [1] -> key_slot_end
      [2] -> master_node
          [0] -> master 0 ip (string)
          [1] -> master 0 port (number)
      [3..n] -> slave_node(s)
  [1] -> key slot range 1)
      [0]  -> key_slot_start
      [1] -> key_slot_end
      [2] -> master_node
          [0] -> master 1 ip (string)
          [1] -> master 1 port (number)
      [3..n] -> slave_node(s)
  [n] -> key slot range n
      [0] -> key_slot_start
      [1] -> key_slot_end
      [2] -> master_node
          [0] -> master n ip (string)
          [1] -> master n port (number)
      [3..n] -> slave_node(s)
Parameters
[in,out]clusterto apply map to.
[in]replyfrom cluster_map_get.
Returns
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_FAILED on failure.
  • CLUSTER_OP_NO_CONNECTION connection failure.
  • CLUSTER_OP_BAD_INPUT if the map didn't provide nodes for all keyslots.

Definition at line 493 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_map_get ( redisReply **  out,
fr_redis_conn_t conn 
)
static

Learn a new cluster layout by querying the node that issued the -MOVE.

Also validates the response from the Redis cluster, so we can be sure that it's well formed, before doing more expensive operations.

Note
Errors may be retrieved with fr_strerror().
Parameters
[out]outWhere to write cluster map.
[in]connto use for learning the new cluster map.
Returns
  • CLUSTER_OP_IGNORED if 'cluster slots' returned an error (indicating clustering not supported).
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_FAILED if issuing the command resulted in an error.
  • CLUSTER_OP_NO_CONNECTION connection failure.
  • CLUSTER_OP_BAD_INPUT on validation failure (bad data returned from Redis).

Definition at line 795 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int cluster_map_node_validate ( redisReply *  node,
int  map_idx,
int  node_idx 
)
static

Validate a cluster map node entry.

Note
Errors may be retrieved with fr_strerror().
In a separate function, as it's called for both master and slave nodes.
Parameters
[in]nodewe're validating.
[in]map_idxwe're processing.
[in]node_idxwe're processing.
Returns
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_BAD_INPUT on validation failure (bad data returned from Redis).

Definition at line 729 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_node_conf_from_redirect ( uint16_t *  key_slot,
cluster_node_addr_t node_addr,
redisReply *  redirect 
)
static

Parse a -MOVED or -ASK redirect.

Converts the body of the -MOVED or -ASK error into an IPv4/6 address and port.

Parameters
[out]key_slotvalue extracted from redirect string (may be NULL).
[out]node_addrRedis node ipaddr and port extracted from redirect string.
[in]redirectto process.
Returns
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_BAD_INPUT if the server returned an invalid redirect.

Definition at line 404 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_node_connect ( fr_redis_cluster_t cluster,
cluster_node_t node 
)
static

Establish a connection to a cluster node.

Note
Must be called with the cluster mutex locked.
Configuration to use for the connection must be set in node->pending_addr, not node->conf.
Parameters
[in]clusterto search in.
[in]nodeconfig.
Returns
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_FAILED if the operation failed.

Definition at line 352 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int cluster_node_find_live ( cluster_node_t **  live_node,
fr_redis_conn_t **  live_conn,
REQUEST request,
fr_redis_cluster_t cluster,
cluster_node_t skip 
)
static

Attempt to find a live pool in the cluster.

The intent here is to find pools/nodes where a connection was released the shortest time ago. Having a connection be released (vs closed) indicates that the pool is live.

We don't want to have all workers try and grab a connection to this node however, as it may still be dead (we don't know).

So we use an inverse transform sample, to weight the nodes, based on time between now and when the connection was released. Connections released closest to the current time are given a higher weighting.

Weight range is between 1 - 11,000.

  • If released > 10.0 seconds ago,information is not valid, weight 500.
  • If closed < 10.0 seconds ago, it's a bad pool, weight 1.
  • If spawn failed < 10.0 seconds ago, it's a bad pool, weight 1.
  • If a connection was released 0.0 seconds ago, weight 11,000.
  • If a connection was released 10.0 seconds ago, weight 1000.

Using the above algorithm we use the experience of other workers using the cluster to inform our alternative node selection.

Suggestions on improving live node selection appreciated.

Inverse transform sampling based roughly on the solution from this post: http://stackoverflow.com/questions/17250568/randomly-choosing-from-a-list-with-weighted-probabilities

Wikipedia page here: https://en.wikipedia.org/wiki/Inverse_transform_sampling

Note
Must be called with the cluster mutex free.
Parameters
[out]live_nodewe found.
[out]live_connto that node.
[in]requestThe current request (used for logging).
[in]clusterto search for live pools in.
[in]skipthis node (it's bad).
Returns
0 (iterates over the whole tree).

Definition at line 1267 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_node_ping ( REQUEST request,
cluster_node_t node,
fr_redis_conn_t conn 
)
static

Issue a ping request against a cluster node.

Establishes whether the connection to the node we have is live.

Parameters
requestThe current request.
nodeto ping.
connthe connection to ping on.
Returns
  • CLUSTER_OP_BAD_INPUT if we got a bad response.
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_NO_CONNECTION on connection down.

Definition at line 1199 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int cluster_node_pool_health ( struct timeval const *  now,
fr_connection_pool_state_t const *  state 
)
static

Try to determine the health of a cluster node passively by examining its pool state.

Returns an integer value representing the likelihood that the pool is live. Range is between 1 and 11,000.

If a weight of 1 is returned, connections from the pool should be checked (by pinging) before use.

Parameters
nowThe current time.
stateof the connection pool.
Returns
  • 1 the pool is very likely to be bad.
  • 2-11000 the pool is likely to be good, with a higher number indicating higher probability of liveness.

Definition at line 1157 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_redirect ( cluster_node_t **  out,
fr_redis_cluster_t cluster,
redisReply *  reply 
)
static

Retrieve or associate a node with the server indicated in the redirect.

Note
Errors may be retrieved with fr_strerror().
Parameters
[out]outWhere to write the node representing the redirect server.
[in]clusterto draw node from.
[in]replyRedis reply containing the redirect information.
Returns
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_FAILED no more nodes available.
  • CLUSTER_OP_NO_CONNECTION connection failure.
  • CLUSTER_OP_BAD_INPUT on validation failure (bad data returned from Redis).

Definition at line 1045 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_rcode_t cluster_remap ( REQUEST request,
fr_redis_cluster_t cluster,
fr_redis_conn_t conn 
)
static

Perform a runtime remap of the cluster.

Note
Errors may be retrieved with fr_strerror().
Must be called with the cluster mutex free.
Parameters
[in]requestThe current request.
[in,out]clusterto remap.
[in]connto use to query the cluster.
Returns
  • CLUSTER_OP_IGNORED if 'cluster slots' returned an error (indicating clustering not supported).
  • CLUSTER_OP_SUCCESS on success.
  • CLUSTER_OP_FAILED if issuing the 'cluster slots' command resulted in a protocol error.
  • CLUSTER_OP_NO_CONNECTION connection failure.
  • CLUSTER_OP_BAD_INPUT on validation failure (bad data returned from Redis).

Definition at line 940 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static cluster_key_slot_t* cluster_slot_by_key ( fr_redis_cluster_t cluster,
REQUEST request,
uint8_t const *  key,
size_t  key_len 
)
static

Implements the key slot selection scheme used by freeradius.

Like the scheme in the clustering specification but with some differences if the key is NULL or zero length, then a random keyslot is chosen.

If there's only a single node in the cluster, then we avoid the CRC16 and just use key slot 0.

Parameters
clusterto determine key slot for.
requestThe current request.
keythe key to resolve.
key_lenthe length of the key.
Returns
pointer to key slot key resolves to.

Definition at line 1518 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

fr_redis_cluster_t* fr_redis_cluster_alloc ( TALLOC_CTX *  ctx,
CONF_SECTION module,
fr_redis_conf_t conf 
)

Allocate and initialise a new cluster structure.

This holds all the data necessary to manage a pool of pools for a specific redis cluster.

Note
Will not error out unless cs.pool.start > 0. This is consistent with other pool based modules/code.
Parameters
ctxto link the lifetime of the cluster structure to.
moduleConfiguration section to search for 'server' conf pairs in.
confBase redis server configuration. Cluster nodes share database number and password.
Returns

Definition at line 2059 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void* fr_redis_cluster_conn_create ( TALLOC_CTX *  ctx,
void *  instance,
struct timeval const *  timeout 
)

Create a new connection to a Redis node.

Parameters
[in]ctxto allocate connection structure in. Will be freed at the same time as the pool.
[in]instancedata of type cluster_node_t. Holds parameters for establishing new connection.
[in]timeoutThe maximum time allowed to complete the connection.
Returns

Definition at line 1415 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool fr_redis_cluster_min_version ( fr_redis_cluster_t cluster,
char const *  min_version 
)

Check if members of the cluster are above a certain version.

Parameters
clusterto perform check on.
min_versionthat must be found on each node for the check to succeed. Must be in the format
<major>.<minor>.<release> 
.
Returns
  • true if all contactable members are above min_version.
  • false if at least one member if not above minimum version (use fr_strerror to retrieve node information).

Definition at line 2031 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int fr_redis_cluster_pool_by_node_addr ( fr_connection_pool_t **  pool,
fr_redis_cluster_t cluster,
fr_ipaddr_t ipaddr,
uint16_t  port,
bool  create 
)

Get the pool associated with a node in the cluster.

Note
This is used for testing only. It's not ifdef'd out because tests need to run against production builds too.
Parameters
[out]poolassociated with the node.
[in]clusterto search for node in.
[in]ipaddrof node.
[in]portof node.
[in]createEstablish a connection to the specified node if it was previously unknown to the cluster client.
Returns
  • 0 on success.
  • -1 if no such node exists.

Definition at line 1919 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

fr_redis_rcode_t fr_redis_cluster_state_init ( fr_redis_cluster_state_t state,
fr_redis_conn_t **  conn,
fr_redis_cluster_t cluster,
REQUEST request,
uint8_t const *  key,
size_t  key_len,
bool  read_only 
)

Resolve a key to a pool, and reserve a connection in that pool.

This should be used with fr_redis_cluster_state_next, and fr_redis_command_status, to transparently locate the cluster node we need to perform the operation on.

Example code below shows how this function is used in conjunction with fr_redis_cluster_state_next to follow redirects, and reconnect handles.

int s_ret;
redis_conn_state state;
redisReply *reply;
for (s_ret = fr_redis_cluster_state_init(&state, &conn, cluster, key, key_len, false);
s_ret = fr_redis_cluster_state_next(&state, &conn, cluster, request, status, &reply)) {
reply = redisCommand(conn->handle, "SET foo bar");
status = fr_redis_command_status(conn, reply);
}
// Reply is freed if ret == REDIS_RCODE_TRY_AGAIN, but left in all other cases to allow error
// processing, or extraction of results.
if (s_ret != REDIS_RCODE_SUCCESS) {
// Error
}
// Success
Parameters
[out]stateto track current pool and various counters, will be initialised.
[out]connWhere to write the reserved connection to.
[in]clusterof pools.
[in]requestThe current request.
[in]keyto resolve to a cluster node/pool. If no key is NULL or key_len is 0 a random slot will be chosen.
[in]key_lenLength of the key.
[in]read_onlyIf true, will use random slave pool in preference to the master, falling back to the master if no slaves are available.
Returns
  • REDIS_RCODE_TRY_AGAIN - try your command with this connection (provided via command).
  • REDIS_RCODE_RECONNECT - when no additional connections available.

Definition at line 1594 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

fr_redis_rcode_t fr_redis_cluster_state_next ( fr_redis_cluster_state_t state,
fr_redis_conn_t **  conn,
fr_redis_cluster_t cluster,
REQUEST request,
fr_redis_rcode_t  status,
redisReply **  reply 
)

Get the next connection to attempt a command against.

Will process reconnect and redirect states performing the actions necessary.

If a remap is in progress, has ocurred within the last second, has recently failed, or fails, the '-MOVE' will be treated as a temporary redirect (-ASK).

This allows the server to be more responsive during remaps, as unless the worker has been redirected to a node we don't currently have a pool for, it can grab a connection for the node it was redirected to, and continue.

Note
Irrespective of return code, the connection passed via conn will be released, A new connection to attempt command on will be provided via conn.
reply will be automatically freed and set to NULL if a new connection is provided in all other cases, the caller is responsible for freeing the reply.
Parameters
[in,out]statecontaining the current pool, and various counters which control retries, and limit redirects.
[in,out]connwe received the '-ASK' or '-MOVE' redirect on. Will be replaced with a connection in the new pool the key points to.
[in]requestThe current request.
[in]clusterof pools.
[in]statusof the last command, must be REDIS_RCODE_MOVE or REDIS_RCODE_ASK.
[in]replyfrom last command. Freed if 0 is returned, else caller must free.
Returns
  • REDIS_RCODE_SUCCESS - on success.
  • REDIS_RCODE_TRY_AGAIN - try new connection (provided via conn). Will free reply.
  • REDIS_RCODE_ERROR - on failure or command error.
  • REDIS_RCODE_RECONNECT - when no additional connections available.

Definition at line 1714 of file cluster.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function: