Redis often used in the system's cache ( MySQL and Redis cache synchronization program ), which can solve the current problem that IO devices cannot meet the massive read and write requests of Internet applications.
1. Cache penetration
Cache penetration refers to data that is not in the cache or the database, and users continue to initiate requests, such as initiating data with an id of -1 or particularly large non-existent data. It is possible that hackers use vulnerabilities to attack the application database.
1. Common solutions
For the cache penetration problem, there are three common solutions:
- Verification interception: The interface layer performs verification, such as authenticating user permissions, and doing basic verification on fields such as IDs, such as direct interception of fields with id<=0;
- Cache empty data: When the data queried by the database is empty, this data will also be cached, but the effectiveness of the cache should be set to be short, so as not to affect the cache of normal data;
public Student getStudentsByID(Long id) {
// 从Redis中获取学生信息
Student student = redisTemplate.opsForValue()
.get(String.valueOf(id));
if (student != null) {
return student;
}
// 从数据库查询学生信息,并存入Redis
student = studentDao.selectByStudentId(id);
if (student != null) {
redisTemplate.opsForValue()
.set(String.valueOf(id), student, 60, TimeUnit.MINUTES);
} else {
// 即使不存在,也将其存入缓存中
redisTemplate.opsForValue()
.set(String.valueOf(id), null, 60, TimeUnit.SECONDS);
}
return student;
}
- Use Bloom filter: Bloom filter is a relatively unique data structure with certain errors. When it specifies that a data exists, it does not necessarily exist, but when it specifies that a data does not exist, then it must not exist.
2. Bloom filter
Bloom filter is a relatively special data structure, a bit similar to HashMap. In business, we may use HashMap to determine whether a value exists. It can return results in O(1) time complexity and is extremely efficient. High, but limited by storage capacity, if the value that may need to be judged exceeds 100 million, then the memory occupied by HashMap is considerable.
The BloomFilter solution to this problem is very simple. First, replace the array in the HashMap with multiple bits. In this case, the storage space is down. After that, the Key is hashed multiple times, and the bit position corresponding to the hashed value of the Key is 1.
When judging whether an element exists, judge whether the bits hashed out of this value are all 1, if they are all 1, then it may or may not exist (Figure F below). But if there is a bit that is not 1, then this Key definitely does not exist.
Note: BloomFilter does not support delete operations, only add operations. This is easy to understand, because if you want to delete data, you have to set the corresponding bit position to 0, but the bit corresponding to your key may also correspond to other keys.
3. Comparison of Cached Empty Data and Bloom Filter
The above two solutions are briefly introduced. Cached empty data and Bloom filters can effectively solve the cache penetration problem, but the usage scenarios are slightly different;
- When some malicious attack queries have different keys and a large number, caching empty data is not a good solution. Because it needs to store all the keys, the memory space is high. And in this case, many keys may only be used once, so it is meaningless to store them. So for this situation, using Bloom filter is a good choice;
- For scenarios where the number of keys with empty data is limited and repeated key requests are more efficient, the scheme of caching empty data can be selected.
Second, cache breakdown
Cache breakdown means that when the current hot data storage expires, multiple threads concurrently access the hot data at the same time. Because the cache has just expired, all concurrent requests will query the database for data.
solution
- Set hotspot data to never expire;
- Adding mutex locks: Mutex locks can control thread access for querying the database, but this solution will cause the throughput of the system to decrease, and it needs to be used according to the actual situation.
public String get(key) {
String value = redis.get(key);
if (value == null) { // 代表缓存值过期
// 设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { // 代表设置成功
value = db.get(key);
redis.set(key, value, expire_secs);
redis.del(key_mutex);
} else { // 这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
sleep(50);
get(key); // 重试
}
} else {
return value;
}
}
Three, cache avalanche
There are several situations in which a cache avalanche occurs. For example, a large number of caches are concentrated or the cache fails in a large area at the same time, and a large number of requests are made to access the database, which leads to CPU and memory overload and even downtime.
A simple avalanche process:
- Redis cluster has a large area failure;
- Cache failed, there are still a large number of requests to access the Redis cache server at this time;
- After a large number of Redis requests fail, these requests will access the database;
- Because the design of the application relies on the database and Redis service, it will soon cause an avalanche of the server cluster, and ultimately lead to the paralysis of the entire system.
solution
[Before] High-availability cache: High-availability cache is to prevent the entire cache from failing. Even if individual nodes, machines and even computer rooms are shut down, the system can still provide services, Redis sentinel (Sentinel) and Redis cluster (Cluster) can achieve high availability;
[In progress] Cache downgrading (temporary support): How can we ensure that the service is still available when the number of visits increases sharply and the service has problems. Hystrix is more widely used in the country, which reduces the loss after an avalanche occurs through three methods: fusing, downgrading, and current limiting. As long as the database is not dead, the system can always respond to requests. Don't we all come here during the 12306 Spring Festival every year? As long as you can respond, there is at least a chance to grab a ticket;
[After the event] Redis backup and fast warm-up: Redis data backup and recovery, fast cache warm-up.
Author: Tuesday Duck
Source: https://www.cnblogs.com/jojop/p/14106671.html
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。