Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the function of event-driven model in Redis

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces what is the role of the event-driven model in Redis, the content is very detailed, interested friends can refer to, I hope it can be helpful to you.

Preface

Redis is an event-driven in-memory database, and the server needs to handle two types of events.

File event

Time event

The implementation principles of these two events are described below.

File event

The Redis server interacts with the client (or other redis server) through socket, and the file event is the server's abstraction of socket operations. The Redis server responds to client calls by listening to these socket-generated file events and processing them.

Reactor

Redis developed its own event handler based on the Reactor pattern.

Let's start with the Reactor model. Look at the following picture:

The "FD O Multiplexing Module" listens for multiple FD, when these FD are generated, file events of accept,read,write or close. Events are delivered to the File event Distributor (dispatcher).

After receiving the event, the File event Distributor (dispatcher) distributes the event to the corresponding handler according to the type of event.

We follow the diagram and explain how Redis implements this Reactor model one by one from top to bottom.

Ipaw O multiplexing module

In fact, Redis's Icano multiplexing module encapsulates the basic functions such as select,epoll,avport and kqueue provided by the operating system. A unified interface is provided to the upper layer, shielding the details of the underlying implementation.

Generally speaking, Redis is deployed on Linux systems, so let's take a look at how we can use Redis to implement IRedis O multiplexing using the epoll provided by linux.

First, take a look at the three methods provided by epoll:

/ * * create a handle to epoll, and size is used to tell the kernel the total number of listeners * / int epoll_create (int size); / * * it can be understood that adding, deleting and modifying events to be listened to by fd * epfd is a handle created by epoll_create (). * op indicates addition, deletion and modification * epoll_event refers to events that need to be monitored. Redis only uses four states: readable, writable, error and hang up * / int epoll_ctl (int epfd, int op, int fd, struct epoll_event * event); / * can be understood as querying qualified events * epfd is a handle created by epoll_create (). * epoll_event is used to store the collection of events obtained from the kernel * maximum number of events obtained by maxevents * timeout wait timeout * / int epoll_wait (int epfd, struct epoll_event * events, int maxevents, int timeout)

Let's take a look at Redis to file events, encapsulating the interface provided by epoll:

/ * * event status * / typedef struct aeApiState {/ / epoll_event instance descriptor int epfd; / / event slot struct epoll_event * events;} aeApiState / * * create a new epoll * / static int aeApiCreate (aeEventLoop * eventLoop) / * * resize event slots * / static int aeApiResize (aeEventLoop * eventLoop, int setsize) / * * release epoll instances and event slots * / static void aeApiFree (aeEventLoop * eventLoop) / * * associate a given event to fd * / static int aeApiAddEvent (aeEventLoop * eventLoop, int fd, int mask) / * * delete a given event from fd * / static void aeApiDelEvent (aeEventLoop * eventLoop, int fd) Int mask) / * * get executable event * / static int aeApiPoll (aeEventLoop * eventLoop, struct timeval * tvp)

So take a look at how this ae_peoll.c encapsulates epoll:

AeApiCreate () is an encapsulation of epoll.epoll_create ().

AeApiAddEvent () and aeApiDelEvent () are wrappers for epoll.epoll_ctl ().

AeApiPoll () is an encapsulation of epoll_wait ().

In this way, Redis's use of epoll to implement the Imax O multiplexer is relatively clear.

To the next level, we need to see how ea.c is encapsulated.

The first thing to focus on is the data structure of the event handler:

Typedef struct aeFileEvent {/ / listen for event type mask, / / value can be AE_READABLE or AE_WRITABLE, / / or AE_READABLE | AE_WRITABLE int mask; / * one of AE_ (READABLE | WRITABLE) * / / read event handler aeFileProc * rfileProc; / / write event handler aeFileProc * wfileProc; / / Private data void * clientData;} aeFileEvent of the multiplexing library

Mask is the type of event that can be understood.

In addition to using the methods provided by ae_peoll.c, ae.c also adds several "add and delete" API.

Add: aeCreateFileEvent

Delete: aeDeleteFileEvent

Check: check includes two dimensions: aeGetFileEvents gets the listening type of a certain fd and aeWait waits for a certain fd until it times out or reaches a certain state.

Event dispatcher (dispatcher)

Redis's event dispatcher ae.c/aeProcessEvents handles not only file events but also time events, so here only some of the code related to file distribution is posted, and dispather calls different event handlers according to mask.

