Redis learning (4) Redis principle: underlying data structure, network model, memory recovery strategy

Redis underlying data structure

SDS dynamic string

Redis itself builds a new string structure called Simple Dynamic String, or SDS for short.
insert image description here
insert image description here
insert image description here

IntSet integer collection

insert image description here
insert image description here
insert image description here
insert image description here

Dict dictionary

  • Dict consists of three parts: hash table, hash node, and dictionary.

  • The dictionary Dict contains two hash tables, one of which is the current data, and the other is generally empty and used for rehash.

  • Each node in the hash table is a hash node, and the hash node is similar to the node of the linked list.

insert image description here

insert image description here

Progressive rehashing in Dict stretching

insert image description here
insert image description here
insert image description here
insert image description here

ZipList compressed list

insert image description here
insert image description here
insert image description here

QuickLisk Quick List

Although ZipList saves memory, the application memory must be a continuous space. If the memory occupation is large, the application memory efficiency is low.

QuickList features:

  • Is a double-ended linked list whose node is ZipList
  • The node adopts ZipList, which solves the memory occupation problem of the traditional linked list
  • The size of ZipList is controlled to solve the problem of continuous memory space application efficiency.
  • Intermediate nodes can be compressed, further saving memory.

insert image description here
insert image description here
insert image description here

insert image description here

SkipList skip table

The jump table is an improvement to the original linked list. The query of the original linked list requires O ( n ) O(n)O(n) traversal for each node, while the jump table draws on the idea of ​​binary search to classify the index of the linked list. , the essence of the skip list is an ordered linked list that can realize binary search.

Features of SkipList:

  • The jump list is a doubly linked list, each node contains score and ele, score is similar to index, and ele is the actual stored string content, nodes are sorted by score value, and the same score value is sorted by ele lexicographical order.
  • Each node can contain multiple layers of pointers, and the number of layers is a random number between 1-32.
  • Different pointers have different spans to the next node, and the higher the level, the larger the span.
  • The efficiency of adding, deleting, modifying and checking is basically the same as that of red-black tree, but the implementation is simpler.

insert image description here

insert image description here

dynamic indexing

In the case of known data distribution, it is ideal to continuously select the midpoint of the data as the position for index establishment:
insert image description here
in practice, our process of creating skip tables is dynamically added or deleted one by one. If you keep adding data to the original list without updating the index, there may be a lot of data between the two index nodes. In extreme cases, the jump list degenerates into a singly linked list:
insert image description here

The most ideal index is the case of binary search. In the original linked list (assuming the length is n), randomly select n/2 elements as the primary index, randomly select n/4 elements as the secondary index, and randomly select n/2 elements as the secondary index. Eight elements are used as three-level indexes, and so on, until the topmost index.

The randomLevel() method is used in the jump table to implement the above index building process. This method will randomly generate a number between 1 and MAX_LEVEL (MAX_LEVEL indicates the highest level of the index), and this method has a probability of 1/2 to return 1, 1 A probability of /4 returns 2, a probability of 1/8 returns 3, and so on. (The implementation of randomLevel() can be to call a function that returns 1 with a probability of 0.5 in a loop. If it is 1, continue to call the function until it is 0.)

跳表实际上是使用了这种随机产生元素的索引高度的方式,来打乱了输入的规律性,使得整体上按索引查询某个元素的时间复杂度为O ( l o g N ) O(logN)O(logN)

Assuming that a new element 6 is added, 1 is returned through the randomLevel() function, that is, a layer of index is established (a layer of index can only be established at the bottom layer), and its establishment method is as follows: starting from the highest-level index of the header
node , if the next element of a certain node is greater than the inserted element (6), stop and enter the next layer index, and so on, until the current layer is the same as the index layer of the element (6), insert the node.
insert image description here

RedisObject

RedisObject is the actual type of data objects stored in Redis.
insert image description here
insert image description here
insert image description here

Variable type and data structure implementation

String

The RedisObject of String type contains a lot of header information, so if you can use the numerical type, try to use a collection to save it, so that more elements can be stored in a RedisObject.
insert image description here

