We want to use Redis to distribute data to remote servers.
There is one master instance in the HQ and many remote slaves in our subsidiaries connected to the master.
Our applications are running in our subsidiaries. In 99% of the time there are read-only requests made to the slave instance.
But there is also the case of modifying data. Such a request is issued against the master.
Is there a way to ensure that the changes made to the master are replicated to the slave before the next read request?
I'm not sure if there is a way you can ensure this 100%, but you probably want to check in your redis.conf file and find this:
slave-serve-stale-data yes
Sounds like you'd want that set to no. The comments in the config file explain more about this directive.
Related
I have a redis cluster created with master slave mode. I want to create a redisson client to access the cluster but I want to specify separate endpoints for reads and writes. Writes should go to master and reads should happen from the slaves. There is a config readMode that can I set to SLAVE to read only from slave nodes but how do I restrict writes to master only?
In Redis, writes happen only in master nodes. So you don't need separate config to handle that.
There is a config readMode that can I set to SLAVE to read only from slave nodes but how do I restrict writes to master only?
Writes are executed in master nodes.
All commands are executed in the master nodes, by default: while Redis Enterprise allows for a multi-master active-active clusters, Redis (Open Source) only allows one master node and zero or more replicas per slot range. In all cases, all nodes can receive both read and write commands but, by default, replicas reply with a -MOVED redirection error along with the endpoint of the master which is believed to handle a given target key. Clients may use that information to contact the master which will actually execute the command.
With that being said, replicas can be configured to reply to read-only commands - provided they handle the slot range of the given target key. In that context, most cluster-aware Redis clients allow to read from replicas with the goal of distributing the load - with the risk of reading stale data: Redisson manages that through the readMode setting and automatically deals with the aforementioned connection configuration.
I'm testing out ElastiCache backed by Redis with the following specs:
Using Redis 2.8, with Multi-AZ
Single replication group
1 master node in us-east-1b, 1 slave node in us-east-1c, 1 slave node in us-east-1d
The part of the application writing is directly using the endpoint for the master node (primary-node.use1.cache.amazonaws.com)
The part of the application doing only reads is pointing to a custom endpoint (readonly.redis.mydomain.com) configured in HAProxy, which then points to the two other read slave end points. (readslave1.use1.cache.amazonaws.com and readslave2.use1.cache.amazonaws.com)
Now lets say the primary node (master) fails in us-east-1b.
From what I understand, if the master instance fails, I won't have to change the url for the end point for writing to Redis (primary-node.use1.cache.amazonaws.com), although from there, I still have the following questions:
Do I have to change the endpoint names for the read only slaves?
How long until the missing slave is added into the pool?
If there's anything else I'm missing, I'd appreciate the advice/information.
Thanks!
If you are using ElastiCache, you should make use the "Primary EndpointThe" provided by AWS.
That endpoint actually is backed by Route53, if the primary (master) redis is down, since you enable MutliA-Z, it will auto fail over to one of the read replica (slave).
In that case, you don't need to modify the endpoint of your redis.
I don't know why you have such design, seems you only want write to master, but always read from slave.
For HA Proxy part, you should include TCP check for ALL 3 redis nodes, using their "Read Endpoint"
In haproxy, you can check if the endpoint is SLAVE, if yes, your haproxy should redirect the traffic to that.
Notice that in the application layer, if your redis driver don't support auto reconnect, your script will fail to connect to the new master nodes.
In addition to "auto reconnect", since AWS is using Route53 DNS to do fail over, some lib will NOT do NS lookup again, which means the DNS is still pointing to the OLD ip which is the old master.
Using HAproxy can solve this problem.
We have a redis cluster with a master and a slave managed by three sentinel processes, and an additional remote slave, hosted in a different datacenter, for transparent failover and data preservation in the case that something bad happens to the master and slave machines.
It may happen that a transient error takes down the master redis process only, and in this situation we would like to see the slave process promoted to master, and the remote slave reslaved to it. However, it seems that sentinel could just as easily promote the remote slave to master, and we have not found any way to prevent this.
Is there any way to mark a particular slave machine as unpromotable, so that sentinel will not try to make it the master in the event of a failover?
Yes. In the slave's config file set the slave-priority setting to zero (the number not the word).
I have installed Redis for my nodeJS application and configured it to be a slave for another instance of Redis DB running on a different server. Can I have the same instance (different DB) of Redis (running as slave) act as Master for locally installed application?
Thanks in advance
Yes, you can, but with a big caveat.
Any slave instance can be master of one or several other instances. So you can imagine daisy chaining slaves and build a hierarchical replication system.
Now, my understanding is you don't need your slave to feed another Redis instance, but just allow an application to perform read/write operations in another database of the slave instance.
To allow it, you need to set the value of the slave-read-only parameter to "no" in the slave configuration:
# You can configure a slave instance to accept writes or not. Writing against
# a slave instance may be useful to store some ephemeral data (because data
# written on a slave will be easily deleted after resync with the master) but
# may also cause problems if clients are writing to it because of a
# misconfiguration.
#
# Since Redis 2.6 by default slaves are read-only.
#
# Note: read only slaves are not designed to be exposed to untrusted clients
# on the internet. It's just a protection layer against misuse of the instance.
# Still a read only slave exports by default all the administrative commands
# such as CONFIG, DEBUG, and so forth. To a limited extend you can improve
# security of read only slaves using 'rename-command' to shadow all the
# administrative / dangerous commands.
slave-read-only no
Now, all the write operations you will run on this instance will be ephemeral. If the link is lost between the master and the slave, the slave will completely synchronize again to the master. All the data you have set on the slave will be lost. If you stop and restart the slave, you will also loose all the ephemeral data.
It may or may not suit your needs.
There is no way to parameter the synchronization (or the persistence options) at the database level. You cannot tell Redis to synchronize a given database, and not another one. Configuration always applies at the instance level.
Does REDIS has built-in mechanism that will use slave when master is down?
Can I use virtual IP to direct to master and when Master is down is it possible to direct to slave?
As per the documentaion:
elect the slave to master using the SLAVEOF NO ONE command, and shut down your master.
But how the application will know about the changed IP?
mysql has a third party utility that is called MMM (master master replication with monitor). Is there such an utility for REDIS?
You can use a virtual IP in a load balancer, though this is not built in to Redis. Any quality hardware or software load balancer should be able to do it. For example you can use "balance" or HAProxy to front the VIP and use a script or rules that checks the status of Redis instances to see which is master and sets that as the destination in the load balancer (LB).
Going this route would require one or more additional servers (or VMs depending on your setup) but it would provide you with a configuration that has clients talking to a single IP and being clueless about which server they need to talk to on the back end. How you update the LB with which server to talk to is dependent on what LB you use. Fortunately, none of them would need to know or handle the Redis protocol; they are just balancing a port.
When I go this route I go with a Slave-VIP and a Master-VIP. The slave-VIP load balances across all Redis instances, whereas the Master-VIP only has the current master enabled. If your write load is very heavy you can leave the current master out of the Slave-VIP pool. Otherwise I would leave it in; that eliminates the need for failover updating of the Slave-VIP pool.