Databases 14 min read

Redis Master‑Slave Replication Memory Consumption and the Shared Replication Buffer Design

This article analyzes the excessive memory usage and blocking issues in Redis master‑slave replication, explains how the upcoming Redis 7.0 shared replication buffer solves these problems, and details the design, implementation, and key considerations of the shared buffer mechanism.

High Availability Architecture
High Availability Architecture
High Availability Architecture
Redis Master‑Slave Replication Memory Consumption and the Shared Replication Buffer Design

The article begins with a brief overview of Redis master‑slave replication, describing the two main phases: full synchronization (where the master forks a child process to generate an RDB snapshot) and command propagation (where the master streams write commands to replicas).

It then identifies three critical problems in the existing replication architecture: (1) memory consumption grows linearly with the number of replicas because each replica has an independent output buffer; (2) copying and freeing large output buffers can block the server for hundreds of milliseconds; and (3) the replication backlog size creates a trade‑off between partial resynchronization capability and memory usage.

To address these issues, Redis 7.0 introduces a shared replication buffer that allows all replicas and the replication backlog to reference a single global buffer (ReplicationBuffer). The buffer is divided into 16 KB blocks (

typedef struct replBufBlock { int refcount; long long id; long long repl_offset; size_t size, used; char buf[]; } replBufBlock;

) linked together, similar to the client output buffer implementation.

Each replica now stores only a reference to the relevant block ( listNode *ref_repl_buf_node; size_t ref_block_pos; in the client structure) instead of a full copy. When a replica finishes using a block, the reference count is decremented, eliminating the costly deep‑copy and free operations. The replication backlog also holds a reference to the same blocks, so its memory footprint no longer grows with the number of replicas.

The design includes mechanisms for trimming and releasing the buffer: blocks with a reference count of zero are freed from the head of the list, and the function incrementalTrimReplicationBacklog performs this trimming incrementally to avoid long pauses. The backlog index is implemented with a radix tree (rax), storing an index entry every 64 blocks, which enables fast lookup of the block containing a given replication offset (typically under 1 ms).

Additional considerations such as INFO metrics ( mem_total_replication_buffers), interaction with key eviction, and multi‑threaded I/O are discussed. The article concludes that the shared replication buffer reduces per‑replica memory usage, removes hidden blocking during buffer copy/free, and simplifies backlog management, thereby improving Redis stability in large‑scale deployments.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Memory OptimizationredisReplicationDatabase InternalsShared Buffer
High Availability Architecture
Written by

High Availability Architecture

Official account for High Availability Architecture.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.