Redis cache penetration and cache avalanche analysis and solutions

The relationship between cache and DB access in general

Cache penetration

Refers to querying a data that must not exist. Since there is no such query object in the cache (the cache can never hit the corresponding data), then the database will query the data. If there is no corresponding data in the database, it cannot be written to the cache. In this case, every query for non-existent data will query the database, which is cache penetration .

Affect:

In the case of high concurrency, cache penetration may slow down the database, thereby slowing down the entire system, or even downtime.

Solution:

When the corresponding data cannot be hit in the cache, and the target data is not found when accessing the database, an empty result is stored in the cache at this time. In this case, each query first determines whether there is target data in redis (that is, exist(String key)). If the key exists, the cached result will be returned directly, even if the cached result is empty.

Cache avalanche

When a large number of caches fail in the same period of time, a large number of database access queries will be triggered during this period, which will bring greater pressure to the database.

Solution:

  1. At the database access level, lock/queue walkthrough access
  2. Analyze the actual situation of the system cache (including user usage scenarios, etc.), and design a more evenly distributed failure time.
  3. Data warm-up, before the concurrency peak that can be encountered, update the cached data evenly and plannedly in advance to prevent a large number of cache failures during the concurrency peak period.
  4. Set business hotspot data to never expire, only cache update operations
  5. In the case of distributed databases, evenly distribute hot data to disperse the access pressure of a single database after a cache avalanche
  6. Access current limit (least recommended)

It is recommended to use methods 2, 3, and 4 to prevent and solve the cache avalanche problem. Locking or queued access control will definitely bring performance loss. Problems that can be avoided in advance should be avoided as far as possible. It is best not to wait until Remedy should be done if the accident happened.

Reasonable lock

Double detection lock:

public User selectById(String id) {

    User user = (User) hash.get(id);
    if (null == user) {
        synchronized (this) {
            //这里多一次缓存的检查是关键
            user = (User) hash.get(id);
            if (null == user) {
                user = //...查询数据库
                hash.put("user", user);
            }
        }
    }
    return user;
}

Advantages: When high concurrency, cache expires, and hot data is not warmed up, the first thread accesses the lock object, and other threads are waiting; during the time when the first thread queries the database, a large number of threads are crowded When the DB query result of the first thread is cached, the other threads waiting to obtain the lock object get the lock in turn. At this time, the most critical step is to check the cache again to avoid these threads. Do unnecessary database access .

 

Guess you like

Origin blog.csdn.net/qq_25805331/article/details/109322693