Several I/O models

Why use I/O multiplexing in Redis?

First of all, the Redis is run in a single thread, all operations are carried out in accordance with the order linear, but due to the read and write operations waiting for user input or output is blocked, so the I/O operations in general often cannot return directly, which can lead to a particular file I/O block causes the entire process cannot provide services to other customers, And I/O multiplexing is to solve this problem.

Blocking I/O

Let’s take a look at how the traditional blocking I/O model works: When read or write is used to read or write a File Descriptor, if the current FD is unreadable or unwritable, the Redis service does not respond to other operations and becomes unavailable.

The blocking model, while very common and well understood in development, is often not used when multiple client tasks need to be handled because it affects other FD corresponding services.

I/O multiplexing

There are many other I/O models, but none of them are covered here.

We need a more efficient I/O model to support multiple Clients of Redis (RedIS-CLI). Here is the I/O multiplexing model:

In the I/O multiplexing model, the most important function call is select, which monitors the readability and writability of multiple file descriptors at the same time. When some file descriptors are readable or writable, select returns the number of file descriptors that are readable and writable.

Select about the specific use of the method, there is a lot of information on the network, here is not more to expand the introduction;

There are other I/O multiplexing functions, epoll/kqueue/ EVport, that perform better than SELECT and support more services.

I/O multiplexing module

The I/O multiplexing module encapsulates the underlying I/O multiplexing functions such as SELECT, Epoll, Avport and Kqueue and provides the same interface for the upper layer.

Redis will prefer I/O multiplexing functions with a time complexity of $O(1)$for the underlying implementation, including Evport in Solaries 10, Epoll in Linux, and KQueue in macOS/FreeBSD. All of these functions use internal kernel constructs and can serve hundreds of thousands of file descriptors.

However, if the current compilation environment does not have the above function, select will be selected as an alternative, because it will scan all the listening descriptors, so its time complexity is poor $O(n)$, and can only serve 1024 file descriptors at the same time, so it is generally not used as the first scheme.

conclusion

Redis for I/O multiplexing module design is very simple, through macro to ensure that THE I/O multiplexing module has excellent performance on different platforms, different I/O multiplexing functions packaged into the same API for the upper layer to use.

The whole module enables Redis to serve thousands of file descriptors while running in a single process, avoiding the increase in code implementation complexity caused by the introduction of multi-process applications and reducing the possibility of errors.