Redis’s cache breakdown, penetration, avalanche, preheating, and how to solve it?

Time:2021-11-12

The process of data acquisition is generally a front-end request. The background first fetches data from the cache. If the cache cannot be fetched, it goes to the database. If the database gets it, it returns to the front-end, and then updates the cache. If the database cannot be fetched, it returns empty data to the front-end

flow chart:

Redis's cache breakdown, penetration, avalanche, preheating, and how to solve it?

If there is no cached data, the background will always request the database, causing pressure on the database. If there is a large amount of requests or malicious requests, the database will crash. We generally call it cache penetration, cache breakdown and cache avalanche.

1. Cache penetration

Description: cache penetration refers toThere is no data in the cache or database, and the user constantly initiates requests, such as data with ID “- 1” or data with ID particularly large (non-existent data). At this time, the user is likely to be an attacker, and the attack will lead to excessive pressure on the database.

Redis's cache breakdown, penetration, avalanche, preheating, and how to solve it?

solve:

  1. Verification is added in the interface layer, such as user authentication verification, and ID is used for basic verification, such as direct interception of ID < = 0;
  2. The data that cannot be retrieved from the cache is not retrieved in the database. At this time, you can also write the key value pair as key null and directly return a null value. The cache validity time can be set to be shorter, such as 30 seconds (setting too long will make it impossible to use under normal conditions). This can prevent the attacking user from repeatedly attacking with the same ID.
  3. Using the mutex lock, when the cache fails, first get the lock, get the lock, and then request the database. If the lock is not obtained, sleep for a period of time and try again.
  4. Asynchronous update. Directly return a null value, and then start a thread to read data from the database and update the cache. For example, load the cache before starting the project.
  5. Most commonThe other is to useBloom filter, hash all possible data into a large enough bitmap, and a certain non-existent data will be intercepted by the bitmap, so as to avoid the query pressure on the underlying storage system.

2. Buffer breakdown

Description: cache breakdown refers toData not in cache but in database, when a key is very hot (similar to a hot payment), it is constantly carrying large concurrency, and large concurrency focuses on accessing this point; When the key fails, the continuous large concurrency breaks through the cache and directly requests the database, which is like cutting a hole in a barrier.

Redis's cache breakdown, penetration, avalanche, preheating, and how to solve it?

solve:

  1. Set hotspot data to never expire.
  2. Add mutex.

    As shown in the figure:

    Redis's cache breakdown, penetration, avalanche, preheating, and how to solve it?

If there is data in the cache, it will be returned directly. If there is no data, the first incoming thread will query the database and lock it, and other threads will wait. In this way, it can prevent checking duplicate data in the database and updating the cache repeatedly.

3. Cache avalanche

Cache avalanche meansThe time when the data in the cache reaches the expiration date in large quantities, a large number of data expired at the same time, resulting in all requests to the database, resulting in database downtime.

Redis's cache breakdown, penetration, avalanche, preheating, and how to solve it?

solve:

  1. Add a random value to the cache expiration time to avoid a large number of cache collective failures.
  2. Dual cache: cache a and B. for example, the expiration time of a is 20 minutes, and B does not expire. For example, if you don’t read from a, read from B, and then asynchronously start a thread to synchronize to a.

For mutual exclusion, take the following example:

  1. Redis

If redis is used, redis can be usedSETNX, that is, it can be set only when it does not exist. You can use it to achieve the effect of locking.

public String get(key) {
      String value = redis.get(key);
      If (value = = null) {// indicates that the cache value has expired
          //Set a 3min timeout to prevent the next cache expiration from failing to load dB when the Del operation fails
          If (redis. Setnx (key_mutex, 1, 3 * 60) = = 1) {// the setting succeeds
               value = db.get(key);
                      redis.set(key, value, expire_secs);
                      redis.del(key_mutex);
              }Else {// at this time, it means that other threads at the same time have loaded dB and set it back to the cache. At this time, try again to obtain the cache value
                      sleep(50);
                      get(key);  // retry 
              }
          } else {
              return value;      
          }
 }
  1. memcache
if (memcache.get(key) == null) {  
    // 3 min timeout to avoid mutex holder crash  
    if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {  
        value = db.get(key);  
        memcache.set(key, value);  
        memcache.delete(key_mutex);  
    } else {  
        sleep(50);  
        retry();  
    }  
} 

4. Cache preheating

Cache preheating means that after the system goes online, the latter will directly load the relevant cache data to redis when the system is restarted. In this way, the problem of querying the database first and then caching the data when the user requests can be avoided. The user can directly query the cached data preheated in advance.

solve:

  1. When online, add an interface to manually trigger the loading cache or refresh the cache regularly.
  2. The amount of data is small and can be loaded automatically when the project is started.


reference resources:

  • https://www.iteye.com/blog/ca…
  • https://mp.weixin.qq.com/s/LO…

Ask for some praise? Seeking attention ❤️ For sharing?