当前位置:网站首页>Talk about how redis handles requests
Talk about how redis handles requests
2022-07-25 05:28:00 【qq_ forty-three million four hundred and seventy-nine thousand 】
High quality resource sharing
| Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
|---|---|---|
| 🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
| Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |
Please state the source of reprint ~, This article was published at luozhiyun The blog of :https://www.luozhiyun.com/archives/674
This article uses Redis 5.0 Source code
I think this part of the code is quite interesting , I try to explain it in a more popular way
summary
I remember I was Let's make it clear Go Language HTTP Standard library In this article, it is analyzed that Go How to create a Server End program :
- The first is to register the processor ;
- Open the loop listening port , Every time you hear a connection, you create one Goroutine;
- Then is Goroutine There will be a loop waiting to receive the request data , Then according to the requested address to match the corresponding processor in the processor routing table , Then the request is sent to the processor for processing ;
In code, that's it :
Copyfunc (srv *Server) Serve(l net.Listener) error {
...
baseCtx := context.Background()
ctx := context.WithValue(baseCtx, ServerContextKey, srv)
for {
// receive listener Network connection over here
rw, err := l.Accept()
...
tempDelay = 0
c := srv.newConn(rw)
c.setState(c.rwc, StateNew)
// Create coprocessing connection
go c.serve(connCtx)
}
}
about Redis It's a little different , Because it's single threaded , Cannot use multithreading to process connections , therefore Redis Select Use Based on Reactor Mode event driver to realize the concurrent processing of events .

stay Redis Zhongso Reactor The pattern is through epoll To monitor multiple fd, Whenever these fd When there is a response, it will be notified in the form of an event epoll Make a callback , Each event has a corresponding event handler .
Such as : accept Corresponding acceptTCPHandler Event handler 、read & write Corresponding readQueryFromClient Event handlers, etc , Then, the event is allocated to the event processor for processing in the form of circular distribution of events .
So this one above Reactor Patterns are all through epoll To achieve , about epoll There are three main methods :
Copy// Create a epoll The handle of ,size Used to tell the kernel how many monitors there are in total
int epoll\_create(int size);
/*
* It can be understood as , Additions and deletions fd Events that need to be monitored
* epfd yes epoll\_create() Created handle .
* op Express Additions and deletions
* epoll\_event Indicates the event to be monitored ,Redis Only readable , Can write , error , Hang up Four states
*/
int epoll\_ctl(int epfd, int op, int fd, struct epoll\_event *event);
/*
* It can be understood as querying qualified Events
* epfd yes epoll\_create() Created handle .
* epoll\_event Used to store the collection of events obtained from the kernel
* maxevents Maximum number of events obtained
* timeout Waiting timeout
*/
int epoll\_wait(int epfd, struct epoll\_event * events, int maxevents, int timeout);
So we can implement a simple server:
Copy// Create a listener
int listenfd = ::socket();
// binding ip And port
int r = ::bind();
// establish epoll example
int epollfd = epoll_create(xxx);
// add to epoll The type of event to listen for
int r = epoll_ctl(..., listenfd, ...);
struct epoll\_event* alive\_events = static_cast(calloc(kMaxEvents, sizeof(epoll\_event)));
while (true) {
// Events wait
int num = epoll\_wait(epollfd, alive\_events, kMaxEvents, kEpollWaitTime);
// Traversal Events , And handle the event
for (int i = 0; i < num; ++i) {
int fd = alive\_events[i].data.fd;
// Get events
int events = alive\_events[i].events;
// Distribution of events
if ( (events & EPOLLERR) || (events & EPOLLHUP) ) {
...
} else if (events & EPOLLRDHUP) {
...
}
...
}
}
Calling process
So according to the above introduction , You know, for Redis There are only a few steps in an event cycle :
- Register event listening and callback functions ;
- Loop waiting to get the event and handle ;
- Call callback function , Processing data logic ;
- Write back data to Client;

- register fd To epoll in , And set the callback function acceptTcpHandler, If there is a new connection, the callback function will be called ;
- Start an endless loop call epoll_wait Wait and continue to handle the event , We will return to aeMain Loop call in function aeProcessEvents function ;
- When a network incident comes , Will follow the callback function acceptTcpHandler Call all the way to readQueryFromClient Data processing ,readQueryFromClient Can parse client The data of , Find the corresponding cmd Function execution ;
- Redis After the instance receives the client request , After processing the client command , Write the data to be returned to the client output buffer instead of returning immediately ;
- And then in aeMain Every time the function loops, it calls beforeSleep Function writes the data in the buffer back to the client ;
In fact, the code steps of the whole event cycle above have been written very clearly , There are also many articles on the Internet , I won't talk more .
Command execution process & Write back client
Command execution
Now let's talk about some things that are not mentioned in many online articles , have a look Redis How to execute commands , And then it's stored in the cache , And write data back from the cache Client This process .

In the previous section, we also mentioned , If a network event comes, it will call readQueryFromClient function , It's where the orders are actually executed . We just follow this method and keep looking down :
- readQueryFromClient It will call processInputBufferAndReplicate Function to process the requested command ;
- stay processInputBufferAndReplicate It's called inside the function processInputBuffer And judge if it is a cluster mode , Whether you need to copy commands to other nodes ;
- processInputBuffer The function will cycle through the requested commands , And call according to the requested Protocol processInlineBuffer function , take redisObject Call after object processCommand Carry out orders ;
- processCommand When executing the order, it will pass lookupCommand Go to
server.commandsFind the corresponding execution function according to the command in the table , Then after a series of checks , Call the corresponding function to execute the command , call addReply Write the data to be returned to the client output buffer ;
server.commands Will be in populateCommandTable In the function, all Redis Order to register , As a table that gets command functions according to the command name .
for instance , To execute get command , Then it will call getCommand function :
Copyvoid getCommand(client *c) {
getGenericCommand(c);
}
int getGenericCommand(client *c) {
robj *o;
// Find data
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL)
return C_OK;
...
}
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) {
// To db Find data in
robj *o = lookupKeyRead(c->db, key);
// Write to cache
if (!o) addReply(c,reply);
return o;
}
stay getCommand Data found in function , And then call addReply Write the data to be returned to the client output buffer .
Data write back client
After executing the command above and writing to the buffer , You also need to fetch data from the buffer and return it to Client. For the process of writing data back to the client , In fact, it is also completed in the event cycle of the server .

- First Redis Will be in main Call in function aeSetBeforeSleepProc The function will write back to the function of the package beforeSleep Sign up to eventLoop In the middle ;
- then Redis Calling aeMain Functions will judge when they cycle events beforesleep Is it set , If there is , Then it will be called ;
- beforesleep Function will call handleClientsWithPendingWrites function , It will be called writeToClient Write data back from the buffer to the client ;
summary
This article introduces the whole Redis What is the request processing model of . Listen from registration fd Event to execute command , At last, I wrote the data back to the client and made a general analysis . Of course, this article is also a little different from my previous articles , No lengthy post code , Mainly, I don't think it's necessary , Interested can follow the flow chart to see the code .
Reference
http://www.dre.vanderbilt.edu/~schmidt/PDF/reactor-siemens.pdf
https://time.geekbang.org/column/article/408491
http://remcarpediem.net/article/1aa2da89/
https://github.com/Junnplus/blog/issues/37
https://blog.csdn.net/neooelric/p/9629948.html

边栏推荐
猜你喜欢

STL notes (IV): String

C编程 --“最大子数组的和” 的动态规划的解法

Easyrecovery free data recovery tool is easy to operate and restore data with one click

Realsense d435i depth map optimization_ High precision mode

SystemVerilog中interface(接口)介绍

C Programming -- the solution of dynamic programming of "the sum of the largest subarray"
![2022-07-24: what is the output of the following go language code? A:[]int{}; B:[]int(nil); C:panic; D: Compilation error. package main import ( “fmt“ ) f](/img/bf/e38a8fd813f88a83f61a1abfa3b95d.png)
2022-07-24: what is the output of the following go language code? A:[]int{}; B:[]int(nil); C:panic; D: Compilation error. package main import ( “fmt“ ) f

1310_一个printf的实现分析

Win11 how to view the file explorer tab

Introduction to base ring tree
随机推荐
How to carry out the function test with simple appearance and complex interior?
Sword finger offer II 014. anagrams in strings
微服务 - 配置中心 - Nacos
obj文件格式与.mtl文件格式
深圳随到随考,科目四随到随考,科三理论第二理论随到随考说明
The price is 17300! Why does Huawei mate x face Samsung fold?
自己实现is_class
H5 new feature domcontentloaded event - custom attribute -async attribute -history interface method - local storage -postmessage
Realsense d435i depth map optimization_ High precision mode
Necessary skills for mobile terminal test: ADB command and packet capturing
Three schemes for finclip to realize wechat authorized login
systemverilog中function和task区别
Pikachu vulnerability platform exercise
Implement is by yourself_ class
Introduction to base ring tree
Shenzhen on call test, subject 4 on call test, subject 3 theory, second theory on call test instructions
Learning records [email protected] R & D effectiveness measurement indicators
C Programming -- the solution of dynamic programming of "the sum of the largest subarray"
STL notes (II): template and operator overloading
Add transition layer to JS page