Не бойся больше, кеш-лавина, пробой, проникновение!

Redis

Данные пользователя обычно хранятся в базе данных, данные базы данных находятся на диске, а скорость чтения и записи диска можно назвать самым медленным аппаратным обеспечением компьютера.

Когда пользователь запрашивает все доступ к базе данных, база данных легко выйдет из строя, как только число запросов увеличится. Поэтому, чтобы предотвратить прямой доступ пользователей к базе данных, Redis будет использоваться в качестве уровня кэширования. Поскольку Redis является внутренним memory database, мы можем использовать базу данных Данные кэшируются в Redis, что эквивалентно кэшированию данных в памяти.Скорость чтения и записи памяти на несколько порядков выше, чем у жесткого диска, что значительно повышает производительность системы.

С введением слоя кеша возникнут три проблемы с исключениями кеша, а именно:Лавина кеша, разбивка кеша, проникновение в кеш.

Эти три вопроса также часто задают на собеседованиях, и нам нужно знать не только, как они возникают, но и как их решать.

Адо,Идти!


Кэш Лавина

Обычно, чтобы обеспечить согласованность между данными в кеше и данными в базе данных, мы устанавливаем время истечения срока действия данных в Redis.Когда срок действия кэшированных данных истекает, если данные, к которым обращается пользователь, не находятся в cache бизнес-системе необходимо восстановить кеш, чтобы получить доступ к базе данных и обновить данные в Redis.

Тогда, когдаОдновременно истекает срок действия (аннулируется) большого объема кэшированных данных или происходит сбой Redis.В это время, если в это время имеется большое количество пользовательских запросов, они не могут быть обработаны в Redis, поэтому все запросы напрямую обращаются к базе данных, что приведет к внезапному увеличению нагрузки на базу данных, что серьезно вызовет база данных выходит из строя, образуя серию цепных реакций, в результате чего вся система рушится, и вот чтоКэш ЛавинаПроблема.

在这里插入图片描述

Как видите, лавины кеша возникают по двум причинам:

  • Срок действия большого количества данных истекает одновременно;
  • время простоя Redis из-за сбоя;

Разные стимулы, стратегии преодоления будут разными.

Срок действия большого количества данных истекает одновременно

Для проблемы лавины кеша, вызванной одновременным истечением срока действия большого объема данных, распространенными решениями являются следующие:

  • Установите время экспирации равномерно;
  • мьютекс;
  • Стратегия двойного ключа;
  • Кэш фоновых обновлений;

1. Установите время экспирации равномерно

Если вы хотите установить срок действия для кэшированных данных, вам следует избегать установки одного и того же срока действия для большого объема данных. Когда мы устанавливаем время истечения кэшированных данных,Добавить случайное число ко времени истечения этих данных, что гарантирует, что срок действия данных не истечет одновременно.

2. Мьютекс

Когда бизнес-поток обрабатывает запросы пользователей, если он обнаружит, что запрашиваемые данные не находятся в Redis, онДобавьте мьютекс, чтобы гарантировать, что одновременно будет только один запрос на создание кеша.(Прочитайте данные из базы данных, затем обновите данные в Redis) и снимите блокировку при построении кеша. Запросы, которым не удается получить мьютекс, либо ждут снятия блокировки и повторно считывают кэш, либо возвращают значение null или значение по умолчанию.

При реализации мьютекса лучше всего установитьсверхурочное время, иначе первый запрос получает блокировку, а затем этот запрос по какой-то аварии и был заблокирован, и блокировка не была снята, в это время другие запросы не смогли получить блокировку, и вся система будет казаться невосприимчивым.

3. Стратегия двойного ключа

Мы можем использовать два ключа для данных кеша, один из нихПервичный ключ, который будет устанавливать время истечения срока действия,одинРезервный ключ, срок действия не устанавливается, у них только разные ключи, но одинаковое значение, что эквивалентно созданию копии кэшированных данных.

