Deep Dive into Redis 6 Multithreaded I/O: Architecture, Code Walkthrough, and Performance Benchmark
This article analyzes Redis 6's newly introduced multithreaded I/O feature, explains its design and code implementation, presents benchmark configurations and results that show near‑doubling of GET/SET throughput, and discusses practical considerations and limitations of the approach.
The upcoming Redis 6.0 release adds multithreaded I/O, a major change aimed at improving network throughput on multi‑core servers. The author examined the relevant source code, performed benchmark tests, and reported the performance impact.
Design Overview
Redis still executes commands in a single thread; the new threads only handle network reads/writes and protocol parsing. The main thread accepts connections, places read events into a global pending‑read queue, then distributes those connections to a pool of I/O threads using round‑robin scheduling. The I/O threads process the data and return control to the main thread, which finally executes the commands.
Key Code Snippets
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
/* Check if we want to read from the client later when exiting from
* the event loop. This is the case if threaded I/O is enabled. */
if (postponeClientRead(c)) return;
...
} int postponeClientRead(client *c) {
if (io_threads_active &&
server.io_threads_do_reads &&
!(c->flags & (CLIENT_MASTER|CLIENT_SLAVE|CLIENT_PENDING_READ))) {
// Mark connection to avoid re‑adding to the queue
c->flags |= CLIENT_PENDING_READ;
// Add to pending‑read list
listAddNodeHead(server.clients_pending_read, c);
return 1;
} else {
return 0;
}
} int handleClientsWithPendingReadsUsingThreads(void) {
...
listRewind(server.clients_pending_read, &li);
int item_id = 0;
while ((ln = listNext(&li))) {
client *c = listNodeValue(ln);
int target_id = item_id % server.io_threads_num;
listAddNodeTail(io_threads_list[target_id], c);
item_id++;
}
...
while (1) {
unsigned long pending = 0;
for (int j = 0; j < server.io_threads_num; j++)
pending += io_threads_pending[j];
if (pending == 0) break;
}
} void *IOThreadMain(void *myid) {
while (1) {
listRewind(io_threads_list[id], &li);
while ((ln = listNext(&li))) {
client *c = listNodeValue(ln);
if (io_threads_op == IO_THREADS_OP_WRITE) {
writeToClient(c->fd, c, 0);
} else if (io_threads_op == IO_THREADS_OP_READ) {
readQueryFromClient(NULL, c->fd, c, 0);
} else {
serverPanic("io_threads_op value is unknown");
}
}
listEmpty(io_threads_list[id]);
io_threads_pending[id] = 0;
}
}The implementation is lock‑free because the main thread spins until all I/O threads finish their work, avoiding data races.
Performance Comparison
Benchmarks were run on two identical Alibaba Cloud Ubuntu 18.04 instances (8 CPU × 2.5 GHz, 8 GB RAM). The multithreaded build used the unstable branch with the following configuration:
io-threads 4 # enable four I/O threads
io-threads-do-reads yes # also parse requests in I/O threadsThe benchmark command was:
redis-benchmark -h 192.168.0.49 -a foobared -t set,get -n 1000000 -r 100000000 --threads 4 -d ${datasize} -c 256Results show that GET/SET throughput roughly doubled when using four I/O threads compared with the single‑threaded Redis 5.0.5 baseline. The graphs (omitted here) illustrate the near‑2× improvement.
Note that the standard redis-benchmark tool is single‑threaded; for accurate multithreaded testing the benchmark binary must be compiled from the same unstable source.
Conclusion
Redis 6.0’s multithreaded I/O can significantly boost network‑bound workloads without complicating command execution, which remains single‑threaded. The design avoids locks by having the main thread wait for all I/O threads, though it may cause CPU spin when the pending queue is empty. Future versions may refine thread management (e.g., using condition variables).
Redis 6.0 is expected to be released by the end of 2019, bringing additional performance, protocol, and security enhancements, as well as a new cluster proxy component.
High Availability Architecture
Official account for High Availability Architecture.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.