preface

This article has been included on GitHub: HTTPS://zhouwenxing.github.io/
Copy the code

In daily development, in order to ensure the consistency of data, we generally choose relational databases to store data, such as MySQL and Oracle, because relational databases have the characteristics of transactions. However, in a large amount of concurrent business scenarios, relational databases often become the system bottleneck, unable to fully meet our needs, so we need to use caching, rather than relational databases, that is, NoSQL databases often become the best choice.

The most common definition of a NoSQL database is non-relational, but some people interpret it as Not Only SQL. Non-relational databases do not guarantee transactions, that is, do not have transaction ACID properties, which is also the biggest difference between non-relational databases and relational databases, and we are going to introduce Redis is a NoSQL database.

What is a Redis

REmote DIctionary Service Redis stands for REmote DIctionary Service. Redis is an open source (BSD compliant), network-enabled, memory-based and persistent logging, key-value database. Redis has the following features:

  • 1, support rich data types: strings (strings), hashes (Hashes), lists (Lists), sets (sets), sorted sets (sorted sets), bitmaps etc.
  • 2. Rich features: it provides persistence mechanism, expiration policy, subscription/publication and other functions.
  • 3. High performance, high availability and cluster support.
  • 4. Multiple languages are availableAPI.

The installation of Redis

  • 1, download the corresponding version of the installation package, such as Redis 5.0.5, other versions can also be downloaded here.
  • 2. Upload the file to the specified directory on the server and run the commandThe tar - ZXVF redis - 5.0.5. Tar. GzDecompress.
  • 3. After successfully decompressing, enterRedisHome directory, run the commandMake && make install PREFIX=/ XXX/XXX /redis-5.0.5If you do not specify a directory, the default installation directory is/usr/localDirectory.
  • 4. You can see it after the successful installationRedisThere’s an extra one in the home directorybinDirectory,binThe directory contains executable scripts.
  • 5, to return toRedisHome directory, findredis.confConfiguration file, which will be configureddaemonize noModified todaemonize yesIs used to start the service in the background.
  • 6. The command can then be executed/ / XXX XXX/redis - 5.0.5 / bin/redis server/XXX/XXX/redis - 5.0.5 / redis. ConfStart theRedisService.

Just how fast Redis is

We all know that Redis is fast, but how fast is Redis? For example, what is the throughput of Redis? I don’t think everyone can say a specific number.

Redis provides a test script that can be used to test Redis throughput.

  • redis-benchmark -q -n 100000You can test throughput of commonly used commands.
  • redis-benchmark -t set,lpush -n 100000 -qtestRedisTo deal withsetlpushCommand throughput.
  • redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"testRedisTo deal withLuaScript throughput.

The following is the self-test result of executing the first command on my side. It can be seen that the throughput of most commands can reach more than 40,000, that is, more than 40,000 requests can be processed per second:

But if you think this is the true throughput of Redis, you are wrong. In fact, the official Redis test result is a throughput of 100,000. Here is one of the official benchmark results (the vertical axis is throughput and the horizontal axis is connections) :

Is Redis single-threaded or multi-threaded

This is a classic question because many people think of Redis as single-threaded. However, Redis has had the concept of multithreading since version 4.0, and while the core module for processing command requests does guarantee single-threaded execution, multithreading already exists in many other places, such as: Deleting objects in the background, using the Redis module to implement blocking commands, generating dump files, and network I/O implementation of multi-threading in version 6.0, and in the future there should be more and more Redis modules to implement multi-threading.

By single threading, we mean that Redis processes requests from clients (i.e., commands) with a single thread, not that the entire Redis process is single threaded.

Why does Redis choose to use a single thread to execute requests

