Redis Network Model Analysis

Detailed analysis on the source code of redis network model

Deep dive into how Redis achieves exceptional performance through its network architecture:

Event-Driven Architecture:

Single-Threaded Event Loop:

  • Main Thread: All Redis operations run in a single thread
  • Non-blocking I/O: Uses epoll/kqueue for efficient I/O multiplexing
  • Event Processing: Commands processed sequentially without context switching
  • Atomicity: Single-threaded nature ensures atomic operations

Event Types:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// File events for network I/O
#define AE_READABLE     1   // Socket ready for reading
#define AE_WRITABLE     2   // Socket ready for writing

// Time events for periodic tasks
typedef struct aeTimeEvent {
    long long id;           // Time event identifier
    long when_sec;          // When to fire (seconds)
    long when_ms;           // When to fire (milliseconds)
    aeTimeProc *timeProc;   // Time event handler
} aeTimeEvent;

Network I/O Implementation:

Client Connection Handling:

  1. Accept Phase: New client connections accepted
  2. Read Phase: Commands read from client sockets
  3. Process Phase: Commands executed in Redis core
  4. Write Phase: Responses written back to clients
  5. Cleanup Phase: Closed connections handled

Buffer Management:

1
2
3
4
5
6
7
typedef struct client {
    int fd;                 // Client socket file descriptor
    sds querybuf;           // Input buffer for commands
    list *reply;            // Output buffer list
    unsigned long reply_bytes; // Bytes in output buffer
    size_t querybuf_peak;   // Peak query buffer size
} client;

Performance Optimizations:

Pipeline Support:

  • Batch Processing: Multiple commands in single network round-trip
  • Reduced Latency: Fewer network calls for better performance
  • Buffer Reuse: Efficient memory management for pipelined requests

Memory Efficiency:

  • Zero-Copy: Direct buffer manipulation where possible
  • Pooled Buffers: Reuse of network buffers
  • Lazy Deletion: Deferred cleanup of large objects

Redis Under the Hood

Redis: under the hood

Comprehensive exploration of Redis internal data structures and algorithms:

Core Data Structures:

String Implementation:

1
2
3
4
5
struct sdshdr {
    int len;        // String length
    int free;       // Available space
    char buf[];     // Actual string data
};

Features:

  • Dynamic Sizing: Automatic growth and shrinkage
  • Binary Safe: Can store any byte sequence
  • Memory Efficient: Minimal overhead compared to C strings
  • O(1) Length: Length stored, not calculated

Hash Table (Dict):

1
2
3
4
5
6
typedef struct dict {
    dictType *type;     // Type-specific functions
    void *privdata;     // Private data
    dictht ht[2];       // Two hash tables for rehashing
    int rehashidx;      // Rehashing progress (-1 if not rehashing)
} dict;

Rehashing Strategy:

  • Incremental Rehashing: Gradual migration to avoid blocking
  • Progressive: Few entries moved per operation
  • Dual Tables: Old and new tables coexist during rehashing

Advanced Features:

Expiration Mechanism:

1
2
3
4
5
6
// Expiration strategies
#define EXPIRE_STRATEGY_ACTIVE    1  // Active expiration
#define EXPIRE_STRATEGY_PASSIVE   2  // Lazy expiration

// Expire dictionary tracks TTL
dict *expires;  // Maps keys to expiration times

Implementation:

  • Active Expiration: Background task removes expired keys
  • Passive Expiration: Keys checked on access
  • Sampling: Random sampling to find expired keys efficiently

Memory Management:

  • Object Encoding: Different encodings for memory efficiency
  • Reference Counting: Shared objects for memory savings
  • Copy-on-Write: Efficient forking for persistence

Persistence Models:

RDB (Redis Database) Snapshots:

  • Fork-based: Child process handles disk I/O
  • Compressed: Efficient binary format
  • Point-in-time: Consistent snapshots
  • Configurable: Various trigger conditions

AOF (Append Only File):

  • Command Logging: Every write command logged
  • Replayable: Reconstruct state by replaying commands
  • Rewriting: Periodic compaction of log files
  • Fsync Options: Different durability guarantees

Scaling Patterns:

Replication:

M a s t e r ─ ─ ┬ β”œ β”” ─ ─ ─ ─ ─ ─ S S S l l l a a a v v v e e e 1 2 N

Features:

  • Asynchronous: Non-blocking replication
  • Partial Resync: Resume from disconnection point
  • Read Scaling: Distribute read load across replicas

Clustering:

C C C l l l u u u s s s t t t e e e r r r N N N o o o d d d e e e 1 2 3 ─ ─ ─ ┬ β”Ό β”΄ ─ ─ ─ H H H a a a s s s h h h S S S l l l o o o t t t s s s 0 5 1 - 4 0 5 6 9 4 1 2 6 - 3 0 1 - 0 1 9 6 2 3 2 8 3

Implementation:

  • Hash Slots: 16384 slots distributed across nodes
  • Client-side Routing: Clients calculate target node
  • Automatic Failover: Master failures handled automatically
  • Resharding: Live migration of slots between nodes

Performance Characteristics:

Operation Complexity:

G L L S S Z Z E P R A I A R T U A D N D A / S N D T D N S H G : E : G E / E R E T R : : : : P U S H : O O O O O O O ( ( ( ( ( ( ( 1 1 S 1 N l l ) ) + ) * o o N M g g ) ) ( ( N N w w ) ) h h ) + e e M r r ) e e w S N h = = e s s r t m e a a r l M t l = , e e s l N t e = m e s e l e n e t t m s e n r t e s t u r n e d

Memory Usage:

  • Overhead: ~20-30% overhead for Redis objects
  • Encoding Optimization: Automatic selection of efficient encodings
  • Compression: Option to trade CPU for memory savings

Production Considerations:

Configuration Tuning:

# m m # s s s # t t t a a a a a c i c M x x P v v v N p m p e m m e e e e e - e - m e e r t b o k o m m s 9 3 6 w a u e r o o i 0 0 0 o c t e y r r s 0 0 r k p y y t 1 k l 0 a - e 1 1 0 o l 2 p n 0 0 g i g o c 0 v b l e 0 5 e i 1 c 1 3 y 0 # # # 0 a l S S S l a a a k v v v e e e e y s i i i - f f f l r 1 1 1 u 0 0 k 0 e k 0 y e 0 y c s k h e a c y n h s g a e n c d g h e a i d n n g i e 9 n d 0 0 3 i 0 n s 0 e 6 c s 0 o e n c s d o e s n c d o s n d s

Monitoring Metrics:

  • Memory Usage: Watch for memory pressure
  • Command Latency: Monitor P99 latencies
  • Connection Count: Track client connections
  • Persistence Metrics: RDB/AOF performance
  • Replication Lag: Master-slave synchronization delay

Redis’s architecture demonstrates how careful design of data structures, memory management, and I/O handling can create exceptionally high-performance systems while maintaining simplicity and reliability.