Contents

Секреты кэширования с примерами

Видео доступно на канале

Когда кэшировать

  • Производительность: Долгие операции и данные не меняются какое-то время, быстро не теряют свою актуальность
  • Надежность: Повысить надежность системы в случае отказов, в зависимости от типа может иногда прикрыть хранилище целиком
  • Масштабируемость: Повысить масштабируемость системы, меньше запросов - больше возможностей, снижается нагрузка и тд

Виды кэшей

  • Локальные, на каждом узле свой
    • Плюсы
      • Легко поддерживать
      • очень быстрый
    • Минусы
      • Дубли данных на всех узлах
      • При перезапусках пропадает
      • Все данные в памяти узла, утечка памяти ведет к проблемам
  • Распределенные, общий сетевой
    • Плюсы
      • Устойчив к перезапуску узлов
      • Данные хранятся в одном месте
      • Отделение хранения данных в отдельную систему
    • Минусы
      • Сложнее поддерживать
      • Синхронизация глобального доступа

Инвалидация кэша

  • Стратегии
    • Событийно, что-то случилось и пора делать
    • По времени (время жизни ключа например 10 минут)
    • Принудительно, пытаемся обновить кэш самостоятельно
  • Когда стоит делать
    • В целом понятно, что-то произошло - мы реагируем
    • Ключ ставится с таймаутом и сам удаляется через 10 минут
    • Отделение кэширующего источника данных, часто используется для нагрузки

Варианты хранения с учётом скорости

  • Хранение ответов из базы
  • Хранение ответов обработчика целиком
  • Хранение сжатых данных
  • Бинарные данные

Расчет объема кэша

  • По количеству объектов
  • Сжатие
  • Сколько минимум памяти нужно

Когда кэш не нужен

  • Каждый раз новые данные
  • Количество данных на столько мало, что можно всегда брать из базы
  • Данные статические, лучше просто заменить на константы или enum

Стратегии вытеснения данных из кэша

  • наименее недавно использованные данные lru
  • наименее редко использованные данные lfu
  • очередь добавления данных fifo
  • стек кэширования, новые данные сразу будут не нужны, lifo, не видел на практике
  • произвольная замена

Метрики кэша

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

Бонус, причины почему у вас могут быть промахи

  • холодный старт, кэшей может не быть, как победить - в современном мире до readiness пробы загрузить данные
  • переполнение, тут банально - увеличить размер, попробовать другую стратегию
  • Протухание единовременное
    • Кэшу ставится время жизни, кэш протух, данных нет
    • Хорошо всегда держать кэш и самим пытаться его протухнуть, чтобы если вдруг не получится - данные есть всегда
  • Неправильные таймауты. Это целая проблема есть несколько таймаутов к кэшу и все они должны быть настроены валидно, падение кэша или сильная деградация не должны вызывать падение.
    • Таймаут подключения
    • Таймаут выполнения чтения
    • Таймаут записи
    • Реальная история, что от таймаута в 10сек забилась сеть и запросы вставали в очередь, приложение легло целиком.

Важные наблюдения

  • кэши не влияют на перцентили большие чем попадания, при промахах все равно идем в базу
  • как считать эффективность, допустим у нас попадание 80%. Возьмем например к=0.1, это коэффициент показывающий сколько занимает дополнительный поход в кэш, проверка наличия данных и ответ.
    • для 80% пользователей мы будем отвечать за 10% времени
    • для 20% мы будем отвечать за 110%
    • в реальности этот к стараются снизить до 0.05
    • в идеале мы должны стремиться к попаданиям на 99%, но нижняя граница около 80%
    • нашел более научную модель https://courses.cs.washington.edu/courses/cse378/05sp/lectures/cacper.pdf
    • 10мс и 100мс, в нашем случае среднее станет = 8+20=28мс