Overview
Replication means making a copy of the data for future use in the case of failures or may be to scale.
Why is it a big deal ? We copy files for backup all the time. For static files, that do not change, making a copy is 1 copy command. But if the data is being updated by users all the time. How often do you run the command to copy. How do you keep the copy in sync with the source ?
That is the problem of replication in databases and data systems. All databases have replication built in that you can setup with a command or two. So why read or discuss it? If you are building a distributed systems that involves data, you will need to replicate data. The concepts from databases will be useful.
While replication is most well known for its use with databases, it is also a critical part of distributed systems where the data is unstructured such as distributed file systems (HDFS) or messaging systems (Apache Kafka)
This post covers replication in traditional single node systems as well as modern distributed systems.
Why do we need replication ?
Redundancy
Make a copy of the data. When the main server becomes unavailable for any reason, switch to the copy. This is ensure that the data is always available.
Scalability
Your data becomes really popular and the database gets a lot of read requests and cannot keep up. So you make copies of the database and have a load balancer distribute the request across to the copies (replicas).
Geo distribution of data
Bring the data close of user. You have users in Americas, Europe and Asia. Data from americas is replicated to Europe and Asia, so users there can read data locally without making a round trip to the americas for every read.
Secondary use cases
These are lesser known and unconventional use cases. They might be done higher up in the stack at the application layer or middleware than in the database.
Mirroring
Mirroring involves replicating the requests to the application to a copy of the entire application stack. You can think of this as application level replication.
For example, for a REST service, this involves sending the http request, not just to the production service but also to a mirror service.
The mirror service reads and writes from the mirror database. Mirror database is a previous replica that was in sync with the leader. Just before starting mirroring, it is discontinued as a replica so it does not get duplicates.
Mirroring can be used for testing large complex changes against production traffic.
Data in the mirror database is then compared with data in the production database for accuracy.
Testing
A regular database replica is used as a test database. Various kinds of tests - feature tests, performance tests, concurrency tests, scalability tests can be run with services running with the replica. This is a different use case from mirroring.
Migration
This can be used to eliminate or reduce downtimes needed for migration.
Create additional replicas.
Run migration on them.
Rollover the application services to the new database replicas.
Replication strategies
Single leader
This is the most common pattern. It shown in Figure 1.
One server is designated as the leader. The others are followers. All writes go to the leader. The leader replicates the writes to the followers.
The advantages are :
Setting up is fairly easy.
Reads become scalable. You can put a load balancer in front and distribute read requests to followers.
High availability: If the leader fails, you fail over to one of the followers and let it become the leader.
The disadvantages are :
All the writes go to one server , the leader. So this can become a bottleneck. Writes are not scaled.
If you read from a replica that is behind on replication, you might read stale data.
Multi leader
Multi leader replication is needed when
(1) Writes and replication needs to happen across geographically distributed areas.
(2) Connectivity to single leader is not guaranteed. The is usually the case with mobile devices or laptops or when people want the ability to work offline and/or multiple devices.
In the geo distributed case, the writes go to a local local leader. The local leader not only replicates to local replicas but also to the distributed leader (who replicate to their replicas).
In the mobile case, the writes are store locally and the replicated periodically when connectivity is available.
Advantages:
Writes are also scaled.
Writes can done locally or close to clients. Better latency for writes.
Disadvantages:
Since writes happen at multiple leaders. There can be conflict. The conflicts need to be resolved.
Leaderless
In the leaderless model, all nodes are equal and no node is designated leader. Writes can go to any node and that node replicates the write to other nodes. This is the model made popular by AWS Dynamo and later adopted by Cassandra.
Consensus based replication
Replication Implementations
Statement based replication
In this approach, the SQL statements such as INSERT/UPDATE/DELETE etc are forwarded as they are from the leaders to the followers. While this can work in most cases, it does not work in certain cases such as timestamps or when you generate an id or a random number.
It is not efficient either. If you insert a record and then delete it, why replicate both commands ?
Write ahead log (WAL) replication
Databases first append every write to the WAL before doing anything else, before writing it to structured storage from where it will be read. WAL is used for recovery. If the database crashed, it state is reconstructed from the WAL. A recent slogan has been "The WAL is the database". Replication here involves replicating the WAL.
A disadvantage is that WAL entries contain where specific storage details like which byte in which block is to be updated. This can create compatibility issues if the leader and followers are on different versions.
Logical replication
A logical log on the other hand captures at a row, how the table was changed. You can view this as an approach somewhere between statement based and WAL replication.
Change data capture is a form of logical replication. It is used to replicate changes in a database to other third party systems. A popular use case is data warehousing where data from multiple sources is aggregated and summarized for analytics.
Unstructured data replication
Potential issues with replication
Replication Lag
Most of the time replication is asynchronous. Client writes to the leader and returns before any acknowledgement that it has been replicated. Synchronous replication is not viable due both performance and availability issues. A single failure can hold up all replications.
Lost write
However, one problem this creates is that if you read immediately after a write, the replica you are reading from may not yet have your last write.
Inconsistent read
If you read multiple times in quick succession ( same read) , each read may get a different result depending on which replica services the read ( as the replicas may be in different stages of replication)
Cassandra addressed this issue using quorum. CockroachDb uses a consensus protocol like Raft.
Write Conflicts
Write conflict is an issue in multi leader replication. This happens when multiple clients update the same data while talking to a different master. The database does not know which update to accept and how they should be merged. This is similar to a merge conflict in git.
An approach to handle conflicts is to store both versions on write. But on read, send both versions to the client and let the the client resolve the conflict
Replication is real world systems
The product documentation for database on replication can be quite confusing. It best to follow a tutorial or blog in the internet.
Postgres
The documentation and blogs describe it in 2 ways.
You can set it up as synchronous, asynchronous , streaming , log file based etc
And it can be WAL based or logical replication. Statement based is rarely seen.
In snapshot replication, a snapshot of the database is taken and replicated to followers.
Instead of streaming, you can also setup the replication as file based, where the WAL files are periodically shipped to followers.
In WAL replication, replication slots lets the leader track how much of the WAL is replicated to each replica. This helps the leader not discard segments not yet replicated. But this consumes resources on the leader. Replication slots need to be managed and deleted when not needed.
Mysql
The traditional way in mysql was a logical replication based on their binlog file - a binary format for logical changes.
The newer way is based on global transaction identifier (GTID) which is built on top of the binlog. It can be either statement based or row based.
Dynamo / Cassandra
In this architecture, replication is fundamental to the architecture. All you need to do is to set the replication factor to greater than 1. All servers are equal - no leader and no follower. Writes can go to any server. Partitioning is also fundamental to the architecture. The server that receives the write redirects the write to appropriate server. From here it is replicated to other servers based on the replication factor.
Consistency issues are addressed using quorum based tunable consistency. Quorum mean a majority which is (RF/2+1) agree on something. If you have replication factor (RF) 3, quorum is 2. So on a write, at least 2 nodes need to acknowledge that the write was saved. On read, at least 2 nodes need to agree on the return value. In general, to avoid inconsistencies, you want Read quorum (R)+ Write quorum (W) > RF .
CockroachDb
CockroachDB uses the Raft distributed consensus protocol to ensure that a majority of replicas are in consensus before any change is committed. This is the safest approach to ensure consistency but comes at a cost.
Apache Kafka
Apache Hadoop (HDFS)
Conclusion
Replication is a critical piece of any distributed data system. It has to be part of the core architecture. It cannot come after the fact like it did in the past. While redundancy and HA are well known benefits, there are other benefits such geo distribution of data as well. It can cause some effects such as read consistency. Care should be taken to address those. Different products use different strategies. You should be familiar with the replication strategies, configuration and side effects for your data product. If you are building a new system with data, understanding how existing systems replicate and the issues they face, can help you design your replication.