preface

Redis will officially launch version 6.0 in May 2020 with a lot of exciting new features, so it’s getting a lot of attention.

What features are provided? Will I get a raise if I know?

The main features are as follows:

  1. Multithreading network IO;
  2. Client cache;
  3. Fine-grained permission control (ACL);
  4. RESP3Use of the protocol;
  5. RDB files used for replication are no longer useful and will be deleted immediately;
  6. RDB file loading speed is faster;

One of the most concerned is “multi-threaded model + client cache”, we only master the principle of the new features, in order to determine when to use version 6.0, how to use better and faster, do not step on the pit.

This article will start with the Redis multithreaded model, with client caching, etc., broken down next time.

Finally, click on the card below to see if you can get a raise.

Share an image of Redis and like it.

Why didn’t you use multithreading before Redis 6.0?

Official reply:

  • With Redis, there is almost no CPU bottleneck; Redis is largely limited by memory and network.
  • On a normal Linux system, Redis uses thepipeliningIt can handle a million requests per second, so if the application mainly uses O(N) or O(log(N)) commands, it hardly takes up much CPU.
  • High maintainability after using single thread. Although multithreaded model has excellent performance in some aspects, it introduces the uncertainty of program execution order, brings a series of problems of concurrent read and write, increases the system complexity, and may cause performance loss caused by thread switching, even locking and unlocking, deadlock.

Redis has very high processing performance through AE event model and IO multiplexing, so there is no need to use multithreading.

The single-threaded mechanism greatly reduces the complexity of the internal implementation of Redis. Lazy Rehash, Lpush and other “thread-unsafe” commands of Hash can be executed without locking.

Before Redis 6.0, single thread meant Redis had only one thread working?

No, when Redis processes the client’s request, including obtaining (socket reading), parsing, executing, returning (socket writing) and so on, it is processed by a sequential main thread, which is called “single thread”.

In the command execution stage, because Redis is a single thread to process commands, all the commands arriving at the server will not be executed immediately, all the commands will enter a Socket queue, when the Socket is readable, the single thread event dispatcher will be executed one by one.

In addition, some command operations can be performed with background threads or child processes (such as data deletion, snapshot generation, AOF overwriting).

Why did Redis 6.0 introduce multithreading?

As hardware performance improves, the performance bottleneck of Redis may be network IO read and write. That is, the speed of a single thread processing network read and write cannot keep pace with the speed of the underlying network hardware.

Read /write system calls on read/write networks occupy most of the CPU time during Redis execution. The bottleneck mainly lies in the IO consumption of the network. Optimization mainly has two directions:

  • Improve network IO performance, typical implementations such as usingDPDKTo replace the kernel networking stack.
  • Use multithreading to make full use of multi-core, improve the parallelism of network request reading and writing, typical implementation such asMemcached.

Adding support for the user-mode network protocol stack would require modifying the network-specific parts of the Redis source code (for example, modifying all the network sending and receiving request functions), which would require a lot of development work.

And the new code may introduce new bugs, causing system instability.

Therefore, Redis uses multiple IO threads to process network requests to improve the parallelism of network request processing.

It should be noted that the Redis multi-IO thread model is only used to process network read and write requests, while Redis read and write commands are still handled by single threads.

This is because network processing is often a bottleneck, and performance can be improved by multi-threaded parallel processing.

And continue to use a single thread to execute read and write commands, do not need to ensure that Lua scripts, transactions, and other development of multithreaded security mechanism, implementation is simpler.

The architecture diagram is as follows:

How do mainthread and IO multithreading work together?

The diagram below:

Main process:

  1. The main thread is responsible for receiving the request to establish a connectionsocketPut into the global wait read queue;
  2. The main thread will be readable by pollingsocketAssign to the IO thread;
  3. The main thread blocks waiting for the I/O thread to readsocketComplete;
  4. The main thread executes Redis request commands read and parsed by the IO thread.
  5. The main thread blocks and waits for the I/O thread to write back the result of the instructionsocketTo complete;
  6. The main thread empties the global queue and waits for subsequent requests from clients.

I/O read/write tasks of the main thread are split into a group of independent threads, so that multiple socket read/write tasks can be parallelized, but the Redis command is still the main thread serial execution.

How do you turn on multithreading?

Multi-threading in Redis 6.0 is disabled by default and only the main thread is used. To enable this function, modify the redis.conf configuration file: io-threads-do-reads yes.

Code old wet, is the number of threads the better?

Of course not. There is an official recommendation for setting the number of threads: 2 or 3 for a 4-core machine and 6 for an 8-core machine. The number of threads must be smaller than the number of cores.

The number of threads is not always better, and the official view is that more than eight threads is almost meaningless.

In addition, after opening multithreading, also need to set the number of threads, otherwise it is not effective.

io-threads 4
1.
Copy the code

Summary and Reflection

With the rapid development of the Internet, Internet business system has to deal with more and more online traffic. The single-thread mode of Redis will cause the system to consume a lot of CPU time on network I/O, thus reducing throughput. There are two ways to improve the performance of Redis:

  • Optimize the network I/O module
  • Improve the speed of reading and writing machine memory

The latter depends on the development of hardware and has no solution for the time being. Therefore, network I/O optimization can be divided into two directions:

  • Zero copy technology or DPDK technology
  • Take advantage of multiple nuclear weapons

Model defects

The Multi-threaded network model of Redis is not a standard multi-questioning/Master-workers model. In the Multi-threaded solution of Redis, I/O threads only read and parse client request commands through sockets, but do not actually execute commands.

All client commands eventually need to return to the main thread for execution, so multi-core utilization is not very high, and each time the main thread must wait for all I/O threads to complete their tasks before continuing to execute other logic.

In my opinion, Redis’ current multithreading approach is more of a compromise: preserving the compatibility of the original system while leveraging multiple cores to improve I/O performance.