Разница между разбивкой кеша и лавиной кеша в том, что лавинная разбивка идет по многим клавишам, а разбивка только по определенной горячей клавише.
Установите для кеша неограниченный срок действия.Хотя этот метод очень жесток, он может решить большинство проблем.Конечно, большинство сценариев неприменимы;
Установка случайного времени истечения, это решение не подходит для разбивки кеша, потому что разбивка только на одну горячую клавишу, пока она не сработает, большое количество обращений уничтожит базу данных;
Другие решения, такие как использование блокировок мьютексов и механизмов двойного кеша, также могут решить проблему разбивки кеша Давайте посмотрим на конкретную реализацию этих решений.
Активно очищать кеш
Срок действия кеша не ограничен, и когда данные в БД обновляются или удаляются, данные в кеше также активно обновляются или удаляются.
Это решение простое для понимания, но очень сложное в реализации.Всякий раз, когда необходимо использовать кэшированные данные, необходимо добавить код базы данных и кэша с двойной записью, а во время процесса двойной записи необходимо обеспечить согласованность данных. поддерживается.
Проверить наличие обновлений
Кэш по-прежнему поддерживает установленное время истечения срока действия. Каждый раз, когда вы получаете кеш, он сравнивает время истечения срока действия данных с текущим временем. Когда интервал времени меньше порогового значения, кеш активно обновляется.
Например (время истечения кэша - текущее системное время) меньше 5 минут, затем один раз обновить кэш и сбросить время истечения кэша;
Однако у этого метода есть и фатальная проблема: если за пять минут до инвалидации кеша к части данных вообще не обращались, то обновление проверки не сработает. также приведет к поломке кеша.
использовать замок
После того, как кеш становится недействительным, количество потоков, читающих базу данных и записывающих в кеш, контролируется с помощью мьютекса или очереди.
первый метод:Весь метод синхронизирован, хотя это может предотвратить попадание большого количества запросов на БД, даже если кэш не инвалидирован, данные нужно запрашивать из БД, что несомненно снижает пропускную способность системы.
public synchronized String getCacheData() {
String cacheData = "";
//读 Redis
cacheData = getDataFromRedis();
if (cacheData.isEmpty()) {
//读数据库
cacheData = getDataFromDB();
//写 Redis
setDataToCache(cacheData);
}
return cacheData;
}
Второй метод:Когда кеш недействителен, блокируется только операция запроса к базе данных, что также очень удобно для случая, когда кеш не является недействительным.Однако блокировка операции запроса здесь заблокирует только другие вызовы.Во-первых, другие потоки должны ждите.Абонент не дружественный, и второй запрос, что эти запросы блокируются, в конечном итоге ляжет на БД.
static Object lock = new Object();
public String getCacheData() {
String cacheData = "";
// 读 Redis
cacheData = getDataFromRedis();
if (cacheData.isEmpty()) {
synchronized (lock) {
//读数据库
cacheData = getDataFromDB();
//写 Redis
setDataToCache(cacheData);
}
}
return cacheData;
}
Третий метод:Используйте блокировку взаимного исключения, если вы захватываете блокировку, читаете базу данных и записываете в кеш, если вы не можете захватить блокировку, она не будет блокировать, а напрямую читать кеш.Запишите успешно), просто подождите некоторое время и попробуйте чтобы снова прочитать кеш.
public String getCacheData(){
String result = "";
//读 Redis
result = getDataFromRedis();
if (result.isEmpty()) {
if (reenLock.tryLock()) {
try {
//读数据库
result = getDataFromDB();
//写 Redis
setDataToCache(result);
}catch(Exception e){
//...
}finally {
reenLock.unlock();//释放锁
}
} else {
//注意:这里可以结合下文中的双缓存机制:
//抢不到锁的去查询二级缓存
//读 Redis
result = getDataFromRedis();
if (result.isEmpty()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//...
}
return getCacheData();
}
}
}
return result;
}
двойной кеш
Установите кеш первого уровня и кеш второго уровня, кеш первого уровня имеет короткий срок действия, а кеш второго уровня имеет длительный срок действия или не имеет срока действия.После истечения срока действия кеша первого уровня второй кеш-уровня, и кеш-память первого уровня и кэш-память второго уровня обновляются одновременно.
Метод двойного кеша, грубо говоря, не может одновременно сделать недействительными данные в кеше первого уровня и кеше второго уровня. по-прежнему конкурируют за блокировки друг с другом, и поток, который захватывает блокировку, делает запрос к базе данных и обновляет кеш, в то время как другие потоки, которые не захватывают блокировку, напрямую обращаются к кешу второго уровня (код может ссылаться на блокировку мьютекса выше) , как показано на рисунке:
Дядя, который знает код | Текст [Оригинал]