В современной архитектуре Интернета почти в каждом Интернет-проекте будет внедрена система кэширования, такая как Redis и Memcached. Для защиты нижестоящих баз данных и улучшения параллелизма системы. Независимо от того, какая система кэширования используется, можно столкнуться спроникновение в кешЭта проблема.
Проникновение в кеш относится к ситуации, когда данные не запрашиваются в системе кеша, но запрос должен быть отправлен в базу данных для запроса.
Конечно, система кеша неизбежна, и небольшое проникновение кеша не повредит системе.Неизбежные причины следующие:
- Емкость кеш-системы ограничена, и невозможно хранить все данные в системе, поэтому при запросе некэшированных данных будет происходить проникновение в кеш.
- С другой стороны, основываясь на «принципе 208», мы обычно кэшируем только 20% часто используемых горячих данных.
При нормальных обстоятельствах проникновение в кеш безвредно, но если ваша система атакована и есть большое количество проникновений в кеш, это может быть проблемой.Если большое количество проникновений в кеш превышает возможности внутреннего сервера, то есть возможность сбоя службы, что недопустимо.
Исходя из возможности такого большого количества проникновений в кеш, нам необходимо решить проблему проникновения в кеш от корня и решить проблему проникновения в кеш.В настоящее время обычно есть два решения:Кэширование нулей и использование фильтров Блума.
Кэшировать пустые значения
Если наша система подвергнется атаке, очень вероятно, что запрошенное значение подделано, и есть большая вероятность, что оно не существует в нашей системе, поэтому, сколько бы раз оно ни запрашивалось, оно никогда не будет существовать в кеше, так что проникновение в кеш будет всегда.
В этом случае мы можем кэшировать нулевое значение в системе кэширования, чтобы предотвратить постоянное проникновение, но поскольку нулевое значение не является точными бизнес-данными и будет занимать место в кэше, мы добавим значение к этому нулевому значению. Относительно короткое время истечения позволяет быстро истечь и устранить нулевые значения в течение короткого периода времени. Вот кусок псевдокода:
Object nullValue = new Object();
try {
Object valueFromDB = getFromDB(uid); //从数据库中查询数据
if (valueFromDB == null) {
cache.set(uid, nullValue, 10); //如果从数据库中查询到空值,就把空值写入缓存,设置较短的超时时间
} else {
cache.set(uid, valueFromDB, 1000);
}
} catch(Exception e) {
cache.set(uid, nullValue, 10);
}
Хотя этот метод может решить проблему проникновения в кэш, он также имеет недостатки.Поскольку в системе кеша хранится большое количество нулевых значений, пространство для хранения кеша тратится впустую.Если пространство кеша заполнено, некоторая пользовательская информация, которая была в кеше, также будет удалена, что приведет к попаданию в кеш. скорость падать.
Используйте фильтр Блума
В 1970 году Блум предложил алгоритм фильтра Блума для определения того, входит ли элемент в набор. Нижний слой фильтра Блума представляет собой очень большой битовый массив. Значение по умолчанию — 0. Элемент сопоставляется с этим битовым массивом с помощью нескольких хэш-функций, и 0 изменяется на 1. Фильтр Блума нам, конечно, реализовывать не нужно, фильтр Блума есть в пакете Google guava, заинтересованные партнеры могут его изучить.
Существует определенное неправильное изменение фильтра Bloom, поскольку используется хеш-алгоритм, должны быть хэш-конфликты, которые могут вызвать элементы, которые не являются в базе данных, которые необходимо оценить, чтобы существовать в фильтре Bloom, ноЭлементы, которых нет в фильтре Блума, не должны существовать в базе данных.
Использование этой функции фильтра Блума может решить проблему проникновения в кеш,При запуске службы сначала сопоставьте условия запроса данных, такие как идентификатор данных, с фильтром Блума.Конечно, если вы добавляете новые данные, помимо записи их в базу данных, вам также необходимо сохранить идентификатор данных в фильтре Блума.Длинный фильтр.
Когда мы запрашиваем фрагмент данных, мы сначала определяем, существует ли идентификатор запроса в фильтре Блума. Если он не существует, мы вернем нулевое значение напрямую, не продолжая запрашивать базу данных и кэш. Если он существует в фильтре Блума. Фильтр Блума, мы будем продолжать делать запросы к базе данных и кешу, что решает проблему проникновения в кеш.
Конечно, фильтр Блума несовершенен.Помимо некоторых заблуждений, о которых мы упоминали выше,Удаление не поддерживается.
Как кэширование нулевых значений, так и использование фильтров Блума могут в определенной степени решить проблему проникновения в кеш, каждый из них имеет свои преимущества, и то, как его использовать, зависит от конкретных сценариев.
Вышеупомянутое содержание является сегодня опубликованным. Я надеюсь, что это будет полезно для вашей учебы или работы. Если вы считаете, что статья хороша, пожалуйста, отметьте и перешлите ее, спасибо.
наконец
В настоящее время многие большие ребята в Интернете имеют статьи, связанные с проникновением в кеш, Если есть какие-то сходства, пожалуйста, потерпите меня. Нелегко быть оригинальным, и нелегко кодировать слова, я также надеюсь, что вы поддержите это. Если в тексте будут ошибки, надеюсь сообщить о них, спасибо.