Когда бизнес-поток не может получить доступ к кэшированным данным «первичного ключа», он напрямую возвращает кэшированные данные «резервного ключа», а затем при обновлении кэшаОдновременно обновите данные «основного ключа» и «резервного ключа»..

4. Кэш фонового обновления

Бизнес-поток больше не отвечает за обновление кеша, и кеш не устанавливает срок действия, аСделайте кеш «постоянно действительным» и передайте работу по обновлению кеша фоновому потоку для регулярного обновления..

На самом деле тот факт, что кешированные данные не имеют срока годности, не означает, что данные всегда могут находиться в памяти, т.к.Когда системной памяти мало, некоторые кешированные данные будут «устранены»., и в период с момента «удаления» кеша до следующего периодического обновления кеша в фоновом режиме бизнес-поток возвращает нулевое значение, если ему не удается прочитать кеш, и с точки зрения бизнеса данные потеряны.

Есть два пути решения вышеуказанной проблемы.

В первом случае фоновый поток отвечает не только за регулярное обновление кеша, но и заЧасто проверяйте, действителен ли кеш, обнаружено, что кеш недействителен, и причина может быть в том, что система нагружена и устранена, поэтому необходимо немедленно прочитать данные из базы данных и обновить кеш.

Интервал времени обнаружения этого метода не может быть слишком большим. Слишком длинный также приведет к тому, что данные, полученные пользователем, будут нулевым значением вместо реальных данных. Поэтому интервал обнаружения предпочтительно должен быть в миллисекундах, но всегда есть интервал , и пользовательский опыт в целом.

При втором способе, после того как бизнес-поток обнаружит, что кэшированные данные недействительны (кэшированные данные удаляются),Отправьте сообщение через очередь сообщений, чтобы уведомить фоновый поток об обновлении кэша., после того, как фоновый поток получит сообщение, он может определить, существует ли кеш перед обновлением кеша.Если он существует, он не будет выполнять операцию обновления кеша, если он не существует, он будет читать данные базы данных и загружать данные в кеш. По сравнению с первым методом обновление кеша будет более своевременным, а пользовательский опыт будет лучше.

Когда бизнес просто находится в сети, лучше буферизовать данные заранее, а не ждать, пока доступ пользователя вызовет создание кэша, что называетсяпрогрев кеша, механизм кэширования фоновых обновлений как раз подходит для этого.

Время простоя Redis

Для проблемы лавины кеша, вызванной сбоем и простоем Redis, общие методы реагирования следующие:

  • Сервисный предохранитель или запросить токоограничивающий механизм;
  • Создайте высоконадежный кластер кэша Redis;

1. Замените предохранитель или запросите механизм ограничения тока.

Когда лавина кеша вызвана простоем Redis, мы можем начатьСервисный предохранительМеханизм, который приостанавливает доступ бизнес-приложений к службе кэширования, напрямую возвращает ошибку и не требует продолжения доступа к базе данных, тем самым снижая давление доступа к базе данных и обеспечивая нормальную работу системы баз данных, а затем позволяя бизнес-приложения для доступа к службе кэширования после того, как Redis вернется в нормальное состояние.

Механизм отключения служб — это нормальное разрешение для защиты базы данных, но доступ бизнес-приложения к системе кэш-сервера приостановлен, и все службы не могут нормально работать

Чтобы уменьшить влияние на бизнес, мы можем включитьрегулирование запросовМеханизм, только небольшое количество запросов отправляется в базу данных для обработки, а большему количеству запросов напрямую отказывают в обслуживании на входе.После того, как Redis возвращается в нормальное состояние и кеш прогревается, механизм ограничения текущего запроса отключается.

2. Создайте высоконадежный кластер кэша Redis

Служебный предохранитель или механизм ограничения тока запроса — это план ответа после возникновения лавины кеша.Создайте высоконадежный кластер кэша Redis с помощью узлов master-slave..

