gx

Redis - Event Library

Posted at — Apr 9, 2022

This is my notes taken while reading Redis.

Current commits: 3bcc67d14f5fcdfb1a44e216fe4aaef3533028f8.

The main function of Redis is located in src/server.c. In main function, after lots of preparation is done, the server is launched and begin to loop registed events. The processing of registered events is done by a event library implemented by Redis.

What is an event library?

When a network server is launched, it should watch for all inbound connections on the port it’s listening and aceept them. After accepting a request, the server will save the descriptor and do non-blocking operations on it. If the operations are blocking, then the server cannot accept other requests before the opertations are done.

Event library helps to archieve such behavior by the operation system’s polling facility and timers. The library API usually provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. There are some famous libraries, like libevent, libev, libuv.

Redis implements its own event library, defined in src/ae.c. (There is some discussions in the mailing list.) The remained part of this article will introduce how it works.

Initialization

First let us have a look at how the event loop in Redis looks like, where the file events are arranged in arraies indexed by file descriptors and the time events are organized in a linked list. The memory space of those containers is allocated during the initialization of the event loop. The API data is created and used by operation system’s polling facility.

Event Loop
 |--Registered File Events
 |--Fired File Events
 |--Time Events
 |--Pre-process Function of Sleeping
 |--Post-process Function of Sleeping
 `--API Data

During the initialization of a Redis server, a event loop is created and some events are registered in the event loop.

Time Events

Below is how a time event looks like in Redis. The finalizer function will be used when the time event is deleted.

Time Event
 |--The Time to Process
 |--Process Function
 |--Finalizer Process Function
 `--Data of Client

During the initialization of Redis server, a time event is registered with process function, serverCron. The serverCron conducts a number of things that need to be done asynchronously every server.hz times per second.

File Events

Here is how a file event in Redis looks like:

File Event
 |--The Mask of File
 |--Process Function for Readable File
 |--Process Function for Writable File
 `--Data Provided by Client

When a file event is created, the event will also be added into OS’s polling facility. During the initialization of server, several file events are registered to accept and handle new connections in TCP, TLS and UNIX socket. There is also a event registered to watch the module pipe to awake the event loop from module thread.

Polling

Operation system provides some facility to help I/O multiplexing. Redis picks the one with best performance to implement its event loop during compiling. In Linux, epoll is picked. In BSD, kqueue is picked.

Redis maintains the data of multiplexing API by its internal structure and stores it in the “API Data” part of the event loop. The interaction with those system calls are wrapped as aeApi, used by file events. aeApi gets available file descriptors and places then in the fired file events of the event loop.

Process the Event Loop

Redis server processes the event in an endless loop after the server is initialized. The step of processing is as below.

That’s all. Thanks for reading.