Redis is a popular open-source in-memory database that supports multiple data structures like strings, hashes, lists, and sets. But similar to other tools, we can scale standalone Redis to a particular extent, but not beyond that. That’s why we have a cluster mode setup in which we can scale Redis nodes horizontally and then distribute data among those nodes.
Generally, we categorize the Redis setup into three different types:
Standalone
Leader-Follower (Replication)
Leader-Leader(Sharding)
Standalone Setup
In a Standalone setup, the complexity is minimal, but we cannot scale the solution if the data increases. Also, the fail-over and high availability will not be supported inside it.
Redis is a popular and opensource in-memory database that supports multiple data structures like strings, hashes, lists, and sets. But similar to other tools, we can scale standalone redis to a particular extent and not beyond that. That’s why we have a cluster mode setup in which we can scale Redis nodes horizontally and then distribute data among those nodes.
Since Kubernetes is becoming buzz technology and people are using it to manage their applications, databases, and middlewares at a single place. So in this blog, we will see how we can deploy the Redis cluster in production mode in the Kubernetes cluster and test failover.
Watching cluster sharding and failover management is as gripping as visualizing a robotic machinery work.
My last blog on Redis Cluster was primarily focussed on its related concepts and requirements. I would highly recommend to go through the concepts first to have better understanding.
Here, I will straight forward move to its setup along with the behaviour of cluster when I intentionally turned down one Redis service on one of the node. Let’s start from the scratch.
Speed fascinates everyone, but only if its under control.
It is well said and a proven fact that everyone needs to implement a cache at some point in their application lifecycle, and this has become our requirement too.
During the initial phase we placed Redis in a Master Slave mode with next phase involving Sentinal setup to withstand Master failover. I would like to throw some light on their architecture along with pros and cons so I can put emphasis on why I finally migrated to Redis Cluster.
Redis Master/Slave
Redis replication is a very simple to use and configure master-slave replication that allows slave Redis servers to be exact copies of master servers.
What forced me to look for Redis Sentinel
When using Master-Slave architecture
There will be only one Master with multiple slaves for replication.
All write goes to Master, which creates more load on master node.
If Master goes down, the whole architecture is prone to SPOF (Single point of failure).
M-S architecture does not helps in scaling, when your user base grows.
So we need a process to Monitor Master in case of failure or shutdown, that is Sentinel.
Redis Sentinel
Initial Setup
Failover Handling
I was still concerned about the below Sharding of data for best performance
Concept of Redis Cluster
“A query that used to take an hour can run in seconds on cache”.
Redis Cluster is an active-passive cluster implementation that consists of master and slave nodes. The cluster uses hash partitioning to split the key space into 16,384 key slots, with each master responsible for a subset of those slots.
Each slave replicates a specific master and can be reassigned to replicate another master or be elected to a master node as needed.
Ports Communication
Each node in a cluster requires two TCP ports.
One port is used for client connections and communications. This is the port you would configure into client applications or command line tools.
Second required port is reserved for node-to-node communication that occurs in a binary protocol and allows the nodes to discuss configuration and node availability.
Failover
When a master fails or is found to be unreachable by the majority of the cluster as determined by the nodes communication via the gossip port, the remaining masters hold a vote and elect one of the failing masters’ slaves to take its place.
Rejoining The Cluster
When the failing master eventually rejoins the cluster, it will join as a slave and begin to replicate another master.
Sharding
Redis sharded data automatically into the servers. Redis has a concept of hash slot in order to split data. All the data are divided into slots. There are 16384 slots. These slots are divided by the number of servers.
If there are 3 servers; A, B and C then
Server 1 contains hash slots from 0 to 5500.
Server 2 contains hash slots from 5501 to 11000.
Server 3 contains hash slots from 11001 to 16383.
6 Node M/S Cluster
In a 6 node cluster mode, 3 nodes will be serving as a master and the 3 node will be their respective slave.
Here, Redis service will be running on port 6379 on all servers in the cluster. Each master server is replicating the keys to its respective redis slave node assigned during cluster creation process.
3 Node M/S Cluster
In a 3 node cluster mode, there will be 2 redis services running on each server on different ports. All 3 nodes will be serving as a master with redis slave on cross nodes.
Here, two redis services will be running on each server on two different ports and each master is replicating the keys to its respective redis slave running on other node.
WHAT IF Redis Goes Down
1 node goes down in a 6 node Redis Cluster
If one of the node goes down in Redis 6-node cluster setup, its respective slave will be promoted as master.
In above example, master Server3 goes down and it slave Server6 is promoted as master.
1 node goes down in a 3 node Redis Cluster
If one of the node goes down in Redis 3-node cluster setup, its respective slave running on the separate node will be promoted to master.
In above example, Server 3 goes down and slave running on Server1 is promoted to master.
Redis service goes down on one of the 3 node Redis Cluster
If redis service goes down on one of the node in Redis 3-node cluster setup, its respective slave will be promoted as master.
Conclusion
Although, this methodology will prevent Redis Cluster in partial Failover scenarios only, but if we want full failover we need to look for Disaster Recovery techniques as well.
Well this implementation helped me having a sound sleep while thinking of Redis availability, sharding and performance.
A few days back I came across a problem of migrating a Redis Master-Slave setup to Redis Cluster. Initially, I thought it to be a piece of cake since I have been already working on Redis, but there was a hitch, “Zero Downtime Migration”. Also, the redis was getting used as a database, not as Caching Server. So I started to think of different ways for migrating Redis Master-Slave setup to Redis Cluster and finally, I came up with an idea of migration.
Before we jump to migration, I want to give an overview regarding when we can use Redis as a database, and how to choose which setup we should go with Master-Slave or Cluster mode.
Redis as a Database
Sometimes getting data from disks can be time-consuming. In order to increase the performance, we can put the requests those either need to be served first or rapidly in Redis memory and then the Redis service there will keep rest of the data in the main database. So the whole architecture will look like this:-
Redis Master-Slave Replication
Beginning with the explanation about Redis Master-Slave. In this phenomenon, Redis can replicate data to any number of nodes. ie. it lets the slave have the exact copy of their master. This helps in performance optimizations.
I bet now you can use Redis as a Database.
Redis Cluster
A Redis cluster is simply a data sharding strategy. It automatically partitions data across multiple Redis nodes. It is an advanced feature of Redis which achieves distributed storage and prevents a single point of failure.
Replication vs Sharding
Replication is also known as mirroring of data. In replication, all the data get copied from the master node to the slave node.
Sharding is also known as partitioning. It splits up the data by the key to multiple nodes.
As shown in the above figure, all keys 1, 2, 3, 4 are getting stored on both machine A and B.
In sharding, the keys are getting distributed across both machine A and B. That is, the machine A will hold the 1, 3 key and machine B will hold 2, 4 key.
I guess now everyone has a good idea about Redis working mechanism. So let’s start discussing the migration of Redis.
Migration
Unfortunately, redis doesn’t have a direct way of migrating data from Redis-Master Slave to Redis Cluster. Let me explain it to you why?
We can start Redis service in either cluster mode or standalone mode. Now your solution would be that we can change the Redis Configuration value on-fly(means without restarting the Redis Service) with redis-cli. Yes, you are absolutely correct we can change the Redis configuration on-fly but unfortunately, Redis Mode(cluster or standalone) can’t be decided on-fly, for that we have to restart the service.
I guess now you guys will understand my situation :).
For migration, there are multiple ways of doing it. However, we needed to migrate the data without downtime or any interruptions to the service.
We decided the best course of action was a steps process:-
Firstly we needed to create a different Redis Cluster environment. The architecture of the cluster environment was something like
The next step was to update all the services (application) to send all the write operations to both servers(cluster and master-slave). The read commands (GET) will still go to the old setup.
But still, we don’t have the guarantee that all non-expirable data would make it over. So we can run a step to iterate through all of the keys and DUMP/RESTORE them into the new setup.
Once the new Redis Server looks good we could make the appropriate changes to the application to point solely to the new Redis Server.
I know the all steps are easy except the second step. Fortunately, redis provides a method of key scanning through which we can scan all the key and take a dump of it and then restore it in the new Redis Server.
To achieve this I have created a python utility in which you have to define the connection details of your old Redis Server and new Redis Server.
I have provided the detail information on using this utility in the README file itself. I guess my experience will help you guys while redis migration.
Replication or Clustering?
I know most people have a query that when should we use replication and when clustering :).
If you have more data than RAM in a single machine, use Redis Cluster to shard the data across multiple databases.
If you have less data than RAM in a machine, set up a master-slave replication with sentinel in front to handle the fai-lover.
The main idea of writing this blog was to spread information about Replication and Sharding mechanism and how to choose the right one and if mistakenly you have chosen the wrong one, how to migrate it from :).
There are multiple factors yet to be explored to enhance the flow of migration if you find that before I do, please let me know to improve this blog.
I hope I explained everything and clear enough to understand.
Thanks for reading. I’d really appreciate any and all feedback, please leave your comment below if you guys have some feedbacks.