Если главный узел кэша Redis выходит из строя и выходит из строя, подчиненный узел может переключиться на главный узел и продолжить предоставление услуг кэша, избегая проблемы лавины кэша, вызванной сбоем и простоем Redis.


разбивка кеша

В нашем бизнесе обычно есть несколько фрагментов данных, к которым часто обращаются, например действия seckill.Такие часто используемые данные называются данными горячих точек.

Если кешСрок действия данных точки доступа истекаетВ это время к горячим данным обращается большое количество запросов, они не могут быть прочитаны из кеша, а доступ к базе данных возможен напрямую.База данных легко перегружается большим количеством одновременных запросов.разбивка кешаПроблема.

Можно обнаружить, что разбивка кэша очень похожа на лавину кэша, и вы можете думать о разбивке кэша как о подмножестве лавины кэша.

Чтобы справиться с разбивкой кеша, есть два варианта, упомянутых выше:

  • Схема блокировки взаимного исключения гарантирует, что только один бизнес-поток обновляет кеш одновременно. Если запросу не удается получить блокировку мьютекса, он либо ждет снятия блокировки и повторно считывает кеш, либо возвращает нулевое значение. или значение по умолчанию.
  • Не устанавливайте время истечения срока действия для данных точки доступа, не обновляйте кеш асинхронно в фоновом режиме или заранее уведомляйте фоновый поток об обновлении кеша и сбросе срока действия до того, как данные точки доступа будут готовы к истечению срока действия;

проникновение в кеш

Когда происходит лавина или сбой кеша, данные, к которым должно получить доступ приложение, все еще хранятся в базе данных.После того, как соответствующие данные будут восстановлены из кеша, нагрузка на базу данных может быть уменьшена, в то время как проникновение в кеш отличается.

Когда пользователи получают доступ к данным,Ни в кеше, ни в базе, в результате чего при обращении к кешу возникает запрос о том, что кеш отсутствует, а при обращении к базе данных обнаруживается, что в базе данных нет данных, к которым нужно получить доступ, и нет возможности построить кэшированные данные для обслуживания последующих запросов. Затем, когда приходит большое количество таких запросов, резко возрастает нагрузка на базу данных, чтопроникновение в кешПроблема.

Проникновение в кэш обычно происходит в двух случаях:

  • Неправильная работа бизнеса, данные в кеше и данные в базе данных удалены по ошибке, поэтому в кеше и базе данных нет данных;
  • Хакеры злонамеренно атакуют и преднамеренно получают доступ к большому количеству сервисов, которые считывают несуществующие данные;

Есть три распространенных решения для борьбы с проникновением в кэш.

  • Первый вариант, ограничение нелегальных запросов;
  • Второе решение — кэшировать пустые значения или значения по умолчанию;
  • Третье решение — использовать фильтр Блума, чтобы быстро определить, существуют ли данные, и избежать запросов к базе данных, чтобы определить, существуют ли данные;

Первый вариант, ограничение нелегальных запросов

При большом количестве вредоносных запросов на доступ к несуществующим данным также будет происходить проникновение в кеш, поэтому на входе в API нам необходимо определить, являются ли параметры запроса разумными, содержат ли параметры запроса недопустимые значения и поля запроса существуют.Вредоносные запросы просто возвращают ошибку, избегая дальнейшего доступа к кешу и базе данных.

Второй вариант — кэшировать пустые значения или значения по умолчанию.

Когда наш онлайн-бизнес обнаруживает явление проникновения в кеш, мы можем установить нулевое значение или значение по умолчанию в кеше для запрошенных данных, чтобы последующие запросы могли считывать нулевое значение или значение по умолчанию из кеша и возвращать его в приложение. без продолжения запросов к базе данных.

Третье решение — использовать фильтр Блума, чтобы быстро определить, существуют ли данные, и избежать запросов к базе данных, чтобы определить, существуют ли данные.

