Чем тяжелее, тем удачливее,
Эта статья собрана на GitHubJavaCommunity, Есть обмен интервью, статьи серии анализа исходного кода, добро пожаловать на сбор, какGitHub.com/cc Ask Me-Contact/Jav…
В реальных рабочих проектах кеш стал ключевым компонентом архитектуры с высокой степенью параллелизма и высокой производительностью, так почему же Redis можно использовать в качестве кеша? Первыми могут служить две основные характеристики кэша:
- Нахождение в памяти/ЦП в многоуровневой системе имеет хорошую производительность доступа,
- Данные кеша переполнены, и есть хороший механизм удаления данных
Поскольку Redis естественным образом обладает этими двумя характеристиками, Redis основан на работе с памятью и имеет идеальный механизм удаления данных, который очень подходит в качестве компонента кэша.
Среди них, в зависимости от работы памяти, емкость может составлять 32-96 ГБ, а среднее время работы составляет 100 нс, а эффективность работы высока. Механизмов удаления данных много, после Redis 4.0 их 8 видов, что делает Redis как кеш применимым ко многим сценариям.
Так зачем же кэшу Redis нужен механизм удаления данных? Каковы 8 механизмов удаления данных?
Механизм удаления данных
Кэш Redis реализован на основе памяти, и его объем кеша ограничен.Когда кеш заполнен, как Redis должен с ним справиться?
Когда кеш заполнен, Redis требуется механизм удаления данных кеша, а некоторые данные очищаются и удаляются с помощью определенных правил исключения, чтобы можно было повторно использовать службу кеша. Итак, какие стратегии устранения использует Redis для удаления данных?
После Redis 4.0 существует 6+2 типа стратегий устранения кеша Redis, включая три категории:
- данные не удаляются
- noeviction , без удаления данных, при заполнении кеша Redis не предоставляет услуги и возвращает ошибку напрямую.
- В паре ключ-значение, которая устанавливает время истечения срока действия,
- volatile-random , случайным образом удаляет пары ключ-значение с установленным сроком действия
- volatile-ttl , пара ключ-значение, которая устанавливает время истечения срока действия, удаляется в соответствии с порядком времени истечения срока действия, и чем раньше он истечет, тем раньше он будет удален.
- volatile-lru , основанный на алгоритме LRU (наименее недавно использованный) для фильтрации пар ключ-значение с установленным временем истечения срока действия и фильтрации данных на основе принципа наименее недавно использованного
- volatile-lfu , используйте алгоритм LFU ( наименее часто используемый ) для выбора пары ключ-значение с установленным временем истечения срока действия и используйте пару ключ-значение с наименьшей частотой для фильтрации данных.
- Во всех парах ключ-значение
- allkeys-random, случайный выбор и удаление данных из всех пар ключ-значение
- allkeys-lru, фильтровать все данные с использованием алгоритма LRU
- allkeys-lfu, фильтровать все данные с помощью алгоритма LFU
Note: Алгоритм LRU (наименее недавно использованный, наименее недавно использованный), LRU поддерживает двусвязный список, начало и конец связанного списка представляют сторону MRU и сторону LRU соответственно, представляя самые последние использованные данные и самые последние использованные данные .
Когда алгоритм LRU фактически реализован, для управления всеми кэшированными данными необходимо использовать связанный список, что приведет к дополнительным затратам пространства. Кроме того, при доступе к данным данные необходимо перемещать на сторону MRU в связанном списке.Если осуществляется доступ к большому объему данных, это приведет к большому количеству операций перемещения связанного списка, которые будут занимать много времени и уменьшать производительность кэша Redis.
Среди них LRU и LFU реализованы на основе атрибутов lru и refcount объектной структуры Redis redisObject:
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
// 对象最后一次被访问的时间
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
// 引用计数 * and most significant 16 bits access time). */
int refcount;
void *ptr;
} robj;
LRU Redis будет использовать lru redisObject для записи времени последнего доступа, случайным образом выберет число, заданное параметром maxmemory-samples, в качестве набора кандидатов, и выберет данные с наименьшим значением атрибута lru для исключения.
В реальных проектах, как выбрать механизм удаления данных?
- Алгоритм allkeys-lru предпочтительнее хранить самые последние данные, к которым обращались, в кэше, чтобы улучшить производительность доступа приложения.
- Алгоритм volatile-lru используется для служебных данных, время истечения кэша не устанавливается для служебных данных, а время истечения устанавливается для других данных, которые фильтруются на основе правил LRU.
Разобравшись с механизмом устранения кеша Redis, давайте посмотрим, сколько режимов есть у Redis в качестве кеша?
Режим кэширования Redis
Режим кеша Redis можно разделить на кеш только для чтения и кеш чтения-записи в зависимости от того, получены ли запросы на запись:
Кэш только для чтения: Обрабатываются только операции чтения, все операции обновления находятся в базе данных, поэтому риск потери данных отсутствует.
- Кэш-режим
Кэш чтения и записи, операции чтения и записи выполняются в кеше, а сбой во время простоя приведет к потере данных. Данные обратной записи кэша в базу данных можно разделить на два типа: синхронные и асинхронные:
-
Синхронизация: производительность доступа низкая, и больше внимания уделяется обеспечению надежности данных.
- Режим сквозного чтения
- Режим сквозной записи
-
Асинхронный: риск потери данных, основное внимание уделяется обеспечению доступа с малой задержкой.
- Режим отложенной записи
Кэш-режим
Данные запроса сначала считывают данные из кеша, если его нет в кеше, затем считывают данные из базы данных, а затем обновляют их в кеше после получения данных.Однако операция обновления данных сначала обновит данные в базе данных, а затем сделает недействительными данные в кэше.
Кроме того, в режиме Cache Aside существует риск параллелизма: операция чтения пропускает кеш, а затем запрашивает базу данных для извлечения данных, данные были запрошены и не были помещены в кеш. Операция обновления и записи аннулирует кеш, а затем операция чтения извлекает данные.Загружает кеш, в результате чего кешируются грязные данные.
Режим чтения/записи
Как данные запроса, так и данные обновления напрямую обращаются к службе кэширования,Служба кеша синхронно обновляет данные в базе данных.. Вероятность грязных данных низкая, но сильно зависит от кеша, который предъявляет более высокие требования к стабильности службы кеша, но синхронное обновление приведет к плохой производительности.
Режим записи позади
Как данные запроса, так и данные обновления напрямую обращаются к службе кэширования,Но служба кеша использует асинхронный способ обновления данных в базе данных (через асинхронные задачи).Скорость высокая, а эффективность будет очень высокой, но согласованность данных относительно плохая, возможна потеря данных, а логика реализации сложнее.
При разработке реального проекта режим кэширования выбирается в соответствии с реальными требованиями бизнес-сценария. После понимания вышесказанного, почему нам нужно использовать кеш Redis в нашем приложении?
Использование кэша Redis в приложениях может улучшить производительность системы и параллелизм, что в основном отражается на
- Высокая производительность: на основе запроса памяти, структуры KV, простой логической операции
- Высокий параллелизм: Mysql может поддерживать только около 2000 запросов в секунду, а Redis легко превышает 1 Вт в секунду. Пусть более 80% запросов отправляются в кеш, а менее 20% запросов отправляются в базу данных, что может значительно повысить пропускную способность системы.
Хотя использование кеша Redis может значительно улучшить производительность системы, но при использовании кеша возникнут некоторые проблемы, такие как двунаправленное несоответствие между кешем и базой данных, лавина кеша и т. д. Как решить эти проблемы?
Распространенные проблемы с использованием кеша
При использовании кеша возникнут некоторые проблемы, в основном отраженные в:
- Несоответствие между кешем и двойной записью базы данных
- Лавина кеша: кеш Redis не может обработать большое количество запросов приложений, а перенос на уровень базы данных вызывает резкое увеличение нагрузки на уровень базы данных;
- Проникновение в кеш: данные доступа не существуют в кеше и базе данных Redis, что приводит к тому, что большое количество кешей проникновения доступа передается непосредственно в базу данных, что приводит к резкому увеличению нагрузки на уровень базы данных;
- Нарушение кэша: кэш не может обрабатывать высокочастотные горячие данные, что приводит к прямому высокочастотному доступу к базе данных, что приводит к скачку нагрузки на уровень базы данных;
Несоответствие между кэшем и данными базы данных
Кэш только для чтения (режим Cache Aside)
заКэш только для чтения (режим Cache Aside), все операции чтения происходят в кэше, а несогласованность данных возникает только вудалить операциюOn (новой операции не будет, т.к. новое добавление будет обрабатываться только в базе данных), когда произойдет операция удаления, кеш пометит данные как недействительные и обновит базу данных. Следовательно, в процессе обновления базы данных и удаления закэшированного значения, независимо от порядка выполнения двух операций, до тех пор, пока одна операция не будет выполнена, возникнет несогласованность данных.
подвела,При отсутствии параллелизма используйте механизм повтора (используется очередями сообщений), а при высоком параллелизме используйте отложенное двойное удаление (после первого удаления спите в течение определенного периода времени, а затем удаляйте), подробности следующим образом:
последовательность операций | Это высокий параллелизм | потенциальные проблемы | Феномен | план выживания |
---|---|---|---|---|
Сначала удалите кэш, затем обновите базу данных. | нет | Удаление кеша прошло успешно, обновление базы данных не удалось | прочитать старое значение базы данных | Механизм повтора (обновление базы данных) |
Сначала обновите базу данных, затем удалите кеш. | нет | Обновление базы данных выполнено успешно, удаление кеша не удалось | прочитать кешированное старое значение | Механизм повтора (удаление кеша) |
Сначала удалите кэш, затем обновите базу данных. | да | После удаления кеша база данных не обновлялась, и есть параллельные запросы на чтение | Параллельные запросы на чтение считывают старое значение базы данных и обновляют его в кэше, в результате чего последующие запросы на чтение считывают старое значение. | задержка двойного удаления () |
Сначала обновите базу данных, затем удалите кеш. | да | Обновление базы данных выполнено успешно, кеш не удален | прочитать кешированное старое значение | Несоответствие существует в течение короткого времени и мало влияет на бизнес |
NOTE:
Псевдокод отложенного двойного удаления:
redis.delKey(X) db.update(X) Thread.sleep(N) redis.delKey(X)
Чтение и запись кэша (режим Read/Write-Throug, Write Behind)
Для кэша чтения-записи все операции записи происходят в кэше, а затем база данных обновляется.Если хотя бы одна операция завершается неудачей, возникает несогласованность данных.
Делается вывод, что механизм повторных попыток (используемый очередями сообщений) используется при отсутствии параллелизма, а распределенные блокировки — при высоком параллелизме. детали следующим образом:
последовательность операций | Это высокий параллелизм | потенциальные проблемы | Феномен | план выживания |
---|---|---|---|---|
Сначала обновите кэш, затем обновите базу данных. | нет | Обновление кеша выполнено успешно, обновление базы данных не выполнено | Последнее значение будет считано из кеша, что не оказывает краткосрочного влияния. | Механизм повтора (обновление базы данных) |
Сначала обновите базу данных, затем обновите кеш. | нет | Обновление базы данных выполнено успешно, обновление кеша не удалось | прочитает старое значение из кеша | Механизм повтора (удаление кеша) |
Сначала обновите базу данных, затем обновите кеш. | параллелизм записи + чтения | Поток A сначала обновляет базу данных, затем поток B считывает данные, а затем поток A обновляет кеш. | B попадет в кеш и прочитает старое значение | Оказывает временное влияние на бизнес до обновления кеша |
Сначала обновите кэш, затем обновите базу данных. | параллелизм записи + чтения | Сначала поток A успешно обновляет кеш, а затем данные считывает поток B. В это время поток B обращается к кешу, считывает последнее значение и возвращает результат, а затем поток A успешно обновляет базу данных. | B попадет в кеш и прочитает последнее значение | Нет влияния на бизнес |
Сначала обновите базу данных, затем обновите кеш. | запись + запись параллелизма | Поток A и поток B одновременно обновляют одни и те же данные. Порядок обновления базы данных — сначала A, а затем B, но порядок обновления кеша — сначала B, а затем A, что приведет к несогласованности между базой данных и кеш. | Несогласованность базы данных и кеша | Операция записи плюс распределенная блокировка |
Сначала обновите кэш, затем обновите базу данных. | запись + запись параллелизма | Поток A и поток B одновременно обновляют одни и те же данные.Порядок обновления кеша — сначала A, а затем B, но порядок обновления базы данных — сначала B, а затем A, что также приведет к несогласованности между базой данных. и кеш. | Несогласованность базы данных и кеша | Операция записи плюс распределенная блокировка |
Кэш Лавина
Лавина кеша, поскольку срок действия большого объема данных в кеше истекает одновременно или кеш не работает, большое количество запросов приложений не может быть обработано в кеше Redis, а затем отправлено на уровень базы данных, что приводит к всплеску давление на уровень базы данных, что приведет к серьезному простою базы данных.
Для большого количества данных в кэше, срок действия которых истекает одновременно, что приводит к большому количеству запросов, которые невозможно обработать, решение:
-
Прогрев данных,Вручную инициируйте загрузку и кэширование различных ключей до того, как произойдет большой одновременный доступ, что позволяет избежать предварительного запроса к базе данных, когда пользователь запрашивает
-
Установите разные сроки действия, чтобы сделать момент аннулирования кеша как можно более однородным.
-
Стратегия двухуровневого кэширования, добавление кеша копии в исходный кеш, к кешу копии можно получить доступ, когда исходный кеш выходит из строя, и срок действия исходного кеша установлен на краткосрочный, а кеш копии установлен на долгосрочный.
-
Деградация сервиса, когда происходит лавина кеша, для разных данных применяются разные схемы деградации., например, неосновные данные напрямую возвращают предопределенную информацию, нулевое значение или информацию об ошибке.
Для простоя кеша решение:
- Внедрите сервисный предохранитель или механизм ограничения тока запроса в бизнес-системе, чтобы предотвратить простои базы данных, вызванные большим количеством обращений.
проникновение в кеш
Проникновение кеша, данные отсутствуют в базе данных и кеше, что приводит к запросу данных.Если значение соответствующего ключа не может быть найдено в кеше, необходимо снова обратиться к базе данных для повторного запроса, а затем вернуться пустой (эквивалентно выполнению дважды бесполезного запроса).
Когда есть большое количество запросов на доступ, и он обходит кеш и напрямую проверяет базу данных, нагрузка на уровень базы данных резко возрастает, что может привести к серьезному сбою базы данных.
Для проникновения в кеш решение:
- Кэш пустой или значение по умолчанию. Когда данные, возвращаемые запросом, пусты, пустой результат также будет кэшироваться, а срок его действия будет установлен на короткое время, а значение будет получено непосредственно из кеша при следующем посещении. , избегая большого количества запросов, отправляйте его в базу данных для обработки, вызывая проблему с базой данных.
- Фильтр Блума (BloomFilter), хешируйте все возможные ключи данных запроса в достаточно большое растровое изображение, сначала зайдите в BloomFilter, чтобы проверить, существует ли ключ при запросе, если он не существует, верните его напрямую, а затем запросите кеш, если он существует, и нет дальнейший запрос в кэш базы данных, тем самым избегая простоев из-за скачков нагрузки на уровень базы данных.
разбивка кеша
Нарушение кеша для данных точки доступа, к которым обращаются очень часто, срок действия которых истекает и происходит сбой, в результате чего доступ не может быть обработан в кеше, что приведет к большому количеству прямых запросов к базе данных, что увеличит нагрузку на уровень базы данных и привести к серьезному простою базы данных.
Для разбивки кеша решение:
- Срок действия не установлен.Для данных точки доступа, к которым осуществляется очень частый доступ, срок действия не установлен.
Суммировать
В большинстве бизнес-сценариев кэш Redis используется как кэш только для чтения. Для кэшей только для чтения метод сначала обновляет базу данных, а затем удаляет кэш, чтобы обеспечить согласованность данных.
Среди них причины и решения трех основных проблем лавины кеша, проникновения в кеш и поломки кеша.
вопрос | причина | Решение |
---|---|---|
Кэш Лавина | Срок действия большого количества данных истекает одновременно Кэш не работает |
Прогрев данных Установите другое время истечения срока действия Стратегия двухуровневого кэширования понижение уровня обслуживания Сервисный предохранитель Механизм ограничения тока |
проникновение в кеш | Данные отсутствуют ни в базе данных, ни в кеше | Кэш пустой или значение по умолчанию Фильтр Блума (BloomFilter ) |
разбивка кеша | Срок действия данных точки доступа, к которым осуществляется очень частый доступ, истекает | Для данных точки доступа, к которым осуществляется очень частый доступ, срок действия не устанавливается. |
Спасибо за ваши лайки, если не нравится ставьте лайк и поддержите
Наконец, WeChat ищет «Ccww Technology Blog», чтобы посмотреть больше статей, и добро пожаловать на волну
`