Skip to content

Commit

Permalink
Skip redis master when it is in blacklisted range
Browse files Browse the repository at this point in the history
When connecting to redis via proxy endpoints (such as AWS ElastiCache)
nchan will retrieve masters and slaves from each connected node eg.
> master_host:alias.cluster.0001.internal.use1.cache.amazonaws.com
specified in the upstream block.

If this hostname resolves to redis internal network that the client do
not have access to, connection to master fails and nodeset_examine()
will never mark the system ready. Since we can't connect to that internal
network it does not make sense to connect to it, hence we should be
able to blacklist the master, just like we do with slaves.

With that in mind we must accept the fact that we cannot autodiscover
nodes from networks nchan can't connect to. Still we should be able
to configure each nodes manually in the upstream block, eg.:

```
upstream redis_master {
    nchan_redis_discovered_ip_range_blacklist 10.31.0.0/16;
    nchan_redis_server PRIMARY_ENDPOINT;
    nchan_redis_server READER_ENDPOINT;
}

nchan_redis_namespace "nchan";
nchan_redis_pass redis_master;
nchan_redis_pass_inheritable on;
```

This makes it possible to connect to redis ha systems via reverse proxy,
such as HAProxy as long as all nodes are species in the upstream block,
or the reverse proxy can load-balance connections properly.
  • Loading branch information
piotr-lwks authored Mar 4, 2023
1 parent c06e5da commit 6212ad1
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/store/redis/redis_nodeset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1520,9 +1520,15 @@ static void node_discover_slave(redis_node_t *master, redis_connect_params_t *rc
}

static void node_discover_master(redis_node_t *slave, redis_connect_params_t *rcp) {
redis_node_t *master;
if ((master = nodeset_node_find_by_connect_params(slave->nodeset, rcp)) != NULL) {
if(master->role != REDIS_NODE_ROLE_MASTER && master->state > REDIS_NODE_GET_INFO) {
nchan_redis_ip_range_t *matched;
redis_node_t *master = NULL;

if ((matched = node_ip_blacklisted(slave->nodeset, rcp)) != NULL) {
node_log_notice(slave, "skipping master %V blacklisted by %V", &rcp->hostname, &matched->str);
return;
}
else if ((master = nodeset_node_find_by_connect_params(slave->nodeset, rcp)) != NULL) {
if (master->role != REDIS_NODE_ROLE_MASTER && master->state > REDIS_NODE_GET_INFO) {
node_log_notice(master, "Node appears to have changed to master -- need to update");
node_set_role(master, REDIS_NODE_ROLE_UNKNOWN);
node_disconnect(master, REDIS_NODE_FAILED);
Expand Down

0 comments on commit 6212ad1

Please sign in to comment.