При записи данных в базу данных мы можем использовать фильтр Блума, чтобы сделать пометку, а затем, когда поступает запрос пользователя, после того как бизнес-поток подтвердит, что кеш недействителен, мы можем быстро определить, существуют ли данные, запросив фильтр Блума. нет необходимости запрашивать базу данных, чтобы определить, существуют ли данные.

Даже если произойдет проникновение в кеш, большое количество запросов будет обращаться только к Redis и фильтрам Блума, но не к базе данных, что обеспечивает нормальную работу БД.Сам Redis также поддерживает фильтры Блума.

Итак, вопрос в том, как работает фильтр Блума? Далее, позвольте мне представить это.

Фильтр Блума состоит из двух частей: «массив растровых изображений с начальным значением 0» и «N хеш-функций». Когда мы записываем данные в базу данных, мы делаем отметку в фильтре Блума, чтобы в следующий раз, когда мы запрашиваем, есть ли данные в базе данных, нам нужно было запросить только фильтр Блума.Если запрашиваемые данные не отмечены, это означает что его нет в базе.

Фильтр Блума завершает тегирование за 3 операции:

  • Первый шаг — использовать N хеш-функций для хэширования данных, соответственно, для получения N хэш-значений;
  • На втором этапе N хеш-значений, полученных на первом этапе, являются по модулю длины массива битовых карт, чтобы получить соответствующую позицию каждого значения хеш-функции в массиве битовых карт.
  • Третий шаг — установить значение каждого хеш-значения в соответствующей позиции массива растровых изображений равным 1;

В качестве примера предположим, что имеется фильтр Блума с длиной массива растровых изображений, равной 8, и хэш-функцией, равной 3.

在这里插入图片描述

После того, как база данных запишет данные x, когда данные x помечены в фильтре Блума, данные x будут вычислены с помощью 3-х хеш-функций для получения 3-х хеш-значений, а затем 3 хэш-значения будут по модулю 8. , предполагая что результат по модулю равен 1, 4, 6, а затем установите значение 1-й, 4-й и 6-й позиций массива растровых изображений равным 1.Когда приложение хочет запросить, находятся ли данные x в базе данных, фильтру Блума нужно только проверить, равны ли все значения в 1-й, 4-й и 6-й позициях массива растровых изображений 1. Пока одно из значения равно 0, считается, что данных x нет в базе..

Поскольку фильтр Блума основан на хеш-функции для реализации поиска, он может одновременно выполнять поиск эффективно.Возможность коллизии хэшей, например, данные x и данные y могут оказаться на 1-й, 4-й и 6-й позициях, но на самом деле данных y может не быть в базе данных, и есть неверная оценка.

так,Запрос фильтра Блума о том, что данные существуют, не обязательно доказывает, что данные существуют в базе данных, но если данные не существуют в запросе, данные не должны существовать в базе данных..


Суммировать

Есть три проблемы, с которыми столкнутся исключения кэша: лавины кэша, сбои и проникновения.

Среди них основная причина лавины кеша и поломки кеша заключается в том, что данные не находятся в кеше, что приводит к большому количеству запросов, обращающихся к базе данных, и резко возрастает давление базы данных, что легко спровоцирует серию цепных реакций и привести к сбою системы. Однако, как только данные будут повторно загружены обратно в кеш, приложение может быстро прочитать данные из кеша и прекратить доступ к базе данных, а нагрузка на базу данных мгновенно снизится. Таким образом, решения для лавины кеша и разбивки кеша аналогичны.

Основная причина проникновения в кеш заключается в том, что данных нет ни в кеше, ни в базе данных. Таким образом, проникновение в кеш отличается от решений по лавине и сбою кеша.

Я составил таблицу здесь, и вы можете получить хорошее представление о разнице между лавинами кеша, поломками и проникновениями и решениями из таблицы ниже.


использованная литература
  1. «Geek Time: основные технологии и практика Redis»
  2. GitHub.com/ohohgenerate/advpress…
  3. medium.com/@boring.MES э…