Основы кэширования

Базовый System Design
≈ 2 мин чтения

Cache hit и cache miss

Кэш хранит копию данных, которые можно получить из другого источника. Когда нужный ключ уже есть в кэше, происходит cache hit — быстрый слой сразу возвращает значение. Если ключа нет, это cache miss: системе приходится идти к исходному источнику.

request
   |
   v
 cache ---- hit ----> response
   |
  miss
   v
primary source

Чем выше доля полезных попаданий, тем сильнее кэш сокращает среднюю задержку и нагрузку на основной источник. Но сам по себе большой кэш не гарантирует высокий hit rate: важнее, повторяются ли запросы к тем же данным.

Почему кэш ускоряет систему

Кэш обычно выбирают так, чтобы чтение из него было дешевле исходной операции. Например, обращение к памяти или близкому сетевому кэшу может быть быстрее запроса к базе данных, а готовый результат вычисления — дешевле повторного вычисления.

Допустим, чтение из основного источника занимает 40 мс, а из кэша — 2 мс. При большом числе повторяющихся чтений экономия появляется не только во времени ответа: основное хранилище выполняет меньше операций и получает запас по нагрузке.

Ключ определяет, что именно мы переиспользуем

Закэшированное значение обычно ищется по ключу. Ключ должен однозначно описывать данные, иначе разные запросы могут случайно получить одно и то же значение.

product:42
user:17
catalog:category:books:page:3

Если результат зависит от языка, пользователя, страницы или другого параметра, этот параметр обычно должен быть отражён и в ключе.

Кэш подходит не для всех данных

Наибольшую пользу дают данные, которые читают часто, а изменяют заметно реже. Если значение почти никогда не запрашивается повторно, кэш только расходует память. Если оно меняется постоянно, цена поддержания актуальности может оказаться выше выигрыша от быстрых чтений.

Сначала измеряй повторное использование. Кэшировать «на всякий случай» не стоит: хороший кандидат должен давать заметный выигрыш по latency, нагрузке или стоимости вычисления.