This is the fourth day of my participation in the August More text Challenge. For details, see: August More Text Challenge
Redis standalone QPS
/redis-benchmark -t set,lpush -n 100000 -q set: 82101.80 requests per second Lpush: 82440.23 requests per secondCopy the code
I tested SET and LPUSH 100, 000 times on my own computer, and found that SET and LPUSH were around 8W/s, close to the official 10W QPS written on a single computer.
Why so fast
In-memory database
Redis is completely memory based and the vast majority of requests are purely memory operations, so it’s very fast.
Simple data structures
Redis currently supports five data types (String, List, hash, set, and zset). The data structure is relatively simple and the operation is relatively fast.
SDS data structure
For strings, Redis uses SDS to organize the data:
The core idea of this data is that space changes time
- Space preallocation: As the space expands, not only the required space is allocated, but additional space is allocated
- If the SDS length is less than 1M after allocation, then the same amount of extra space is allocated, assuming a modified key
len=13
So also distributefree=13
And the lastbuf=13+13+1=27
- If len after allocation is greater than or equal to 1M, then an additional fixed allocation of 1M, assuming the modification
len=30M
Distribution of,free=1M
And the lastbuf=30M+1M+1byte
- Lazy space release
- Suppose you have a
len=13
.free=13
If the character gets shorterlen=10
, then the extra 3 bytes will not be reclaimed, put first in free, at this timefree=16
In some scenarios, the number of memory requests can be reduced by this allocation method, thus achieving a certain speed
Jump table
Redis’ ordered collection, the use of skip list data structure, through the layer to speed up access to other nodes
Each node has a random layer. For example, O1 node can jump directly to O3 through L4 with a span of 2. Redis’ ordered set is used to speed up the access between nodes in this way.
Single thread
Redis uses single thread model, the advantage of single thread is to avoid multithreaded data competition, locking, context switching problems. Redis’s bottleneck is not CPU, but memory or network bandwidth, so it’s a single thread. By single thread, we mean only one thread is used to process network requests. Redis itself uses additional threads for persistence.
Multithreading in redis4.0
Reddis4.0 also supports multithreading, of course, only for some commands are multithreaded, such as: UNLINK, FLUSHALL, ASYNC, FLUSHDB. The purpose of introducing these is: in some cases, to improve the efficiency as much as possible. Suppose there is a key that is tens of M in size, then the key DEL may be temporarily blocked. If unlink is used to delete the key, only the key is deleted at first.
IO multiplexing
Redis uses non-blocking I/O multiplexing technology. Redis itself is an event driver, Redis abstracts sockets into file events. I/O multiplexing in this case means that the file event handler listens to the associated socket (Accept, read, write, close) in a single-threaded manner.
Since the IO multiplexer is a single-threaded program, when multiple sockets arrive, they must be queued, and they are always processed sequentially in a queued manner.
C10K problem
In the case of no IO multiplexing, suppose there are 10,000 client connections (FD1 -10000), but only 1 client is sending data. However, the computer does not know which FD has data, so it can only traverse 10,000 times, and every time it gets stuck in the kernel, it is expensive, and in fact 9999 times are wasted.
IO multiplexing
IO multiplexing means that multiple network IO is multiplexing a process or thread for multiple TCP connections. The great benefit of this model is that you don’t have to create a process or thread for each connection. The classic model is select, poll, epoll.
- Select: select(FDS), gives the FDS to the kernel once, and the kernel tells which FDS are readable and writable (the kernel traverses them itself, instead of the user traversing them, turning multiple system calls into one). The maximum FDS is 1024, which determines the maximum concurrency of the select model is 1024.
- Poll: Similar to select, but with more concurrency than 1024
- The disadvantage of epoll: select and poll is that the kernel traversal time is O(n), although the user mode does not need to traverse, reducing the number of times to fall into the kernel, but the kernel still needs to traverse. The advantage of epoll is that the kernel does not need to traverse. When the user passes the FDS to the kernel, it relies on hardware interrupts. For example, when the network card has data arriving, it interrupts to tell the CPU which FD has data arriving.
Redis uses epoll by default unless the system does not support it.
conclusion
- Redis is an in-memory database
- Redis special data structures
- Single threading prevents lock contention
- IO multiplexing
The above four points are the main reasons why single-threaded Redis is fast.