Кэш и производительность
Карточка товара собирается из базы за 40 миллисекунд. Запросов - тысяча в секунду. База всё это время занята тем, что тысячу раз в секунду отвечает одно и то же. Кэш - это ответ, положенный поближе, чтобы не спрашивать источник заново.
Стержень: у любого кэша обязан быть внятный ответ на два вопроса - когда он обновляется и что видит пользователь, пока данные устарели.
// Формулировки: «что спросишь перед вводом кэша?», «что такое TTL?», «кэш пуст после перезапуска»
Сколько именно он даёт
Считаем на цифрах карточки. База отвечает за 40 миллисекунд, кэш в памяти - примерно за 1. Если попадание случается в девяти случаях из десяти, средняя задержка выходит 0,9 умножить на 1 плюс 0,1 умножить на 40 - это 4,9 миллисекунды вместо сорока, примерно в восемь раз быстрее.
Нагрузка падает так же: из тысячи запросов в секунду до базы доходит сотня. Обычно ради этого кэш и ставят - не ради миллисекунд на экране, а ради снятой с источника нагрузки.
// Доля попаданий - главный показатель кэша. Упала до 20 процентов, и средняя задержка становится 0,2 умножить на 1 плюс 0,8 умножить на 40, то есть 32 миллисекунды. Выигрыша почти нет, зато память занята и появилось ещё одно место, где данные бывают неправильными.
- доля попаданий
- процент запросов, на которые ответил кэш, не обращаясь к источнику
Главный вопрос - допустимое отставание
Вопрос бизнесовый, и ответ на него определяет всю конструкцию. Цена может отставать на час - ставим TTL (time to live), срок годности записи, и задача решается за день. Расхождение недопустимо даже на минуту, потому что человек увидит одну цену, а спишется другая - нужен сброс по событию изменения цены, отдельный надёжный канал событий и совсем другой объём работы.
TTL - прямой размен между свежестью и нагрузкой. Шестьдесят секунд означают, что до минуты пользователи видят старое значение, зато при тысяче запросов в секунду источник спросят один раз на эти шестьдесят тысяч обращений.
// Сброс по событию даёт свежесть почти мгновенно, но платит хрупкостью: одно потерянное сообщение оставит неверное значение висеть до следующего изменения, а оно может случиться через неделю. Поэтому даже при сбросе по событию срок годности оставляют как страховку.
Кэш - тоже хранилище данных
Клиент потребовал удалить персональные данные. Из базы удалили, а копия в кэше дожила до конца срока годности - сутки. Сутки обязательство не выполнено, и это проверяемое нарушение, а не мелочь.
Значит в требованиях появляются три строчки: ограниченный срок хранения, шифрование там, где данные того требуют, и явный сброс кэша при удалении клиента. Само это никто не вспомнит.
// Второй забываемый случай - холодный старт. Система живёт на кэше и отправляет в базу сотню запросов в секунду. После перезапуска кэш пуст, и в базу летит вся тысяча - вдесятеро больше, чем она рассчитана держать. Лечится прогревом до ввода в строй или пропуском части запросов, пока кэш наполняется.
Что кэшировать бесполезно
Выдачу поиска по произвольным фильтрам. Ключом служит сочетание всех параметров: при десяти фильтрах по пять значений комбинаций получается пять в десятой степени - 9 765 625, почти десять миллионов. Каждый запрос уникален, попаданий нет, память занята зря.
Работает другое: кэшировать популярные предустановленные наборы («новинки», «со скидкой») и отдельные карточки товаров, которые переиспользуются между разными выдачами. Тогда список собирается из горячих кусков, даже если сам список никто раньше не запрашивал.
// Проверяемое требование к кэшу выглядит так: «данные не старше 60 секунд с момента изменения; при устаревании показывается последнее известное значение с отметкой времени; есть ручка принудительного обновления». Формулировка «кэш должен работать быстро» не проверяется ничем.
Как отвечать: «Вводим кэш на цены. Что выяснишь у бизнеса первым делом?»
Какое отставание цены допустимо и что делаем, если клиент увидел старую. Это не техническая мелочь: если расхождение недопустимо, потому что человек оформит заказ по одной цене, а спишется другая, простым сроком годности не обойтись - нужен сброс по событию изменения цены, а это надёжный канал событий и разбор потерянных сообщений. Если же час отставания никого не смущает, задача решается за день на TTL. Дальше уточню два пункта, про которые обычно забывают: срок хранения копии и её удаление вместе с персональными данными клиента, и поведение после перезапуска - кэш пуст, и вся нагрузка уходит в базу разом.
Кандидат ставит бизнес-вопрос перед техническим решением, показывает разницу в трудоёмкости и помнит про персональные данные и холодный старт.
На чём валятся
- −− Решают вопрос о кэше технически, не спросив про допустимое отставание.
- −− Забывают про персональные данные в кэше при удалении клиента.
- −− Не готовятся к холодному старту: после перезапуска вся нагрузка падает на базу.
- −− Кэшируют выдачу поиска по произвольным фильтрам и получают долю попаданий около нуля.
- −− Полагаются только на сброс по событию, без срока годности как страховки.
- −− Пишут «кэш должен работать быстро» вместо ограничения на отставание в секундах.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Что означает инвалидация кэша по событию?A)Запись сбрасывается при изменении источникаB)Кэш обновляется по таймеру каждую минутуC)Кэш очищается при перезапуске сервисаD)Кэш отключается при высокой нагрузке
показать ответ и разбор
+A)Запись сбрасывается при изменении источника// разбор: Вместо ожидания истечения срока система сама сбрасывает запись, как только исходные данные изменились. Свежесть получается почти мгновенной, но нужен надёжный канал событий: пропущенное сообщение оставит в кэше устаревшее значение до следующего изменения, а это может быть очень нескоро.
- Сервис кэширует персональные данные клиента. О чём стоит подумать?A)О скорости выдачи данных из кэшаB)О формате сериализации записейC)О порядке ключей в хранилищеD)О сроке хранения и удалении по запросу
показать ответ и разбор
+D)О сроке хранения и удалении по запросу// разбор: Кэш — это тоже хранилище персональных данных, только про него обычно забывают. Если клиент требует удалить свои данные, а копия лежит в кэше ещё сутки, обязательство не выполнено. Нужны ограниченный срок хранения, шифрование при необходимости и явный сброс при удалении клиента.
- Кэш пуст после перезапуска, и вся нагрузка ушла в базу, которая легла. Как это называют?A)Утечкой памятиB)Гонкой обновленийC)Холодным стартом кэшаD)Переполнением очереди
показать ответ и разбор
+C)Холодным стартом кэша// разбор: Система, привыкшая жить на кэше, не рассчитана обслуживать полный поток запросов из источника. После перезапуска или массового сброса база получает всю нагрузку разом. Лечится прогревом заранее, поэтапным вводом узлов и ограничением параллельных обращений к источнику по одному ключу.
- Почему кэшировать результат поиска по произвольным фильтрам обычно бесполезно?A)Результаты поиска слишком объёмныB)Кэш не умеет хранить спискиC)Поиск выполняется медленнее кэшаD)Комбинаций фильтров слишком много
показать ответ и разбор
+D)Комбинаций фильтров слишком много// разбор: Ключом кэша служит сочетание всех параметров, а при десятке фильтров число комбинаций огромно — почти каждый запрос уникален и промахивается. Кэш занимает память, но не даёт попаданий. Работает другое: кэшировать популярные предустановленные наборы или отдельные карточки из выдачи.
- Как сформулировать требование к кэшу, чтобы его можно было проверить?A)Кэш должен работать быстро и надёжноB)Кэш должен снижать нагрузку на базуC)Данные свежее 60 секунд после измененияD)Кэш должен использовать современное хранилище
показать ответ и разбор
+C)Данные свежее 60 секунд после изменения// разбор: Проверяемое требование говорит о наблюдаемом поведении: максимальное отставание от источника, а вместе с ним — что показывать пользователю при устаревании и как принудительно обновить. Формулировки про скорость и надёжность без чисел принять невозможно, а выбор продукта вообще не требование.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.