This is article 48 in the Big Data series. This article provides an in-depth analysis of Redis communication protocol RESP and Reactor-based event-driven architecture.
Full illustrated version (with screenshots): CSDN Original | Juejin
Why Understanding Redis Underlying Communication?
Redis is known for “single-threaded command processing yet handling high concurrency.” This relies on two core designs: RESP protocol ensures efficient, lightweight network communication; Reactor event-driven model enables single-threaded I/O multiplexing. Understanding these two is the foundation for deep Redis tuning and troubleshooting connection issues.
RESP Protocol (Redis Serialization Protocol)
RESP is a lightweight serialization protocol custom-designed by Redis. Design goals are simplicity, efficiency, good readability, and binary-safe data handling.
Five Data Types
| Type | First Byte | Example |
|---|---|---|
| Simple String | + | +OK\r\n |
| Error | - | -ERR unknown command\r\n |
| Integer | : | :1000\r\n |
| Bulk String | $ | $6\r\nfoobar\r\n |
| Array | * | *2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n |
All data ends with \r\n (CRLF), fixed format, extremely low parsing cost.
Request and Response Example
When client executes SET mykey myvalue, the actual bytes sent:
*3\r\n
$3\r\nSET\r\n
$5\r\nmykey\r\n
$7\r\nmyvalue\r\n
Server returns:
+OK\r\n
RESP’s design makes protocol parsing implementable in dozens of lines of code, greatly reducing client library development difficulty.
Communication Patterns
Serial Mode
Client sends request, waits for response, then sends next request. Each RTT (Round-Trip Time) is pure network overhead, throughput limited by latency.
Pipeline Mode
Pipeline allows client to batch send multiple commands, not waiting for each command’s response. Server processes all commands then returns results together, compressing multiple RTTs into one.
Jedis Pipeline Example:
Jedis redis = new Jedis("host", 6379);
Pipeline pipe = redis.pipelined();
for (int i = 0; i < 50000; i++) {
pipe.set("key_" + i, String.valueOf(i));
}
pipe.sync(); // Send all and wait for responses together
Pipeline can improve performance by 10x or more in batch write scenarios, but note that the number of commands in a single Pipeline shouldn’t be too large (recommended 100-1000), to avoid transferring too much data at once.
Reactor Event-Driven Model
Redis uses single-threaded + I/O multiplexing architecture, processing large numbers of concurrent connections efficiently through Reactor pattern.
I/O Multiplexing Mechanism Comparison
| Mechanism | Platform | Max FD | Scan Method | Performance |
|---|---|---|---|---|
select | Cross-platform | 1024 (FD_SETSIZE) | Linear scan | Low |
poll | Cross-platform | Unlimited | Linear scan | Medium |
epoll | Linux | ~100,000 | Event notification | High |
kqueue | BSD/macOS | ~100,000 | Event notification | High |
Redis uses epoll on Linux, only wakes up when events are ready, no ineffective polling — this is key to supporting high concurrency.
Core Data Structures
aeEventLoop (Event Loop)
├── FileEvent[] ← Monitor read/write events of sockets
└── TimeEvent[] ← Scheduled tasks (e.g., serverCron)
Complete Request Processing Flow
1. Client connect → epoll detects connection event
2. acceptTcpHandler establishes connection, registers read event
3. Client sends command → triggers readable event
4. readQueryFromClient reads data, parses command per RESP protocol
5. Command handler executes business logic, writes to response buffer
6. Register write event → sendReplyToClient sends result back to client
The entire flow executes serially in the single-threaded event loop, with no thread switching or lock contention. This is the root of Redis command processing high performance.
Single-Threaded Architecture Pros and Cons
Advantages:
- No context switching overhead, no lock contention
- Data structure implementation doesn’t need to consider concurrency safety
- Simple code logic, easy to maintain and debug
Limitations:
- Limited to single CPU core, cannot utilize multiple cores
- Time-consuming commands (like
KEYS *, largeLRANGE) block the entire event loop - Big key read/write and delete operations cause other request latencies to increase
Redis 6.0 Multi-Threaded I/O
Redis 6.0 introduces multi-threaded network I/O (reading requests and sending responses handled by multiple threads), but command execution remains single-threaded. This solves the problem of network I/O becoming a bottleneck while maintaining serial command execution, avoiding complex concurrency control.
# Enable multi-threaded I/O in redis.conf (off by default)
io-threads 4
io-threads-do-reads yes
Summary
Redis’s high performance comes from three layers of clever design:
- RESP protocol: Lightweight and efficient, simple parsing, supports Pipeline batch processing
- epoll multiplexing: Single thread monitors tens of thousands of connections, only processes ready events
- Reactor event loop: Unifies network I/O and command execution in single thread, avoiding concurrency overhead