I have this situation. A Redis Master, with a replica(Slave) R1, for redundancy, which can be promoted to Master in case of failure, plus two extra replicas, R2 and R3, which are only for replication, and can't be promoted.
The point is, R2 and R3 are over a WAN, so in other to save bandwidth, I was thinking about making R3 a "replicaof" R2. I know it works, but my problem is :
if R2 crashes, what happens to R3? How can it be then connected to the Master instead? I mean automatically, like using Redis-sentinels, for instance. And, if that is possible, what will happen when R2 recovers?
Ay ideas?
Best Regards,
Luis
if R2 crashes, what happens to R3?
R3 disconnects from R2, and CANNOT sync with the master. Although R3 is still in slave role.
How can it be then connected to the Master instead?
AFAIK, you have to manually reconfig R3 to be a slave of the master.
However, this is an interesting scenario, I think you can open an issue to Redis developers.
Related
In redis master-slave architecture, when a master fails a slave is promoted to master. As only master can perform write operations, What happens to data in the window period when slave is promoted to master. Does my system remain unresponsive?
Define "data":)
Client connections to the master will be closed upon its failure, so your system will be notified of that. Any data that was not written to the master and the replicas before the failure will therefore still reside in your application/system.
Once your system tries using a replica it will be able to read the data in it up to the point it was synchronized before failure. Once the replica is promoted to masterhood, your system will be able to continue writing data.
Note that Redis' synchronization is asynchronous. That means that slaves may lag behind the master and therefore lose some updates in case of failure. Refer to the WAIT command for more information about ensure the consistency.
I am new to Redis. I read their documentation on Sentinel and Replication in which they talk about how the replicas try to remain in sync with the master as much as possible, but it is still possible that if the master fails after a successful write, the replica might not receive that write. If Sentinel then marks this replica as the new master, it is possible that the replica serves stale data.
If I cannot afford to lose consistency and prefer it over availability, how can I turn off replication so that when Sentinel marks a new replica as master, all the first requests would be cache misses and my cache can slowly warm up instead of returning potentially stale data?
Also, is that a good idea? Are there other good alternatives?
I cannot afford to lose consistency and prefer it over availability
It's not clear that redis automated failover is appropriate for your application. It looks like each client would need to carefully keep track of server availability.
Suppose you have a few clients, a master, M1, and three replicas, R2, R3, R4. Client C5 writes a new bank account balance to M1, which immediately permanently fails, and R2 is promoted to become master M2. Master did not obtain an acknowledge from a replica before replying to client. No paxos-like consensus protocol happens between servers prior to the reply being sent to C5.
C5 could remember counters / timestamps embedded in each write request, forget the write payload, and detect stale reads. But client C6 could not, unless you supply such data quickly and reliably outside the protocol. Nathan Fritz observes that your app could issue a write and then a PUBLISH event, and monitor multiple replicas with a LISTEN for that event, delaying its report of success to end user. Consider incorporating derecho into your app if the solid promises of virtual synchrony are necessary. Production releases of redis are targeted at a different part of the problem space than your primary interest.
This is a bit of an odd question, but either the way to do it is buried deep in the web, or it is just stupid.
I have a master instance of Redis on a server (s1) and a slave instance on another server (s2). I have a parallel computation going on in both the servers and I would like to have them to be able to read and write on their instance of Redis and be able to read what has been written from the other party (and possibly write on top of it).
I know that writing on the master from s1 will cause s2 to be able to read the changes, but writing from s2 on the slave doesn't update the master. Is there a way, or a workaround, to do this? I would like to avoid having s2 connected directly to the master in s1 for performance reasons.
Thanks
I am using redis version 2.8.3. I want to build a redis cluster. But in this cluster there should be multiple master. This means I need multiple nodes that has write access and applying ability to all other nodes.
I could build a cluster with a master and multiple slaves. I just configured slaves redis.conf files and added that ;
slaveof myMasterIp myMasterPort
Thats all. Than I try to write something into db via master. It is replicated to all slaves and I really like it.
But when I try to write via a slave, it told me that slaves have no right to write. After that I just set read-only status of slave in redis.conf file to false. Hence, I could write something into db.
But I realize that, it is not replicated to my master replication so it is not replicated to all other slave neigther.
This means I could'not build an active-active cluster.
I tried to find something whether redis has active-active cluster capability. But I could not find exact answer about it.
Is it available to build active-active cluster with redis?
If it is, How can I do it ?
Thank you!
Redis v2.8.3 does not support multi-master setups. The real question, however, is why do you want to set one up? Put differently, what challenge/problem are you trying to solve?
It looks like the challenge you're trying to solve is how to reduce the network load (more on that below) by eliminating over-the-net reads. Since Redis isn't multi-master (yet), the only way to do it is by setting up each app server with a master and a slave (to the other master) - i.e. grand total of 4 Redis instances (and twice the RAM).
The simple scenario is when each app updates only a mutually-exclusive subset of the database's keys. In that scenario this kind of setup may actually be beneficial (at least in the short term). If, however, both apps can touch all keys or if even just one key is "shared" for writes between the apps, then you'll need to bake locking/conflict resolution/etc... logic into your apps to consolidate local master and slave differences (and that may be a bit of an overkill). In either case, however, you'll end up with too many (i.e. more than 1) Redises, which means more admin effort at the very least.
Also note that by colocating app and database on the same server you're setting yourself for near-certain scalability failure. What will happen when you need more compute resources for your apps or Redis? How will you add yet another app server to the mix?
Which brings me back to the actual problem you are trying to solve - network load. Why exactly is that an issue? Are your apps so throughput-heavy or is the network so thin that you are willing to go to such lengths? Or maybe latency is the issue that you want to resolve? Be the case as it may be, I recommended that you consider a time-proven design instead, namely separating Redis from the apps and putting it on its own resources. True, network will hit you in the face and you'll have to work around/with it (which is what everybody else does). On the other hand, you'll have more flexibility and control over your much simpler setup and that, in my book, is a huge gain.
Redis Enterprise has had this feature for quite a while, but if you are looking for an open source solution KeyDB is a fork with Active Active support (called Active Replica).
Setting it up is just a little more work than standard replication:
Both servers must have "active-replica yes" in their respective configuration files
On server B execute the command "replicaof [A address] [A port]"
Server B will drop its database and load server A's dataset
On server A execute the command "replicaof [B address] [B port]"
Server A will drop its database and load server B's dataset (including the data it just transferred in the prior step)
Both servers will now propagate writes to each other. You can test this by writing to a key on Server A and ensuring it is visible on B and vice versa.
https://github.com/JohnSully/KeyDB/wiki/KeyDB-(Redis-Fork):-Active-Replica-Support
I have a physical Prod DB Server (SQL05) and now a VM DB Server. The idea is if the physical machine goes down, we repoint our router (via NAT) to the VM machine. I am thinking of using Log Shipping to keep the VM DB basically current.
Is this the correct way to do it?
Should I be looking at another way, mirroring perhaps?
We would like the VM DB to be in an usable state at all times (so I think this precludes mirroring)
Any (good) suggestions requested! :)
Why wouldn't you use mirroring?