How Redis Handles File and Time Events: Inside the Event Loop
This article explains Redis server's event-driven architecture, detailing how file events (read/write) and time events are processed, illustrated with state diagrams, pseudocode, and examples that show the interaction, scheduling, and impact on server performance.
File Events
Redis uses an event‑driven, multiplexed architecture. Each client connection is represented by a socket, and the server interacts with the socket only when it becomes readable or writable without blocking.
Read Events
A read event tracks the state of a client’s command request. When a client connects, Redis registers a read event for that socket; the event is removed only when the client disconnects.
Waiting – the client is connected but has not sent a command.
Ready – the client has sent a command and the socket is readable.
Example of Read Events
Three clients (A, B, C) are connected but have not issued any commands; all three are in the waiting state.
When client A sends a command that reaches the server, its read event transitions to ready and the command status becomes "sent and arrived".
Write Events
A write event indicates that the server has a result to return to a client. The server creates a write event only when a result is ready; after the result is sent, the write event is removed.
Waiting – the server has a result but the client socket is not currently writable.
Ready – the client socket is writable, allowing a non‑blocking write.
Example of Write Events
Server is waiting for client A to become writable so it can return the cached result.
When A’s socket becomes writable, the write event becomes ready , the server sends the result, and the client’s write‑event state changes to ready .
After the result is delivered, the association between the client and the write event is removed, leaving only the read event.
Simultaneous Read/Write Events
A client can have both read and write events attached, but the event handler processes only one at a time. When both events are ready, the handler gives priority to the read event (new command) before handling the write event (returning a result).
Time Events
Time events are scheduled actions that run at specific timestamps. Redis stores them in an unordered linked list inside the server state.
Because the list is typically very short (often a single element), the unordered structure does not affect performance.
One‑off events: the handler returns AE_NOMORE; the event runs once and is then deleted.
Recurring events: any other integer is returned; the event’s when field is updated to now + retval so the event will run again later.
Pseudocode for handling a time event
def handle_time_event(server, time_event):
retval = time_event.timeProc()
if retval == AE_NOMORE:
server.time_event_linked_list.delete(time_event)
else:
time_event.when = unix_ts_in_ms() + retvalProcessing all time events
def process_time_event(server):
for time_event in server.time_event_linked_list:
if time_event.when <= unix_ts_in_ms():
handle_time_event(server, time_event)The recurring serverCron time event performs regular maintenance tasks such as updating statistics, cleaning expired keys, adjusting database sizes, closing idle clients, attempting AOF/RDB persistence, and synchronizing replicas or clusters.
In Redis 2.6, serverCron runs 10 times per second (every 100 ms). The frequency can be changed with the hz configuration option in later versions.
Scheduling of File and Time Events
The event loop first processes ready file events (incoming commands) and then handles due time events. The maximum poll timeout is determined by the nearest upcoming time event, so a long‑running file event can postpone time‑event execution.
Typical Main Loop
def redis_main():
init_server()
while server_is_not_shutdown():
# Determine the nearest time event
te = get_nearest_time_event(server.time_event_linked_list)
timeout_ms = te.when - now_in_ms()
if timeout_ms <= 0:
# At least one time event is ready; poll without timeout
poll(timeout=None)
else:
# Block only until the next time event is due
poll(timeout=timeout_ms)
# Process any ready file events first
process_file_events()
# Then process due time events
process_time_event()
clean_server()This design guarantees that file events have priority over time events, and that the poll timeout never exceeds the interval to the next scheduled time event.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JavaEdge
First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.
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.
