# The reason why Nginx is faster than Apache http server and Redis is fast only using single-thread --- # The C10K problem http://www.kegel.com/c10k.html --- # File descriptor ![](https://i.imgur.com/yDwJYJC.png) One basic concept of Linux (actually Unix) is the rule that everything in Unix/Linux is a file. Each process has a table of file descriptors that point to files, sockets, devices and other operating system objects. --- # Network I/O model ![](https://i.imgur.com/h4Upqjg.png) - Signal I/O ---- ## Blocking I/O ![](https://i.imgur.com/SryVIKI.png) While a request comes, the application(user space) will ask kernel that data is ready or not and it will block until kernel responds. ---- ## non-Blocking I/O ![](https://i.imgur.com/kdF4VoJ.png) It just like polling. ---- ## I/O multiplexing ![](https://i.imgur.com/gVTvmAN.png) ---- ![](https://i.imgur.com/Ex7oN1y.png) ---- ### select ![](https://i.imgur.com/VftndTU.png) `int select(int maxfd,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout){}` https://man7.org/linux/man-pages/man2/select.2.html ---- ``` #include <stdio.h> #include <stdlib.h> #include <sys/select.h> int main(void) { fd_set rfds; struct timeval tv; int retval; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Don't rely on the value of tv now! */ if (retval == -1) perror("select()"); else if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n"); exit(EXIT_SUCCESS); } ``` ---- ### cons of select 1. It polls all the fds to find which changed (O(n)) 2. It only allows to monitor 1024 fds in a thread. 3. Need to copy fd from user space to kernel space. ---- ### poll `poll` is just like `select` but it fixes the second problem of `select` `int poll(struct pollfd *fds, nfds_t nfds, int timeout);` https://man7.org/linux/man-pages/man2/poll.2.html ---- ### epoll, kqueue You can take `epoll` as event sourcing. `select` and `poll` only provide a API to use it. But `epoll` provides 3 Apis. 1. `int epoll_create(int size);` 2. `int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);` 3. `int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);` https://man7.org/linux/man-pages/man7/epoll.7.html ---- ### How does epoll solve problems? 1. `epoll` only listens to the ready list to know which fd is ready so it solve the first problem of `select`. 2. `epoll` can watch more than 1024 fds. 3. `epoll` use mmap to share memory between kernel space and user space to solve the third problem of `select`. ---- ### Benchmark ![](https://i.imgur.com/wOn9zw6.jpg) ---- ## Signal I/O ![](https://i.imgur.com/CccFW2J.png) ---- ## Asynchronous I/O ![](https://i.imgur.com/UDqx28h.png) --- # Why redis is fast We all know that Redis is a single-thread service, and it is very fast. Not only because it operates in memory but also it uses I/O multiplexing to handle the connections. And redis uses reactor pattern to deal with multiple connections. ---- ![](https://i.imgur.com/tjyLCaO.png) ---- ## Redis server.c ![](https://i.imgur.com/M920CDF.png) https://www.modb.pro/db/232774 https://juejin.cn/post/6844904160710623246 --- ## Why nginx is better than Apache http server while the amount of connections is large. Nginx uses I/O multiplexing as its network model furthur more it prefers to use epoll if the OS support it. But Apache httpd (before 2.4) uses Blocking I/O model for both worker and prefork mode. - Prefork mode: Process mode. Each request is handled by a child process. Thread safety. Not suitable for high-concurrency servers. - Worker mode: Process thread mixed mode. The parent process will create child processes, and each child process will create multiple worker threads and a listener thread. Each thread is responsible for processing an http request. Fortunatly, Aapche httpd 2.4 supports event mode and it bases on I/O multiplexing like Nginx. https://httpd.apache.org/docs/2.4/mpm.html#defaults ---- ## How a normal web server works ![](https://i.imgur.com/D4iFCU8.png) https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/ ---- ## How nginx works ![](https://i.imgur.com/TRvSu3O.png) https://www.aosabook.org/en/nginx.html ---- ## Blocking is the big enermy to NGINX https://www.nginx.com/blog/thread-pools-boost-performance-9x/ --- ## Furthur more https://hackmd.io/@sysprog/fast-web-server https://hackmd.io/@jT29vQ4-SxmlBU5UMj1TGA/High_Performance_Web_Server https://people.eecs.berkeley.edu/~culler/papers/events.pdf https://copyconstruct.medium.com/the-method-to-epolls-madness-d9d2d6378642 --- # References https://www.51cto.com/article/697808.html https://devarea.com/linux-io-multiplexing-select-vs-poll-vs-epoll/#.Yv3el-xBxb8 https://developpaper.com/why-can-redis-single-thread-achieve-high-performance-and-io-multiplexing/ https://redis.com/blog/multiplexing-explained/ https://blog.51cto.com/u_11956937/2097035 https://notes.shichao.io/unp/ch6/ https://cloud.tencent.com/developer/article/1420724 ---- https://programmer.group/analysis-of-io-multiplexing-and-event-mechanism-in-redis.html https://www.youtube.com/watch?v=E7Yn5biBZ58 https://www.computerhope.com/jargon/f/file-descriptor.htm https://rickhw.github.io/2019/02/27/ComputerScience/IO-Models/ https://www.modb.pro/db/232774 https://juejin.cn/post/6844904160710623246 https://blog.fearcat.in/a?ID=00001-ad1d6a96-fa83-4aa9-b9c3-468f79a8ba12 https://httpd.apache.org/docs/2.4/mpm.html#defaults https://www.nginx.com/blog/thread-pools-boost-performance-9x/ https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/ --- ### Thank you! :sheep: <style> .reveal { font-size: 24px; } </style>
{"metaMigratedAt":"2023-06-17T07:06:20.074Z","metaMigratedFrom":"YAML","title":"The reason why Nginx is faster than Apache http server and Redis is fast only using single-thread","breaks":true,"description":"Just simple memo for network I/O","slideOptions":"{\"theme\":\"solarized\"}","contributors":"[{\"id\":\"661583cb-db49-43b5-b24d-5ae18d46764b\",\"add\":7552,\"del\":1061}]"}
    893 views