/ / events of interest from epoll numevents = aeApiPoll (eventLoop, tvp); for (j = 0; j

< numevents; j++) { // 从已就绪数组中获取事件 aeFileEvent *fe = &eventLoop->

Events [eventLoop-> fired.fd]; int mask = eventLoop- > fired.mask; int fd = eventLoop- > fired.fd; int rfired = 0; / read event if (fe- > mask & mask & AE_READABLE) {/ / rfired ensures that read / write events can only execute one of rfired = 1; fe- > rfileProc (eventLoop,fd,fe- > clientData,mask) } / / write event if (fe- > mask & mask & AE_WRITABLE) {if (! rfired | | fe- > wfileProc! = fe- > rfileProc) fe- > wfileProc (eventLoop,fd,fe- > clientData,mask);} processed++;}

You can see this dispatcher, which distributes events to read events and write events depending on the mask.

Type of file event handler

Redis has a large number of event handler types, so let's talk about the three handlers involved in processing a simple command:

The acceptTcpHandler connection reply processor is responsible for handling connection-related events, and AE_READABLE events are generated when a client is connected to the Redis. Trigger it to execute.

The readQueryFromClinet command requests the processor, which is responsible for reading commands sent through sokect.

The sendReplyToClient command replies to the processor, and when the Redis finishes processing the command, an AE_WRITEABLE event is generated to return the data to client.

Summary of file event implementation

We explained the implementation of the file event handler from top to bottom according to the Reactor model given at the beginning, and we will introduce the implementation of time and time below.

Time event

Reids has many operations that need to be handled at a given point in time, and time events are abstractions of such scheduled tasks.

Let's first look at the data structure of time events:

/ * Time event structure * * time event structure * / typedef struct aeTimeEvent {/ / the unique identifier of the time event long long id; / * time event identifier. * / / the arrival time of the event long when_sec; / * seconds * / long when_ms; / * milliseconds * / / event handling function aeTimeProc * timeProc; / / event release function aeEventFinalizerProc * finalizerProc; / / the private data of the multiplexing library void * clientData; / / points to the next time event structure, forming a linked list struct aeTimeEvent * next;} aeTimeEvent

When we see the next, we know that the aeTimeEvent is a linked list structure. Look at the picture:

Note: this is a linked list in reverse order of id, not in the order of events.

ProcessTimeEvent

Redis uses this function to handle all time events. Let's sort out the execution ideas:

Record the last time this function was executed to deal with the problem caused by the modification of the system time.

Traverse the linked list to find all events whose when_sec and when_ms are less than the current time.

Executes the handler function corresponding to the event.

Check the event type, and if it is a periodic event, refresh the next execution event for that event.

Otherwise, remove the event from the list.

Integrated scheduler (aeProcessEvents)

The integrated scheduler is where Redis handles all events uniformly. Let's sort out the simple logic of this function:

/ / 1. Get the time event shortest = aeSearchNearestTimer (eventLoop) closest to the current time; / / 2. Get interval timeval = shortest-nowTime;// if timeval is less than 0, there are already time events that need to be executed. If (timeval

< 0){ timeval = 0}// 3. 在 timeval 时间内,取出文件事件。numevents = aeApiPoll(eventLoop, timeval);// 4.根据文件事件的类型指定不同的文件处理器if (AE_READABLE) { // 读事件 rfileProc(eventLoop,fd,fe->

ClientData,mask);} / / write event if (AE_WRITABLE) {wfileProc (eventLoop,fd,fe- > clientData,mask);}

The pseudo code above is the logic of the entire Redis event handler.

We can see who executed the aeProcessEvents again:

Void aeMain (aeEventLoop * eventLoop) {eventLoop- > stop = 0; while (! eventLoop- > stop) {/ / if there is a function that needs to be executed before event processing, run it if (eventLoop- > beforesleep! = NULL) eventLoop- > beforesleep (eventLoop); / / start processing event aeProcessEvents (eventLoop, AE_ALL_EVENTS);}}

Then we'll see who called eaMain:

Int main (int argc, char * * argv) {/ / some configuration and preparation. AeMain (server.el); / / Recycling after completion.}

We found it in Redis's main method.

The train of thought we sorted out at this time is:

The main () method of Redis invokes the eaMain () method after performing some configuration and preparation.

Call aeProcessEvents () for eaMain () while (true).

So we said that Redis is an event-driven program, during which we found that Redis did not fork any threads. So it can also be said that Redis is an event-driven single-threaded application.

About what the role of the event-driven model in Redis is shared here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report