Общие проблемы с кэшем и решения

Redis

Обратите внимание на общественное число: XY Technology Circle

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

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

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

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

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

решение

Следующие решения:

  • Проверьте параметры запроса, такие как проверка аутентификации пользователя, проверка базовой идентификации,id <= 0прямой перехват.
  • Если в базе данных нет значения, соответствующий ключ также сохраняется в кэше, а значениеnull. Таким образом, следующий запрос будет возвращен непосредственно из кеша. Но время кэширования ключа здесь должно быть относительно коротким, например 30 с. Предотвратить вставку этих данных в базу данных позже, но пользователь не сможет их получить.
  • Используйте фильтр Блума, чтобы определить, был ли проверен ключ.Если он был проверен, база данных не будет запрашиваться.

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

Разбивка кеша относится к,ключКоличество посещений очень велико. Например, активность seckill имеет параллелизм 1w/s.Срок действия этого ключа истекает в какой-то момент, то это большое количество запросов мгновенно попадет в базу данных, и база данных может сразу рухнуть.

решение

Также есть несколько решений для разбивки кеша, которые можно использовать вместе:

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

Кэш Лавина

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

решение

Для двух вышеуказанных ситуаций есть два решения для лавины кеша:

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

Несоответствие двойной записи

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

  • При чтении читать сначала кеш, если кеша нет, читать напрямую из базы, потом вынимать данные и класть в кеш
  • При обновлении сначала удалите кеш, а потом обновите базу

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

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

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

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

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

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

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

Внимательно пишите статьи и делитесь ими с душой.

Персональный сайт:yasinshaw.com

Общедоступный номер: технический круг xy