Кэш (cache)

29 июля 2026 · ~12 мин чтения

концепция производительность инфраструктура история

Кэш (cache)

Быстрое временное хранилище копий данных, к которым часто обращаются, чтобы не ходить каждый раз в медленный и дорогой первоисточник.

История

Идея родилась в 1965 году у британского инженера Мориса Уилкса (того самого, что построил один из первых компьютеров EDSAC в Кембридже в 1949-м). В статье «Slave memories and dynamic storage allocation» он предложил маленькую быструю память-«раба» между процессором и основной памятью: раб хранит то, что процессор трогал недавно, и отдаёт это в разы быстрее, чем основной сундук. Слово «cache» (от французского cacher — прятать) как термин ввёл редактор журнала IBM Systems Journal Лайл Джонсон, когда статью Уилкса перепечатывали — «slave memory» звучало политически неудобно.

Первой коммерческой машиной с кэшем стал IBM System/360 Model 85 (1968) — шкаф размером с два холодильника. Идея сработала: L1-кэш добавил 30% скорости при 10% росте цены. С этого момента кэш стал стандартом.

Дальше вехи:

Что это такое

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

Ключевая метрика — hit rate (доля попаданий). CDN Cloudflare публично хвалится 85–95% hit rate на статику; кэш веб-приложений — 70–90%; кэш процессора L1 — 95%+. Каждый лишний процент hit rate — минус запрос в БД или на диск.

Кэш почти всегда ограничен по объёму (иначе это уже полная копия источника, а не кэш). Поэтому нужна политика вытеснения — какие данные выкидывать, когда место кончилось. Самая частая — LRU (Least Recently Used, «самое давно не используемое»): выкидывается то, к чему дольше всего не обращались. Есть ещё LFU (Least Frequently Used — по частоте), FIFO, random.

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

Кэш vs репликация БД. Реплика — это полная синхронная копия базы; кэш — частичная, ленивая, обычно допускает лёгкое отставание. Реплика гарантирует консистентность, кэш ею жертвует ради скорости.

Кэш vs индекс. Индекс — это структура данных внутри БД для быстрого поиска (например, B-tree); он не хранит копию данных, только указатель. Кэш хранит именно копию.

Аналогии из жизни

Холодильник. Магазин далеко и работает по расписанию — это медленный источник. Холодильник дома быстрый: открыл, взял молоко. Пока молоко есть и не испортилось — living the dream. Где ломается: молоко просрочилось, а ты этого не знаешь, потому что смотрел только «есть/нет». Отравился. В кэше это называется stale data — старая, но формально доступная копия. Именно поэтому все системы кэширования упираются в вопрос: как понять, что копия устарела.

Записная книжка с телефонами. Каждый раз спрашивать Google «телефон стоматологии» — медленно и дорого (трафик, время). Записать один раз в книжку — быстро. Где ломается: стоматология переехала и сменила номер. Ты набираешь старый — попадаешь в квартиру. Это классическая проблема cache invalidation (инвалидации): как узнать, что записанное больше не актуально, если тебя никто не предупредил.

Оперативная память мозга — «где ключи?». Ты кладёшь ключи в одно и то же место каждый день, и мозг подставляет ответ автоматически, не задумываясь. Быстро. Где ломается: вчера ты положил ключи в другое место, но кэш в голове по-прежнему выдаёт старый ответ. Ты идёшь в привычное место, ключей нет, тратишь 20 минут на поиск. Тот же паттерн, что с молоком: копия есть, но она врёт.

Как это работает

Схема запроса через кэш выглядит так:

Потребитель  ─(1)─►  Кэш
                     │
                     ├─ ЕСТЬ и свежее? ─── да ──►  (2a) вернуть копию   ─►  Потребитель
                     │
                     └─ нет ──►  Источник  ─(3)─►  Кэш кладёт себе  ─(4)─►  Потребитель

Стрелка (2a) — это hit; путь (3-4) — miss. Miss всегда дороже, чем прямое обращение к источнику (лишний накладной поход в кэш), поэтому кэш имеет смысл только когда hit rate высокий.

Как определяется «свежесть». Три классических подхода:

  1. TTL (time-to-live). Каждой записи ставится срок жизни. «Этот ответ живёт 60 секунд, потом выбрасываем.» Простой, устойчивый, но грубый: если данные не менялись — зря выкинули; если поменялись — до 60 секунд отдаём враньё.
  2. Пассивная инвалидация (по запросу). Кэш держит копию, пока её не выселит политика вытеснения. Свежесть проверяется условным запросом к источнику: «а вот эта версия ещё актуальна?» Именно так работает HTTP-кэш через заголовки ETag и If-None-Match — сервер отвечает 304 Not Modified (не менялось), и потребитель использует свою копию.
  3. Активная инвалидация (push). Источник сам говорит кэшу: «выбрось запись X, я её изменил». Быстро и точно, но требует прямого канала между источником и кэшем. Так работают CDN Cloudflare с вебхуками «purge» и Redis с pub/sub-каналами.

Cache-aside vs write-through vs write-back — три разных ответа на вопрос «а что делать, когда клиент не читает, а пишет».

Многоуровневые кэши. В процессоре: L1 (~1 нс, десятки КБ), L2 (~10 нс, сотни КБ), L3 (~30 нс, десятки МБ), потом RAM (~100 нс), потом SSD (~100 000 нс), потом сеть. Каждый следующий уровень медленнее и больше. То же самое в вебе: браузерный кэш → CDN → реверс-прокси (nginx) → кэш приложения (Redis) → БД. Отсутствие в одном уровне спускает запрос на следующий.

Знаменитая цитата

«В computer science есть только две по-настоящему сложные вещи: инвалидация кэша и придумывание имён.» — Фил Карлтон, инженер Netscape, ~1996. Первое звучит смешно, но эта строчка объясняет большую часть багов в веб-приложениях за последние 25 лет. Всё, что «то работает, то нет», «у меня в браузере старая версия», «в отчёте старые цифры» — это чаще всего кэш, который никто не подчистил.

Где встречается в обычной жизни

Где встречается в IT и бизнесе

Кто пользуется

Все, у кого больше двух пользователей. Без кэша интернет в текущем виде существовать не может.

Альтернативы и конкуренты

Когда НЕ стоит использовать

Связанные понятия

Литература и источники

Где встретилось у меня

Вчера в разговоре с ассистентом всплыл кэш локальной системы досье: перед тем как звать платный API за 5 ₽, ассистент проверил, нет ли ответа по этому же запросу в локальной директории. Ответ шестидневной давности нашёлся — платить повторно не пришлось. Это классический cache-aside с человеческой политикой инвалидации («данные месяц не двигаются, свежесть 6 дней норм»). Плюс отдельная история про TTL: агент прямо в интерфейсе показал, что кэшу 6 дней, и предложил обновить за 5 ₽ — правильный паттерн «покажи возраст копии и дай пользователю решить».

Краткое резюме