Стратегии обновления кеша
Обновлено: 21.11.2024
В следующем разделе вы можете найти стратегии заполнения и обслуживания кэша.
Какие стратегии использовать для заполнения и обслуживания кэша, зависит от того, какие данные вы кэшируете, и от шаблонов доступа к этим данным. Например, вы, вероятно, не захотите использовать одну и ту же стратегию как для топ-10 лидеров на игровом сайте, так и для популярных новостей. В оставшейся части этого раздела мы обсудим распространенные стратегии обслуживания кэша, их преимущества и недостатки.
Темы
Отложенная загрузка
Как следует из названия, отложенная загрузка – это стратегия кэширования, при которой данные загружаются в кэш только при необходимости. Это работает, как описано ниже.
Amazon ElastiCache – это хранилище пар "ключ-значение" в памяти, которое находится между вашим приложением и хранилищем данных (базой данных), к которому оно обращается. Всякий раз, когда ваше приложение запрашивает данные, оно сначала делает запрос к кэшу ElastiCache. Если данные существуют в кэше и актуальны, ElastiCache возвращает данные вашему приложению. Если данные отсутствуют в кэше или срок их действия истек, ваше приложение запрашивает данные из хранилища данных. Затем ваше хранилище данных возвращает данные вашему приложению. Затем ваше приложение записывает данные, полученные из хранилища, в кеш. Таким образом, при следующем запросе его можно будет получить быстрее.
Попадание в кэш происходит, когда данные находятся в кеше и срок их действия не истек:
Ваше приложение запрашивает данные из кеша.
Кэш возвращает данные в приложение.
Промах в кеше возникает, когда данных нет в кеше или срок их действия истек:
Ваше приложение запрашивает данные из кеша.
В кеше нет запрошенных данных, поэтому возвращается null .
Ваше приложение запрашивает и получает данные из базы данных.
Ваше приложение обновляет кэш новыми данными.
Преимущества и недостатки отложенной загрузки
Преимущества отложенной загрузки следующие:
Кэшируются только запрошенные данные.
Поскольку большая часть данных никогда не запрашивается, отложенная загрузка позволяет избежать заполнения кеша незапрошенными данными.
Сбои узлов не являются фатальными для вашего приложения.
Когда узел выходит из строя и заменяется новым, пустым узлом, ваше приложение продолжает работать, хотя и с увеличенной задержкой. По мере выполнения запросов к новому узлу каждый промах кэша приводит к запросу базы данных. В то же время копия данных добавляется в кеш, чтобы последующие запросы извлекались из кеша.
Отложенная загрузка имеет следующие недостатки:
Существует штраф за промах кэша. Каждый промах кеша приводит к трем срабатываниям:
Первоначальный запрос данных из кеша
Запрос к базе данных
Запись данных в кеш
Эти промахи могут привести к заметной задержке поступления данных в приложение.
Если данные записываются в кеш только при промахе, данные в кеше могут устареть. Этот результат возникает из-за отсутствия обновлений кэша при изменении данных в базе данных. Чтобы решить эту проблему, вы можете использовать стратегии сквозной записи и добавления TTL.
Пример отложенной загрузки псевдокода
Ниже приведен пример псевдокода логики отложенной загрузки.
Для этого примера код приложения, который получает данные, выглядит следующим образом.
Сквозная запись
Стратегия сквозной записи добавляет данные или обновляет данные в кэш всякий раз, когда данные записываются в базу данных.
Преимущества и недостатки сквозной записи
Преимущества сквозной записи заключаются в следующем:
Данные в кеше никогда не устаревают.
Поскольку данные в кеше обновляются каждый раз, когда они записываются в базу данных, данные в кеше всегда актуальны.
Штраф на запись и штраф на чтение.
Каждое письмо включает в себя две поездки:
Запись в кеш
Запись в базу данных
Что увеличивает задержку процесса. Тем не менее, конечные пользователи обычно более терпимы к задержкам при обновлении данных, чем при извлечении данных. Существует неотъемлемое ощущение, что обновления требуют больше работы и поэтому занимают больше времени.
Недостатки сквозной записи заключаются в следующем:
Если вы запускаете новый узел из-за сбоя узла или масштабирования, данные отсутствуют. Эти данные по-прежнему отсутствуют, пока они не будут добавлены или обновлены в базе данных. Вы можете свести к минимуму это, внедрив ленивую загрузку со сквозной записью.
Большинство данных никогда не читаются, что является пустой тратой ресурсов. Добавив значение срока жизни (TTL), вы можете свести к минимуму неиспользуемое пространство.
Пример псевдокода со сквозной записью
Ниже приведен пример псевдокода логики сквозной записи.
Для этого примера код приложения, который получает данные, выглядит следующим образом.
Добавление срока жизни
Отложенная загрузка допускает устаревшие данные, но не завершается ошибкой при пустых узлах.Сквозная запись гарантирует, что данные всегда будут свежими, но может произойти сбой с пустыми узлами и может заполнить кэш лишними данными. Добавляя значение времени жизни (TTL) к каждой записи, вы можете использовать преимущества каждой стратегии. В то же время вы можете избежать загромождения кэша лишними данными.
Время жизни (TTL) – это целочисленное значение, указывающее количество секунд до истечения срока действия ключа. Memcached указывает это значение в секундах. Когда приложение пытается прочитать ключ с истекшим сроком действия, оно обрабатывается так, как если бы ключ не был найден. База данных запрашивается для ключа, и кеш обновляется. Этот подход не гарантирует, что значение не устарело. Однако он не позволяет данным слишком устаревать и требует, чтобы значения в кеше время от времени обновлялись из базы данных.
Для получения дополнительной информации см. команду Memcached set .
Примеры псевдокода TTL
Ниже приведен пример псевдокода логики сквозной записи с TTL.
Ниже приведен пример псевдокода логики ленивой загрузки с TTL.
Для этого примера код приложения, который получает данные, выглядит следующим образом.
Coherence поддерживает прозрачное кэширование чтения/записи любого источника данных, включая базы данных, веб-службы, упакованные приложения и файловые системы; однако базы данных являются наиболее распространенным вариантом использования. В качестве сокращения «база данных» будет использоваться для описания любого внутреннего источника данных. Эффективные кэши должны поддерживать как интенсивные операции только для чтения, так и операции чтения/записи, а в случае операций чтения/записи кэш и база данных должны быть полностью синхронизированы. Для этого Coherence поддерживает кэширование сквозного чтения, сквозной записи, опережающего обновления и отложенной записи.
Для использования с топологиями секционированного (распределенного) и ближнего кэша. Кэширование со сквозной записью и чтением (и варианты) предназначены для использования только с топологией секционированного (распределенного) кэша (и, соответственно, ближнего кэша). Локальные кэши поддерживают часть этой функциональности. Реплицированные и оптимистичные кэши не должны использоваться.
Подключаемое хранилище кеша
CacheStore — это адаптер для конкретного приложения, используемый для подключения кеша к базовому источнику данных. Реализация CacheStore обращается к источнику данных с помощью механизма доступа к данным (например, Hibernate, Toplink Essentials, JPA, вызовов JDBC для конкретного приложения, другого приложения, мейнфрейма, другого кэша и т. д.). CacheStore понимает, как создать объект Java, используя данные, полученные из источника данных, сопоставить и записать объект в источник данных, а также удалить объект из источника данных.
Как стратегия подключения к источнику данных, так и информация о сопоставлении источника данных с объектом приложения зависят от схемы источника данных, макета класса приложения и операционной среды. Поэтому эта информация о сопоставлении должна быть предоставлена разработчиком приложения в форме реализации CacheStore. Дополнительные сведения см. в разделе «Создание реализации CacheStore».
Кэширование чтения
Когда приложение запрашивает в кеше запись, например ключ X , а X еще нет в кеше, Coherence автоматически делегирует CacheStore и просит загрузить X из базового источника данных. Если X существует в источнике данных, CacheStore загрузит его, вернет в Coherence, затем Coherence поместит его в кеш для будущего использования и, наконец, вернет X коду приложения, которое его запросило. Это называется сквозным кэшированием. Функциональность Refresh-Ahead Cache может дополнительно улучшить производительность чтения (за счет уменьшения воспринимаемой задержки). Дополнительные сведения см. в разделе "Кэширование с опережением обновления".
Рис. 13-1. Кэширование со сквозным чтением
Кэширование со сквозной записью
Coherence может обрабатывать обновления в источнике данных двумя различными способами, первый из которых — сквозная запись. В этом случае, когда приложение обновляет часть данных в кеше (то есть вызывает put(.) для изменения записи в кеше), операция не завершится (то есть put не вернется) до тех пор, пока Coherence не исчезнет. через CacheStore и успешно сохранили данные в базовом источнике данных. Это совсем не улучшает производительность записи, поскольку вы по-прежнему имеете дело с задержкой записи в источник данных. Повышение производительности записи является целью функции кэша с отложенной записью. Дополнительные сведения см. в разделе "Кэширование с обратной записью".
Рис. 13-2. Кэширование со сквозной записью
Кэширование с обратной записью
В сценарии с отложенной записью измененные записи кэша асинхронно записываются в источник данных после настроенной задержки, будь то через 10 секунд, 20 минут, день, неделю или даже дольше. Обратите внимание, что это относится только к вставкам и обновлениям кэша — записи кэша удаляются из источника данных синхронно. Для кэширования с отложенной записью Coherence поддерживает очередь отложенной записи для данных, которые должны быть обновлены в источнике данных. Когда приложение обновляет X в кэше, X добавляется в очередь отложенной записи (если его там еще нет; в противном случае он заменяется), и после указанной задержки отложенной записи Coherence вызывает CacheStore для обновления базовый источник данных с последним состоянием X . Обратите внимание, что задержка отложенной записи относится к первой из серии модификаций — другими словами, данные в источнике данных никогда не будут отставать от кэша более чем на задержку отложенной записи.
Приложение улучшает производительность, поскольку пользователю не нужно ждать, пока данные будут записаны в базовый источник данных. (Данные записываются позже и другим потоком выполнения.)
Приложение испытывает резкое снижение нагрузки на базу данных: поскольку количество операций чтения и записи уменьшается, нагрузка на базу данных уменьшается. Кэширование уменьшает количество операций чтения, как и при любом другом подходе к кэшированию. Записи, которые обычно являются гораздо более дорогостоящими операциями, часто сокращаются, поскольку множественные изменения одного и того же объекта в пределах интервала отложенной записи «объединяются» и записываются в базовый источник данных только один раз («объединение записи»). Кроме того, запись в несколько записей кэша может быть объединена в одну транзакцию базы данных ("объединение записи") с помощью метода CacheStore.storeAll().
Приложение в некоторой степени изолировано от сбоев базы данных: функция отложенной записи может быть настроена таким образом, что сбой записи приведет к повторной постановке объекта в очередь для записи. Если данные, которые использует приложение, находятся в кэше Coherence, приложение может продолжать работу без запуска базы данных. Это легко достижимо при использовании секционированного кэша Coherence, который распределяет весь кэш по всем участвующим узлам кластера (с включенным локальным хранилищем), что позволяет использовать огромные кэши.
Линейная масштабируемость: чтобы приложение могло обрабатывать больше одновременных пользователей, вам нужно только увеличить количество узлов в кластере; влияние на базу данных с точки зрения нагрузки можно настроить, увеличив интервал отложенной записи.
Рис. 13-3. Кэширование с отложенной записью
Требования к обратной записи
Хотя включение кэширования с отложенной записью — это просто вопрос настройки одного параметра конфигурации, обеспечение того, чтобы отложенная запись работала должным образом, является более сложной задачей. В частности, при разработке приложения необходимо заранее решить несколько проблем.
Наиболее прямым следствием кэширования с отложенной записью является то, что обновления базы данных происходят вне транзакции кэширования; то есть транзакция кэша (в большинстве случаев) завершится до начала транзакции базы данных. Это подразумевает, что транзакции базы данных никогда не должны прерываться; если это не может быть гарантировано, необходимо обеспечить откат.
Поскольку отложенная запись может изменить порядок обновлений базы данных, ограничения ссылочной целостности должны допускать неупорядоченные обновления. Концептуально это означает использование базы данных в качестве хранилища в стиле ISAM (доступ на основе первичного ключа с гарантией отсутствия конфликтующих обновлений). Если другие приложения совместно используют базу данных, это создает новую проблему — нет способа гарантировать, что транзакция с отложенной записью не будет конфликтовать с внешним обновлением. Это означает, что конфликты с отложенной записью должны обрабатываться эвристически или передаваться оператору-человеку для ручной корректировки.
Как показывает опыт, идеальным вариантом является сопоставление каждого обновления записи кэша с логической транзакцией базы данных, поскольку это гарантирует простейшие транзакции базы данных.
Поскольку отложенная запись фактически превращает кеш в систему записи (до тех пор, пока очередь отложенной записи не будет записана на диск), бизнес-правила должны разрешать надежное кластерное (а не дисковое) хранение данных и транзакций. .
Кэширование с предварительным обновлением
В сценарии Refresh-Ahead Coherence позволяет разработчику настроить кэш для автоматической и асинхронной перезагрузки (обновления) любой недавно использованной записи кэша из загрузчика кэша до истечения срока его действия. В результате после того, как часто используемая запись попала в кеш, приложение не почувствует влияние чтения на потенциально медленное хранилище кеша, когда запись перезагружается из-за истечения срока действия.Асинхронное обновление запускается только при доступе к объекту, срок действия которого достаточно близок к сроку действия. Если доступ к объекту осуществляется после истечения срока его действия, Coherence выполнит синхронное чтение из хранилища кеша, чтобы обновить его значение.
Время предварительного обновления выражается в процентах от времени истечения срока действия записи. Например, предположим, что время истечения срока действия записей в кэше установлено на 60 секунд, а коэффициент упреждающего обновления установлен на 0,5. Если доступ к кэшированному объекту осуществляется через 60 секунд, Coherence выполнит синхронное чтение из хранилища кэша, чтобы обновить его значение. Однако, если запрос выполняется для записи старше 30, но менее 60 секунд, возвращается текущее значение в кеше, и Coherence планирует асинхронную перезагрузку из хранилища кеша.
Упреждающее обновление особенно полезно, если к объектам обращается большое количество пользователей. Значения остаются свежими в кэше, и задержка, которая может возникнуть из-за чрезмерной перезагрузки из хранилища кэша, исключается.
Значение коэффициента упреждающего обновления задается подэлементом элемента read-write-backing-map-scheme > в файле coherence-cache-config.xml. Упреждающее обновление предполагает, что вы также установили время истечения срока действия ( ) для записей в кэше.
Фрагмент кода XML в примере 13-1 настраивает коэффициент опережающего обновления 0,5 и время истечения 20 секунд для записей в локальном кэше. Это означает, что при доступе к записи в течение 10 секунд до истечения срока ее действия будет запланирована асинхронная перезагрузка из хранилища кеша.
Пример 13-1 Конфигурация кэша с указанием коэффициента опережающего обновления
Выбор стратегии кэширования
В этом разделе сравниваются и противопоставляются преимущества нескольких стратегий кэширования.
При кэшировании данных из базы данных существуют шаблоны кэширования для Redis и Memcached, которые вы можете реализовать, включая проактивный и реактивный подходы. Шаблоны, которые вы выбираете для реализации, должны быть напрямую связаны с вашими целями кэширования и приложения.
Двумя распространенными подходами являются кэширование или отложенная загрузка (реактивный подход) и сквозная запись (упреждающий подход). Кэш вне кэша обновляется после запроса данных. Кэш со сквозной записью обновляется сразу же после обновления первичной базы данных. При обоих подходах приложение, по сути, управляет тем, какие данные кэшируются и как долго.
Следующая диаграмма представляет собой типичное представление архитектуры, использующей удаленный распределенный кэш.
Архитектура с использованием удаленного распределенного кэша
Отложенный кэш (отложенная загрузка)
Кэширование вне кеша – это наиболее распространенная стратегия кэширования. Фундаментальную логику извлечения данных можно резюмировать следующим образом:
Когда вашему приложению необходимо прочитать данные из базы данных, оно сначала проверяет кэш, чтобы определить, доступны ли данные.
Если данные доступны (попадание в кеш), возвращаются кэшированные данные, и вызывающей стороне отправляется ответ.
Если данные недоступны (промах кэша), данные запрашиваются в базе данных. Затем кэш заполняется данными, извлеченными из базы данных, и эти данные возвращаются вызывающей стороне.
Кэш вне кеша
У этого подхода есть несколько преимуществ:
Кэш содержит только те данные, которые на самом деле запрашивает приложение, что позволяет экономить на размере кэша.
Реализация этого подхода проста и дает немедленный прирост производительности, независимо от того, используете ли вы платформу приложения, которая инкапсулирует отложенное кэширование, или собственную пользовательскую логику приложения.
Недостаток использования cache-aside в качестве единственного шаблона кэширования заключается в том, что, поскольку данные загружаются в кэш только после промаха в кэше, к начальному времени отклика добавляются некоторые накладные расходы, поскольку требуются дополнительные обращения к кэшу и базе данных. .
Сквозная запись
Кэш со сквозной записью меняет порядок заполнения кеша. Вместо ленивой загрузки данных в кеш после промаха кеш, кеш обновляется упреждающе сразу после обновления основной базы данных. Фундаментальную логику извлечения данных можно резюмировать следующим образом:
Приложение, пакет или серверный процесс обновляют первичную базу данных.
Сразу после этого данные также обновляются в кеше.
Кэш со сквозной записью
Шаблон сквозной записи почти всегда реализуется вместе с отложенной загрузкой. Если приложение получает промах в кеше из-за отсутствия данных или их срока действия, для обновления кеша выполняется шаблон отложенной загрузки.
Подход со сквозной записью имеет несколько преимуществ:
Поскольку кеш обновляется до уровня первичной базы данных, вероятность того, что данные будут найдены в кеше, гораздо выше. Это, в свою очередь, повышает общую производительность приложения и удобство работы пользователей.
Производительность вашей базы данных оптимальна, поскольку выполняется меньше операций чтения базы данных.
Недостаток сквозной записи заключается в том, что редко запрашиваемые данные также записываются в кеш, что приводит к увеличению объема и увеличению стоимости кеша.
Правильная стратегия кэширования включает в себя эффективное использование как сквозной записи, так и отложенной загрузки ваших данных, а также установку соответствующего срока действия для данных, чтобы они оставались актуальными и компактными.
Кэширование — один из самых простых способов повысить производительность системы. Базы данных могут быть медленными (да, даже базы данных NoSQL), и, как вы уже знаете, главное — скорость.
Если все сделано правильно, кэширование может сократить время отклика, снизить нагрузку на базу данных и сократить расходы. Существует несколько стратегий, и выбор правильной может иметь большое значение. Ваша стратегия кэширования зависит от данных и шаблонов доступа к данным. Другими словами, как данные записываются и читаются. Например:
- является ли система интенсивной записи и менее частой чтения? (например, журналы по времени)
- данные записываются один раз и считываются несколько раз? (например, профиль пользователя)
- всегда ли возвращаемые данные уникальны? (например, поисковые запросы)
Стратегия кэширования для системы рейтинга Top-10 для мобильных игр будет сильно отличаться от службы, которая собирает и возвращает профили пользователей. Выбор правильной стратегии кэширования является ключом к повышению производительности. Давайте кратко рассмотрим различные стратегии кэширования.
Кэшировать
Это, пожалуй, наиболее часто используемый подход к кэшированию, по крайней мере, в проектах, над которыми я работал. Кэш находится сбоку, и приложение напрямую взаимодействует как с кешем, так и с базой данных.
Вот что происходит:
- Приложение сначала проверяет кеш.
- Если данные найдены в кеше, мы попадаем в кеш. Данные считываются и возвращаются клиенту.
- Если данные не найдены в кеше, это означает промах кеша. Приложение должно выполнять дополнительную работу. Он запрашивает базу данных для чтения данных, возвращает их клиенту и сохраняет данные в кэше, поэтому последующие операции чтения для тех же данных приводят к попаданию в кэш.
Случаи использования, плюсы и минусы
Кеши в стороне от кэша обычно имеют общее назначение и лучше всего подходят для рабочих нагрузок с большим количеством операций чтения. Широко используются Memcached и Redis. Системы, использующие кэширование, устойчивы к сбоям кэширования. Если кластер кеша выходит из строя, система по-прежнему может работать, обращаясь непосредственно к базе данных. (Хотя это не сильно поможет, если кеш выйдет из строя во время пиковой нагрузки. Время отклика может стать ужасным, а в худшем случае база данных может перестать работать.)
Еще одно преимущество заключается в том, что модель данных в кэше может отличаться от модели данных в базе данных. Например. ответ, сгенерированный в результате нескольких запросов, может быть сохранен для некоторого идентификатора запроса.
При использовании кэширования наиболее распространенной стратегией записи является прямая запись данных в базу данных. Когда это происходит, кэш может стать несовместимым с базой данных. Чтобы справиться с этим, разработчики обычно используют время жизни (TTL) и продолжают обслуживать устаревшие данные, пока не истечет TTL. Если необходимо гарантировать актуальность данных, разработчики либо аннулируют запись в кэше, либо используют соответствующую стратегию записи, как мы рассмотрим позже.
Кэш сквозного чтения
Кэш для чтения встроен в базу данных. При промахе кэша он загружает недостающие данные из базы данных, заполняет кэш и возвращает его приложению.
Как кэширование, так и сквозное чтение загружают данные лениво, то есть только при первом чтении.
Случаи использования, плюсы и минусы
Несмотря на то, что сквозное чтение и удаление из кэша очень похожи, между ними есть по крайней мере два ключевых отличия:
- При использовании кэша приложение отвечает за выборку данных из базы данных и заполнение кэша. При сквозном чтении эта логика обычно поддерживается библиотекой или автономным поставщиком кэша.
- В отличие от кэша, модель данных в кэше сквозного чтения не может отличаться от модели базы данных.
Кэши со сквозным чтением лучше всего подходят для рабочих нагрузок с большим количеством операций чтения, когда одни и те же данные запрашиваются много раз. Например, новость. Недостатком является то, что когда данные запрашиваются в первый раз, это всегда приводит к промаху в кэше и влечет за собой дополнительные штрафы за загрузку данных в кэш. Разработчики справляются с этим, «подогревая» или «предварительно нагревая» кеш, выдавая запросы вручную. Как и в случае с кешем, данные между кешем и базой данных также могут стать несогласованными, и решение заключается в стратегии записи, как мы увидим далее.
Кэш со сквозной записью
В этой стратегии записи данные сначала записываются в кэш, а затем в базу данных. Кэш находится на одной линии с базой данных, и записи всегда проходят через кеш в основную базу данных.
Случаи использования, плюсы и минусы
Кажется, что кэши со сквозной записью сами по себе мало что дают. На самом деле они вызывают дополнительную задержку записи, поскольку данные сначала записываются в кэш, а затем в основную базу данных. Но в сочетании с кэшированием со сквозным чтением мы получаем все преимущества сквозного чтения, а также гарантируем согласованность данных, освобождая нас от использования методов аннулирования кэша.
DynamoDB Accelerator (DAX) — хороший пример кэширования со сквозной записью и чтением. Он встроен в DynamoDB и ваше приложение. Чтение и запись в DynamoDB можно выполнять через DAX. (Примечание: если вы планируете использовать DAX, обязательно ознакомьтесь с его моделью согласованности данных и тем, как он взаимодействует с DynamoDB.)
Запись вокруг
Здесь данные записываются непосредственно в базу данных, и только прочитанные данные попадают в кеш.
Случаи использования, плюсы и минусы
Круговая запись может сочетаться со сквозным чтением и обеспечивает хорошую производительность в ситуациях, когда данные записываются один раз, а считываются реже или вообще никогда. Например, журналы в реальном времени или сообщения чата. Точно так же этот шаблон можно комбинировать с кэшированием.
Ответная запись
Здесь приложение записывает данные в кеш, который немедленно подтверждается, и после некоторой задержки записывает данные обратно в базу данных.
Это также иногда называют отложенной записью.
Случаи использования, плюсы и минусы
Кэши с обратной записью повышают производительность записи и подходят для рабочих нагрузок с большим количеством операций записи. В сочетании со сквозным чтением это хорошо работает для смешанных рабочих нагрузок, когда самые последние обновленные и использованные данные всегда доступны в кэше.
Он устойчив к сбоям базы данных и может допускать некоторые простои базы данных. Если поддерживается пакетная обработка или объединение, это может уменьшить общее количество операций записи в базу данных, что снижает нагрузку и снижает затраты, если поставщик базы данных взимает плату за количество запросов, например. ДинамоДБ. Имейте в виду, что DAX является сквозной записью, поэтому вы не увидите снижения затрат, если ваше приложение интенсивно записывает. (Когда я впервые услышал о DAX, это был мой первый вопрос — DynamoDB может быть очень дорогой, но будь ты проклят, Amazon.)
Некоторые разработчики используют Redis как для резервного кэширования, так и для обратной записи, чтобы лучше поглощать всплески во время пиковой нагрузки. Главный недостаток заключается в том, что в случае сбоя кеша данные могут быть безвозвратно утеряны.
Большинство механизмов хранения реляционных баз данных (например, InnoDB) имеют встроенный кэш с обратной записью по умолчанию. Запросы сначала записываются в память, а затем сбрасываются на диск.
Обзор
В этом посте мы рассмотрели различные стратегии кэширования, их плюсы и минусы. На практике тщательно оцените свои цели, поймите шаблоны доступа к данным (чтение/запись) и выберите лучшую стратегию или комбинацию.
Что произойдет, если вы сделаете неправильный выбор? Тот, который не соответствует вашим целям или схемам доступа? Вы можете добавить дополнительную задержку или, по крайней мере, не увидеть полных преимуществ. Например, если вы выберете сквозную запись/чтение, когда на самом деле вам следует использовать сквозную запись/сквозное чтение (доступ к записываемым данным осуществляется реже), вы будет иметь бесполезный хлам в вашем кеше. Возможно, если кеш достаточно большой, все может быть в порядке. Но во многих реальных системах с высокой пропускной способностью, когда память никогда не бывает достаточно большой, а затраты на сервер вызывают беспокойство, правильная стратегия имеет значение.
Надеюсь, вам понравился этот пост. Дайте мне знать в разделе комментариев ниже, какие стратегии кэширования вы использовали в своих проектах. До следующего раза.
Кэширование – это способ ускорить поиск данных (чтение данных). Вместо чтения данных непосредственно из источника, которым может быть база данных или другая удаленная система, данные считываются непосредственно из кэша на компьютере, которому нужны данные. Кэширование сокращает время загрузки страниц и может снизить нагрузку на ваши серверы и базы данных.
Базы данных часто выигрывают от равномерного распределения операций чтения и записи по разделам. Многократное получение наиболее популярных элементов может привести к перекосу в этом равномерном распределении, что приведет к возникновению узких мест. Добавление уровня кэша перед базой данных может помочь избежать неравномерной нагрузки и скачков трафика приложений.
Учитывая это, вам необходимо определить, какая стратегия обновления кеша лучше всего подходит для вашего случая использования. Ниже приведены четыре различных способа обновления кеша.
Отложить кэш
Приложение отвечает за чтение и запись из хранилища. Кэш не взаимодействует с хранилищем напрямую. Приложение делает следующее:
- Поиск записи в кеше, что приводит к промаху кеша
- Загрузить запись из базы данных
- Добавить запись в кеш
- Вернуть запись
Последующие чтения данных, добавленных в кеш, выполняются быстро. Кэширование также называют ленивой загрузкой. Кешируются только запрошенные данные, что позволяет избежать заполнения кеша незапрошенными данными.
Недостатки:
- Каждый промах кэша приводит к трем обращениям, что может привести к заметной задержке.
- Данные могут устареть, если они будут обновлены в базе данных. Эту проблему можно решить, установив время жизни (TTL), которое принудительно обновляет запись в кэше, или используя сквозную запись.
- Когда узел выходит из строя, он заменяется новым пустым узлом, что увеличивает задержку.
Записать
Приложение использует кеш в качестве основного хранилища данных, читая и записывая в него данные, а кеш отвечает за чтение и запись в базу данных:
- Приложение добавляет/обновляет запись в кеше
- Кэш синхронно записывает запись в хранилище данных
- Вернуть
Сквозная запись — это медленная в целом операция из-за операции записи, но последующие чтения только что записанных данных выполняются быстро. Пользователи обычно более терпимы к задержкам при обновлении данных, чем при чтении данных. Данные в кеше не устарели.
Недостатки:
- Когда новый узел создается из-за сбоя или масштабирования, новый узел не будет кэшировать записи, пока запись не будет обновлена в базе данных. Кэширование в сочетании со сквозной записью может решить эту проблему.
- Большинство записанных данных могут никогда не быть прочитаны, что можно минимизировать с помощью TTL.
Запись
В режиме отложенной записи приложение выполняет следующие действия:
- Добавить/обновить запись в кеше
- Асинхронно записывайте запись в хранилище данных, повышая производительность записи.
Недостатки:
- Возможна потеря данных, если кеш выйдет из строя до того, как его содержимое попадет в хранилище данных.
- Реализовать отложенную запись сложнее, чем кэширование или сквозную запись.
Обновить
Кэш можно настроить таким образом, чтобы он автоматически обновлял любую недавно использованную запись в кэше до истечения срока его действия.
Упреждающее обновление может привести к меньшей задержке по сравнению со сквозным чтением, если кеш может точно предсказать, какие элементы могут понадобиться в будущем.
Читайте также: