Redis: Cache penetration, cache breakdown, cache avalanche (reasons + solutions)

Reprinted from https://www.cnblogs.com/xichji/p/11286443.html .

In our daily development, we use the database to store data. Since there is usually no high concurrency in general system tasks, it seems that there is no problem, but once the demand for large amounts of data is involved, For example, some products are snapped up, or when the amount of visits to the homepage is instantaneous, a system that uses a database to save data will have serious performance disadvantages due to disk-oriented and slow disk read/write speeds. The arrival of thousands of requests requires the system to complete thousands of read/write operations in a very short period of time. This is often not the database can withstand, and it is extremely easy to cause the database system to be paralyzed, and ultimately lead to serious service downtime Production problems.

In order to overcome the above-mentioned problems, projects usually introduce NoSQL technology, which is a memory-based database and provides certain persistence functions. Redis technology is one of NoSQL technologies, but the introduction of redis may cause cache penetration, cache breakdown, and cache avalanches. This article analyzes these three issues in depth.

 

  • Cache penetration: The data corresponding to the key does not exist in the data source. Every time a request for this key cannot be obtained from the cache, the request will go to the data source, which may overwhelm the data source. For example, using a non-existent user id to obtain user information, no matter whether there is a cache or a database, if a hacker exploits this vulnerability to attack, it may overwhelm the database.
  • Cache breakdown: The data corresponding to the key exists, but it expires in redis. At this time, if a large number of concurrent requests come in, these requests will generally load data from the backend DB and reset it to the cache when the cache expires. This is a large concurrent request It may overwhelm the back-end DB instantly.
  • Cache avalanche: When the cache server restarts or a large number of caches fail in a certain period of time, it will also put a lot of pressure on the back-end system (such as DB) when it fails.

Cache penetration solution:

A data that must not exist in the cache and cannot be queried. Because the cache is passively written when it is missed, and for fault tolerance, if the data cannot be found from the storage layer, it will not be written to the cache, which will result in this non-existent data Every request must go to the storage layer to query, losing the meaning of caching.

There are many ways to effectively solve the cache penetration problem. The most common one is to use a Bloom filter to hash all possible data into a large enough bitmap. A data that must not exist will be affected by this bitmap. Block it, thereby avoiding query pressure on the underlying storage system. In addition, there is a simpler and more rude method (this is what we use). If the data returned by a query is empty (whether the data does not exist or the system is faulty), we still cache the empty result, but its The expiration time will be short, no more than five minutes.

Cache breakdown solution:

The key may be accessed extremely concurrently at certain points in time, which is a very "hot" data. At this time, there is a problem that needs to be considered: the problem of "breakdown" of the cache.

Use mutex key

A common practice in the industry is to use mutex. To put it simply, when the cache is invalid (the judged value is empty), instead of going to load db immediately, first use certain operations with the return value of the successful operation of the caching tool (such as Redis SETNX or Memcache) ADD) to set a mutex key. When the operation returns successfully, perform the load db operation and reset the cache; otherwise, retry the entire get cache method.

Cache avalanche solution:

The difference from cache breakdown is that there are many key caches here, and the former is a certain key.

The impact of the avalanche effect on the underlying system when the cache is invalid is terrible! Most system designers consider using locks or queues to ensure that there will not be a large number of threads reading and writing to the database at one time, so as to avoid a large number of concurrent requests falling to the underlying storage system in the event of failure. There is also a simple solution to spread the cache expiration time from time to time. For example, we can add a random value on the basis of the original expiration time, such as 1-5 minutes randomly, so that the repetition rate of the expiration time of each cache will be reduced. It is difficult to cause a collective failure event.

Use locks or queues, set expiration flags to update the cache, and set different cache expiration times for keys. There is also a solution called "second-level cache".

 

 

Guess you like

Origin blog.csdn.net/johnt25/article/details/112204671