About the use of Redis, we should be no stranger, I have also introduced the use of Redis, data structure, use scenario analysis, since Redis this powerful, so the architecture of the introduction of Redis, is not “invincible”?

In fact, all architectures, frameworks, components, while solving some of the problems, also bring new problems, let’s take a look at the use of Redis may encounter what kind of problems.

The cache to penetrate

Most of the usage scenarios of Redis are based on the key, first query in Redis, if the query cannot be found, then query the database.

When there are a large number of requests where the key value is not in Redis at all, the query will fall on the database, and the requests will “penetrate” the database as if they were in Redis, eventually causing the database to become overwhelmed and crash.

The cache to penetrate

Let’s look at the strategy for cache penetration:

1. Save the invalid key to Redis

If the key is not available in Redis and the database is not queried, write the key to Redis and set value = null so that the database is not queried if the key is accessed repeatedly.

Save the invalid key to Redis

However, if the database stores a real entry a few minutes later, an inconsistency will occur between the database and the cached data.

In this case, either actively update the key-empty data in Redis, or set the expiration time of the cache when setting the cache, so that when the time expires, the cache data can be flushed into Redis.

This method will fail if the key value is different for each query, such as a malicious attack, and each access is invalid with a different key value.

2. Bloom filter

The principle of Bloom Filter is complicated to explain, and its characteristics can be summarized in plain English: if it says a key does not exist, it certainly does not exist; if it says a key does exist, it is very likely to exist (there is a certain rate of misjudgment).

Using a Bloom filter to block back invalid requests, the process looks something like this:

Bloom filter

Those interested in Bloom filters can try out Google’s Guava toolkit, which has bloom filters out of the box: BloomFilter;

public class BloomFilterTest {

    public static void main(String[] args){

        int size = 1000000;

        // Bloom filter

        BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.001);



        for (int i = 0; i < size; i++) {

            bloomFilter.put(i);

        }



    List<Integer> list = new ArrayList<Integer>(1000);

        for (int i = size + 1; i < size + 10000; i++) {

            if (bloomFilter.mightContain(i)) {

                list.add(i);

            }

        }

        System.out.println("Number of miscarriages of justice:" + list.size());

    }

}

Copy the code

In addition, Redis has Module functionality after 4.0, which can use external extensions, and can use RedisBloom as a RedisBloom filter plugin.

Cache avalanche

When we use Redis, we usually set an expiration time for the cache, but if a large number of cache failures occur at one point in time, the next point in time will be a large number of requests to access the database. In this case, the database may “crash” due to the volume of traffic. This is a cache avalanche.

Let’s look at the caching avalanche solution:

1. Do not set the cache expiration time

The most violent solution is that the cache does not set an automatic expiration time. As long as the cache does not crash, the database will not crash.

2. Set the random expiration time

Another solution is to make the cache expiration time inconsistent. For example, a batch of cached data expires after 24 hours. Then, based on this, make each cache expiration time random 1-6000 seconds (1-10 minutes).

3. Use mutex

Control the number of threads that can read the database and write the cache through mutex or queue after the cache fails. However, this will cause the throughput of the system to decrease.

4. Double buffer

Set level-1 cache and level-2 cache. Level-1 cache has a short expiration time, and Level-2 cache has a long expiration time or does not expire. After level-1 cache expires, level-2 cache is accessed and refreshed.

Finally, the introduction of any architecture, component, or framework will bring new problems, so we must have corresponding evaluation and solution when using it.

Uncle will point code | article “original”


Please pay attention to the uncle who can code