Why did Redis choose to use single threads? This is because it is unusual for a CPU to become a Redis bottleneck, rather than memory or network bandwidth. For example, using pipelining on a normal Linux system, Redis can complete a million requests per second, so if our application mainly uses O(N) or O(log(N) complexity commands, it hardly uses much CPU.

So since the CPU is not going to be a bottleneck, there is no need to use multiple threads to execute commands. The question we need to clarify is: is multithreading necessarily faster than single threads? The answer is not necessarily. Because multithreading has costs, the two most immediate costs are thread creation and destruction (although thread pooling can reduce frequent thread creation and destruction to some extent) and thread context switching.

In our everyday systems, there are two main types: CPU intensive and IO intensive.

  • CPU intensive: This kind of system is illustrativeCPUIf the usage of multithreading is very high, then the use of multithreading will increase the overhead of context switch, so the efficiency of using multithreading may decrease rather than increase. For example, let’s say you’re working right now, and you’re constantly doing the same thing that you need1It can be done in minutes, but you are always interrupted and need flowers1Seconds to walk to the side to do another task, if that task also requires1Minutes, so you do two things over and over again, and each time you switch it costs1In seconds, finally do this2The time of the event must be greater than2Minutes (depending on how many times you switch), but if there are no interruptions and you finish one thing before moving on to another, then the most you need to do is switch1Theta, which is theta21It can be done in seconds.
  • IO intensive:IOOperations can also be divided into disksIOAnd the InternetIOSuch operations. Most of theIOThe operation is time-consuming andCPUNot a lot of utilization, soRedis 6.0Version of the networkIOWill be improved to multithreading. As for the diskIOBecause theRedisData is stored in memory (and persisted), so there is not much disk manipulation involved. For example, if you water a sapling now, and you have to wait for someone else to add water to it after each watering, then suppose that the waiting process requires5Second, which means you can take a break after you pour water once5Seconds while you switch to do another thing back and forth just need to2Second, you can always go do something else first and come back later to make the most of your free time5Second time, thus improving efficiency.

Another problem with multithreading is data security, so multithreaded programming involves lock contention, which can lead to additional overhead.

What is I/O multiplexing

I/O refers to network I/O, multiplexing refers to multiple TCP connections (such as sockets), and multiplexing refers to the reuse of one or more threads. The core principle of I/O multiplexing is that the server kernel listens for the application instead of the application listening for the connection itself.

In Redis, its multiplexing has a variety of implementation, such as: SELECT, epoll, EVport, Kqueue and so on.

Let’s use the example of going to a restaurant to explain the I/O multiplexing mechanism (the diner is the client, the kitchen is the server, and the chef is the thread).

  • blockingIO: Zhang SAN went to a restaurant for dinner and ordered a dish. At this time, he did nothing but wait until the chef cooked the dish. He took the dish away and began to eat. That is, before the dish is cooked, Zhang SAN is blocked. Here it isBIO(blockingIO), can be very inefficient.
  • non-blockingIOZhang SAN goes to a restaurant for dinner and orders a dish. At this time, Zhang SAN doesn’t wait all the time. He finds a seat and sits down, swips tiktok, makes phone calls, does something else, and then goes to the kitchen every once in a while to check if his food is ready. This is nonblockingIO, this way although can improve performance, but if there is a large number ofIORegular polling will also cause a very large burden on the server.
  • Zhang SAN goes to a restaurant for dinner and orders a dish. At this time, he takes a seat and waits:
    • The kitchen over there cooked dishes will dish out, but do not know who this dish is, so one by one to ask customers, this is multiplexingselectModel, butselectThe model can only listen at best1024socket(pollThe model addresses this limitation.
    • The kitchen has done the dish to put the dish directly on the window, shout 1, so-and-so dish has done, who is quick come over to take, at this time hear the notice of the person will go to take, this is the multiplexing inepollModel.

It is important to note under the IO multiplexing mechanism, the client can block also can choose not to block (most of the scenarios is blocking IO), the particular case is particular analysis, but under the multiplexing mechanism, the server can be used multithreading (can be a few more chefs cooking at the same time in the above example) to improve the efficiency of concurrent.

Application of I/O multiplexing in Redis

The Redis server is an event driver, and the server needs to handle two types of events: file events and time events.

  • File events:RedisCommunication between a server and a client (or other server) generates file events, which the server then listens for and processes to complete a series of communication operations.
  • Time event:RedisInternal operations that need to be performed at a given time.

Redis’s file event handler runs in a single-threaded fashion, using an INTERNAL I/O multiplexer to listen for multiple Socket connections simultaneously, improving performance while keeping the internal single-threaded design simple. Here is a diagram of the file event handler:

The I/O multiplexer will listen for multiple Socket connections at the same time, but it will listen to the Socket in a queue, and then through this queue, the corresponding events of each Socket to the file event dispatcher orderly, synchronous. The file event dispatcher dispatches the event to the corresponding event handler for processing. The I/O multiplexer will send the event corresponding to the next Socket to the file event dispatcher only after the event corresponding to the Socket has been processed. This can also verify the conclusion above. Client command requests are handled in a single-threaded fashion, but there is not just one thread in the event handler.

Why is Redis so fast

The reasons why Redis is so fast have been basically mentioned above, now let’s summarize:

  • 1.RedisIt is a pure memory structure, avoiding disksI/OSuch time-consuming operations.
  • 2,RedisThe core module of command processing is single thread, reducing lock contention, and the cost of frequent thread creation and destruction, reducing the consumption of thread context switch.
  • 3, adoptedI/OMultiplexing mechanism, greatly improve the efficiency of concurrency.