Сегодня мы погружаемся в мир кэширования. Кэширование — это секретное оружие для создания масштабируемых высокопроизводительных систем. Существует много типов кэширования, но в этой статье мы сосредоточимся на кэшировании внутренних объектов (бэкэнд-кешировании). Его освоение поможет вам создавать высокопроизводительное и надежное программное обеспечение.
В этой статье мы рассмотрим:
Что такое кэширование? Мы рассмотрим кэширование и объясним, как оно временно хранит данные для более быстрого доступа.
Преимущества кэширования . Узнайте, как кэширование повышает скорость, снижает нагрузку на сервер, улучшает взаимодействие с пользователем и даже может сократить расходы.
Шаблон кэширования . В этом разделе мы рассмотрим различные способы использования кэша. Помните, что у каждого подхода есть свои плюсы и минусы, поэтому обязательно выберите шаблон, соответствующий вашим потребностям!
Рекомендации по кэшированию . Теперь вы знаете, как хранить и извлекать кэшированные данные. Но как обеспечить актуальность кэшированных данных? А что произойдет, когда кэш достигнет своей емкости?
Когда не кэшировать : Хотя кэширование дает множество преимуществ, бывают случаи, когда его лучше избегать. Реализация кэширования в неправильной системе может увеличить сложность и потенциально даже снизить производительность.
Создание высокопроизводительного и масштабируемого приложения — это устранение узких мест и повышение эффективности системы. Базы данных часто ограничивают производительность системы из-за требований к хранению и обработке. Это делает их дорогостоящим компонентом, поскольку их необходимо часто масштабировать.
К счастью, есть компонент, который может помочь разгрузить использование ресурсов базы данных и одновременно повысить скорость извлечения данных — этот компонент называется кэшем .
Кэш — это временное хранилище, предназначенное для быстрой записи и чтения данных. Он использует память с низкой задержкой и оптимизированные структуры данных для быстрых операций. Скорее всего, вы уже использовали Redis или Memcached или хотя бы слышали их названия. Это две самые популярные системы распределенного кэширования для серверных служб. Redis может даже выступать в качестве основной базы данных, но это тема для другой статьи!
Основным преимуществом кэширования является его скорость. Чтение данных из кэша происходит значительно быстрее, чем их извлечение из базы данных (например, SQL или Mongo). Эта скорость достигается за счет кэшей, использующих структуры данных словаря (или HashMap) для быстрых операций и хранения данных в высокоскоростной памяти, а не на диске.
Во-вторых, кеширование снижает нагрузку на вашу базу данных. Это позволяет приложениям получать необходимые им данные из кэша вместо постоянного обращения к базе данных. Это значительно снижает использование аппаратных ресурсов; вместо поиска данных на диске ваша система просто обращается к ним из быстрой памяти.
Эти преимущества напрямую улучшают взаимодействие с пользователем и могут привести к экономии затрат. Ваше приложение реагирует намного быстрее, создавая более плавную и приятную работу для пользователей.
Кэширование снижает затраты на инфраструктуру. Хотя распределенная система, такая как Redis, требует собственных ресурсов, общая экономия часто бывает значительной. Ваше приложение получает доступ к данным более эффективно, что потенциально позволяет вам уменьшить размер базы данных. Однако здесь есть компромисс: если ваша система кэширования выйдет из строя, убедитесь, что ваша база данных готова справиться с возросшей нагрузкой.
Теперь, когда вы понимаете возможности кэширования, давайте углубимся в лучшие способы его использования! В этом разделе мы рассмотрим две основные категории шаблонов: шаблоны записи в кэш и шаблоны промахов в кэше . Эти шаблоны предоставляют стратегии для управления обновлениями кэша и обработки ситуаций, когда нужные вам данные еще не находятся в кэше.
Написание шаблонов определяет, как ваше приложение взаимодействует как с кешем, так и с вашей базой данных. Давайте рассмотрим три распространенные стратегии: обратная запись , сквозная запись и обходная запись . Каждый из них предлагает уникальные преимущества и компромиссы:
Как это работает:
Идеально подходит для: приложений с большим объемом записи, где скорость имеет решающее значение, а некоторая несогласованность допустима ради производительности. Примеры включают метрики и аналитические приложения.
Преимущества:
Недостатки:
Как это работает:
Преимущества:
Недостатки:
Благодаря Write-Around ваше приложение записывает данные непосредственно в базу данных, минуя кеш во время процесса записи. Для заполнения кэша он использует стратегию, называемую шаблоном кэширования :
Приходит запрос на чтение: Приложение проверяет кэш.
Промах в кэше: если данные не найдены в кэше, приложение извлекает их из базы данных, а затем сохраняет в кэше для дальнейшего использования.
Преимущества:
Недостатки:
Промах в кэше происходит, когда данные, необходимые вашему приложению, не найдены в кэше. Вот две распространенные стратегии решения этой проблемы:
Приложение проверяет кэш.
В случае промаха он извлекает данные из базы данных, а затем обновляет кеш.
Ключевой момент: приложение отвечает за управление кешем.
Использование шаблона Cache-Aside означает, что ваше приложение будет управлять кешем. Этот подход является наиболее распространенным в использовании, поскольку он прост и не требует разработки в других местах, кроме приложения.
Приложение делает запрос, не зная о кеше.
Специализированный механизм проверяет кэш и при необходимости извлекает данные из базы данных.
Кэш обновляется прозрачно.
Шаблоны сквозного чтения уменьшают сложность приложения, но увеличивают сложность инфраструктуры. Вместо этого это помогает разгрузить ресурс приложения промежуточному программному обеспечению.
В целом, шаблон обходной записи с выделением кэша наиболее часто используется из-за его простоты реализации. Однако я рекомендую также включить шаблон сквозной записи, если у вас есть данные, которые будут использоваться сразу после их кэширования. Это обеспечит небольшое улучшение производительности чтения.
В этом разделе мы рассмотрим лучшие практики использования кэша. Следование этим правилам обеспечит сохранение свежих данных в вашем кэше и эффективное управление их хранилищем.
Представьте, что вы сохранили данные в кеше, а затем база данных обновляется. Это приводит к тому, что данные в кэше отличаются от версии базы данных. Мы называем этот тип данных кэша «устаревшими». Без техники аннулирования кэша ваши кэшированные данные могут остаться устаревшими после обновлений базы данных. Чтобы поддерживать актуальность данных, вы можете использовать следующие методы:
Инвалидация кэша при обновлении. При обновлении данных в базе данных также обновите соответствующую запись кэша. Шаблоны сквозной и обратной записи по своей сути справляются с этой задачей, но обходная запись/отложение кэша требует явного удаления кэшированных данных. Эта стратегия не позволяет вашему приложению получать устаревшие данные.
Время жизни (TTL): TTL — это политика, которую вы можете установить при хранении данных в кеше. При использовании TTL данные автоматически удаляются через определенное время. Это помогает очистить неиспользуемые данные и обеспечивает защиту от устаревших данных в случае пропущенной недействительности.
Если вы кэшируете большой объем данных, ваше хранилище кэша может переполниться. Системы кэширования обычно используют память, которая часто меньше, чем хранилище основной базы данных. Когда кеш заполнен, необходимо удалить некоторые данные, чтобы освободить место. Политики замены кэша определяют, какие данные следует удалить:
Наименее недавно использованные (LRU): эта общая политика удаляет данные, которые не использовались (чтение или запись) в течение длительного времени. LRU подходит для большинства реальных случаев использования.
Наименее часто используемый (LFU): аналогичен LRU, но ориентирован на частоту доступа. Вновь записанные данные могут быть удалены, поэтому рассмотрите возможность добавления периода прогрева, в течение которого данные не могут быть удалены.
Существуют и другие политики замены, такие как FIFO (первым пришел, первым обслужен), случайная замена и т. д., но они менее распространены.
Прежде чем приступить к реализации кэша, важно знать, в каких случаях он может оказаться неподходящим . Кэширование часто повышает скорость и снижает нагрузку на базу данных, но оно может оказаться бессмысленным, если:
Низкий трафик. Если у вашего приложения низкий трафик и время ответа по-прежнему приемлемое, вам, скорее всего, пока не нужно кэширование. Добавление кэша увеличивает сложность, поэтому его лучше всего применять, когда вы сталкиваетесь с узкими местами в производительности или ожидаете значительного увеличения трафика.
Ваша система перегружена записью: кэширование наиболее полезно в приложениях с большим количеством операций чтения. Это означает, что данные в вашей базе данных обновляются нечасто или считываются несколько раз между обновлениями. Если ваше приложение имеет большой объем операций записи, кэширование потенциально может увеличить накладные расходы и замедлить работу.
В этой статье мы рассмотрели основы кэширования и способы его эффективного использования. Вот краткий обзор ключевых моментов:
Подтвердите необходимость: убедитесь, что ваша система перегружена чтением и требует предложения кэширования по сокращению задержек.
Выбирайте шаблоны с умом: выбирайте шаблоны записи в кэш и промахов кэша, которые соответствуют тому, как ваше приложение использует данные.
Свежесть данных: реализуйте стратегии аннулирования кэша, чтобы предотвратить предоставление устаревших данных.
Управление политикой замены: выберите политику замены кэша (например, LRU), чтобы обрабатывать удаления, когда кэш достигает своей емкости.