当前位置:网站首页>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

边栏推荐
- Use getifaddrs to obtain the IP address of the local network interface
- Solution of win11 blue screen code 0x0000001a
- 项目管理工具——阿里云Projex介绍与实战
- 编程大杂烩(二)
- obj文件格式与.mtl文件格式
- CSDN编程挑战赛之数组编程问题
- js 页面增加过渡层
- VIM search and replacement and the use of regular expressions
- Anshi semiconductor management paid a visit to Wentai technology and Gree Electric appliance
- 深圳随到随考,科目四随到随考,科三理论第二理论随到随考说明
猜你喜欢

1310_ Implementation analysis of a printf

Wechat applet related operation examples

Pikachu vulnerability platform exercise

Go language function

Dragon Dragon community released the first Anolis OS Security Guide to escort users' business systems

Browser cache HTTP cache CDN cache localstorage / sessionstorage / cookies

Unity接入ChartAndGraph图表插件

What about reinstalling win11 system?

systemverilog中function和task区别

Introduction to kubernetes
随机推荐
background
Game 302 of leetcode
What content does the software test plan include and how to write it. Share test plan template
微服务 - 网关Gateway组件
odoo14 | 关于状态栏statusbar关键词使用后显示异常及解决方法
STL notes (VI): container vector
Array programming problem of CSDN programming challenge
VIM search and replacement and the use of regular expressions
Leetcode 204. 计数质数(太妙了)
Unity接入ChartAndGraph图表插件
LCP plug-in creates peer-to-peer 802.1ad interface
项目管理工具——项目开发者工具
Sword finger offer special shock edition day 9
AirServer 7.3.0中文版手机设备无线传送电脑屏幕工具
Oracle split branches
Shenzhen on call test, subject 4 on call test, subject 3 theory, second theory on call test instructions
编程大杂烩(二)
Performance Optimization: how to solve the slow loading speed of the first screen of spa single page application?
Anshi semiconductor management paid a visit to Wentai technology and Gree Electric appliance
ThreadLocal