List

Before version 3.2, it was implemented by ZipList and LinkedList. After version 3.2, it was implemented by QuickList.

insert image description here

Set

  • For query efficiency and uniqueness, Set is implemented using Dict.
  • When storing all data as integers, it can be realized by using IntSet encoding.
    insert image description here

ZSet

ZSet (ordered collection) is realized through two data structures: jump table (to ensure order) and dictionary (to ensure the efficiency of query existence): but when the number of elements is not large, the advantages of
insert image description here
HT and SkipList are not obvious, and ZSet will use ZipList structure to save memory:
insert image description here

Hash

insert image description here

Redis network model

Is Redis single-threaded or multi-threaded?

  • If you only talk about the core business part of Redis (command processing), they are all single-threaded.
  • If you talk about the whole Redis, it is multithreading.

Why does Redis choose single thread?

  • Persistence aside, Redis is a pure memory operation with a very fast execution speed. Its performance bottleneck is network latency rather than execution speed, so multithreading will not bring huge performance improvements.
  • Multithreading can lead to excessive thread context switching, bringing unnecessary overhead.
  • The introduction of multi-threading will face thread safety issues, and it is necessary to introduce locks and other means to ensure thread safety. The implementation complexity is high, and the performance will be greatly reduced.

epoll event notification mode

insert image description here

Memory recovery strategy

expiration policy

How does Redis know whether a key has expired?

insert image description here
Use two Dicts to record key-value and key-TTL pairs respectively, notify TTL, and check whether it has expired

Is it deleted immediately when the TTL expires?

No, Redis adopts the following two expiration strategies:

  • lazy delete
  • Periodic deletion

Lazy deletion means that when the same key is accessed again later, it will check whether the key has expired, and delete it if it expires.
insert image description here
In the lazy deletion method, the data that has expired but has not been accessed in the future will always survive and occupy memory. At this time, Redis introduced a periodic deletion strategy:

By setting a scheduled task, the key is periodically sampled to determine whether it is expired, and if it is expired, delete it.

Periodic deletion has two working modes:

  • In the initServer() function of Redis, the expired key will be cleaned according to the frequency of server.hz, the mode is SLOW, and the default is 10 times per second.
  • Before each event loop of Redis, the beforeSleep() function is called back to perform the cleaning of expired keys, and the mode is FAST.
  • SLOW performs low frequencies but cleans up more thoroughly. The FAST model executes at high frequencies, but at short intervals.

insert image description here

insert image description here

Elimination strategy

Timing of memory elimination strategy execution:
Redis will try to do memory elimination in the method processCommand() of processing client commands.

Redis supports 8 different strategies for key elimination. The default elimination strategy is noeviction, which does not eliminate any keys, but does not allow new data to be written when the memory is full.

Other common memory elimination strategies are usually divided into processing all keys and processing keys with TTL set.

This includes prioritizing elimination of keys that are about to expire according to the TTL.
Random elimination for all keys, random elimination for keys with TTL set.

All keys or keys with TTL set are eliminated based on the LRU algorithm.
All keys or keys with TTL set are eliminated based on the LFU algorithm.

insert image description here

LRU and LFU

  • LRU (least recently used), least recently used. Subtract the last access time from the current time. The larger the value, the higher the priority of elimination.
  • LRU is time-based and time-sensitive. Recently, newly emerging hot keys are more likely to be resident in memory, while those keys that have not been used for a long time are more likely to be eliminated.
  • LFU (least frequently used), the least frequently used. The access frequency of each key will be unified, and the smaller the value, the higher the elimination priority.
  • LFU is frequency-sensitive, and is more suitable for storing keys that contain multiple hotspots. The last access to a certain key was at 12:00 noon yesterday, and within 5 minutes at 12:00 yesterday, 200 high-frequency accesses were made. If today There is still such a demand at noon. According to the LFU strategy, yesterday's hot keys will be resident in memory.

Guess you like

Origin blog.csdn.net/baiduwaimai/article/details/131750587