Redis I/O Multiplexing: Design, Implementation, and Code Walkthrough

This article examines Redis's I/O multiplexing mechanism, explaining why it uses non‑blocking models, detailing the Reactor pattern, comparing select, epoll, and kqueue, and providing a thorough walkthrough of the underlying C code that implements event creation, addition, deletion, and polling across platforms.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Redis I/O Multiplexing: Design, Implementation, and Code Walkthrough

Redis runs in a single thread, so any blocking I/O operation would stall the whole server. To keep the service responsive to many clients, Redis adopts I/O multiplexing, which monitors multiple file descriptors (FDs) simultaneously.

Traditional blocking I/O reads or writes a FD only when it is ready; otherwise the entire process blocks. This model is simple but unsuitable for high‑concurrency servers.

Redis primarily uses the select system call for I/O multiplexing, though it can also employ epoll, kqueue, or evport depending on the platform. The select function monitors sets of readable and writable FDs and returns the count of ready descriptors.

The server follows the Reactor design pattern: a single event loop watches for events and dispatches them to handlers. Each network connection corresponds to a FD, and events such as accept, read, write, and close trigger callbacks.

The I/O multiplexing module abstracts the underlying system calls, exposing a uniform API. It defines functions like aeApiCreate, aeApiAddEvent, aeApiDelEvent, and aeApiPoll that operate on an internal aeApiState structure.

static int aeApiCreate(aeEventLoop *eventLoop) {
    aeApiState *state = zmalloc(sizeof(aeApiState));
    if (!state) return -1;
    FD_ZERO(&state->rfds);
    FD_ZERO(&state->wfds);
    eventLoop->apidata = state;
    return 0;
}
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
    aeApiState *state = eventLoop->apidata;
    if (mask & AE_READABLE) FD_SET(fd, &state->rfds);
    if (mask & AE_WRITABLE) FD_SET(fd, &state->wfds);
    return 0;
}
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    aeApiState *state = eventLoop->apidata;
    int retval, j, numevents = 0;
    memcpy(&state->_rfds, &state->rfds, sizeof(fd_set));
    memcpy(&state->_wfds, &state->wfds, sizeof(fd_set));
    retval = select(eventLoop->maxfd+1, &state->_rfds, &state->_wfds, NULL,
                   tvp ? tvp : NULL);
    if (retval > 0) {
        for (j = 0; j <= eventLoop->maxfd; j++) {
            int mask = 0;
            if (eventLoop->events[j].mask != AE_NONE &&
                FD_ISSET(j, &state->_rfds)) mask |= AE_READABLE;
            if (eventLoop->events[j].mask != AE_NONE &&
                FD_ISSET(j, &state->_wfds)) mask |= AE_WRITABLE;
            if (mask) {
                eventLoop->fired[numevents].fd = j;
                eventLoop->fired[numevents].mask = mask;
                numevents++;
            }
        }
    }
    return numevents;
}

On Linux, Redis prefers epoll for its O(1) scalability; on macOS/FreeBSD it uses kqueue; otherwise it falls back to select. The selection is performed via compile‑time macros, ensuring the best available mechanism is used without changing the upper‑level code.

By encapsulating these system‑specific calls behind a common interface, Redis can serve tens of thousands of connections in a single‑threaded process while keeping the codebase simple and portable.

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.

Backend DevelopmentredisI/O MultiplexingReactor Patternepollselectevent loopkqueue
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

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.