Комментарии 32
Есть золотое правило: если у вас используется алгоритм вытеснения из тройки random/lifo/fifo — значит, вам кэш не нужен в принципе.
И еще одно: кэш — в подавляющем большинстве проектов — это preliminary optimization, приносит больше зла, чем пользы.
Правильный подход к кэшированию: если планируется вырастить проект до ста миллионов миллиардов гуглов — обособьте вызовы в сторонние сервисы (база, и т. п.) посредством самописной реализации VoidCache
, который просто всегда ходит в чужой сервис. Потом (а скорее всего — никогда) — замените на настоящий взрослый кэш. Когда он потребуется, вы уже будете знать, какой алгоритм вам подходит больше всего.
Идея с VoidCache
подозрительная. Если у вас нет кеша в реальности, то у вас нет и проблемы устаревания кеша, вам не требуется инвалидация, вы не получите на проде неактуальных данных. Т.е. в момент когда вы решите подключить кеш, внезапно пойдут проблемы. Может хотя бы кеш в оперативке сделать, с управляемым временем жизни и то будет польза?
когда вы решите подключить кеш, внезапно пойдут проблемы
VoidCache
решает проблему decoupling’а, а не несуществующие пока проблемы устаревания. Когда вы решите подключить кэш, вам не придется делать рефакторинг на газиллион строк, достаточно будет заменить одну, а потом воевать с неправильным устареванием, с которым по любому придется воевать.
Тогда это не VoidCache некий, а любой другой класс который отвечает за соединение с внешним сервисом\СУБД - репозиторий, сервис, менеджер, на любой вкус.
И их реализация в любом случае хорошая практика, вне зависимости от теоретического использования кешей.
Класс? Серьезно? А если у меня Хаскель — жить мне без кэша?
И нет, это не модуль, который отвечает за соединение, это модуль, который отвечает строго за чтение (и предоставляет интерфейс invalidate
). Поверх модуля, который отвечает за соединение.
Я написал ровно то, что имел в виду.
и предоставляет интерфейс
invalidate
Окей, операцию R мы выносим в отдельный модуль, модуль ещё и умеет в инвалидацию видимо. Можно где-то почитать как этим пользоваться? Я пока не видел таких примеров кода, мне непонятны плюсы и как пользоваться.
Добавлю, что у разработчиков бывает представление о кэше как о штуке, которая решит проблемы с производительностью плохо спроектированного приложения. Представление меняется заменой слова на "базу данных", чем по сути кэш и является.
Не, кэш не является БД ни в каком смысле, потому что из БД не исчезают внезапно записи.
А так-то да, в подавляющем большинстве случаев (preliminary optimization), когда люди втыкают кэш на всякий случай, чтобы было, его использование как раз не только не ускоряет, но замедляет работу плохо спроектированного приложения. Потому что была одна проблема, а теперь их две.
Вообще, кэш нужно использовать с большой осторожностью и всегда после того, как метрики показали провалы в разговорах с другими контрагентами, и ни в коем случае не до того. Плохо спроектированный кэш (а схерали люди, которые плохо спроектировали приложение — вдруг хорошо спроектируют кэш, который идеологически сложнее почти чего угодно) — гораздо хуже отсутствия кэша как такового.
Особенно в современных реалиях, где время расходуется не на точечные, пусть даже и сетевые, вызовы. Смешно видеть, как люди выгружают тонну джаваскрипта клиенту на каждый чих, а рядом прикручивают кэш к постгресу. Так и хочется подойти с шепнуть: «Чувак, постгрес писали люди, которые выборку из миллиарда строк оптимизировали лучше, чем ты свою проверку на cache miss».
согласен кэш не является спасением от плохой архитектуры, а лишь инструментом оптимизации, в дополнение к уже хорошо спроектированной системе. + упомянул что не всегда его использование дает профит
Кэши имеют разные реализации и используются далеко не только в вебе. Банальный пример геймдев, где кэш либо хранится в хэш таблицах либо интегрирован прямо в код функции например. У кэша нет такой сложной архитектуры, как у БД, даже у noSQL.
Да и подходы разные. Например, кэш подразумевает полное удаление себя, без каких либо последствий для сервиса или проекта. Полное удаление всех данных в бд думаю понятно, какие последствия будет иметь.
А заморозка применяется в таких кэшах, как в процессорах?
О какой "заморозке" в процессорных кэшах идёт речь?
И да программный кэш очень сильно отличается от процессорного по внутренней архитектуре и основным сложностям.
В некоторых процессорах есть команда freeze кэш страницы. Не помню деталей, да и не использовал ни разу
Поскольку кэш работает на уровне кэшлайнов, а не страниц, то "фриз кэш страниицы" - звучит как какая-то ерунда.
Вам наверное на уровне идеи лучше объяснить какое поведение вы подразумеваете.
По моему там употреблялось page, а не line, но не уверен. И смысл был в том, чтобы считать массив констант из динамической памяти, потом заморозить этот лайн или пейдж, пройти цикл обработки с их использованием, заморозить кэш инструкций с этой функцией, а потом заниматься чем то другим, чтобы при появлении новых данных это всё повторялось уже из кэша
Честно говоря супер пространное описание.
Смутно похоже на 1 из 3 вещей:
- Tight Coupled Memory (программно управляемый кэш)
- LL SC синхронизацию
- watch points
В целом неясно в чём смысл: оставить надолго некоторые данные в кэше или же "разбудить" ожидающий процесс? Если цель "разбудеть" - то обычно так не делают скрыто в аппаратуре, а посылают уснувшему процессу явный сигнал на уровне программной модели.
В общем случае в микроэлектронике - сложность сделать доступ к памяти быстрой. А в программном кэше сложность - вовремя инвалидировать устаревшие данные (т.к. данные мимо кэша идут в виде "запросов" по которым надо угадать что может инвалидироваться).
Вот вокруг этого: сложности инвалидации (а ещё и "когерентности", если она есть) - построена основная архитектура программных кэшей.
Да, по бенефитам похоже на TCM ARMа но вряд ли. Видел лет 30 или больше назад в сигнальных процессорах TI, а может и ещё где, когда переставали делать статическую память, а динамическая существенно тормозила. Внутренняя память процессора могла работать как статическая, а могла как кэш. И вот в режиме кэша можно было принудительно загнать туда константы и куски кода, которые должны были выполняться постоянно и гарантированно быстро, а свободную часть оставить для кэширования медленной внешней памяти
Понял. Ну из общих соображений:
1. Вам можно забить на согласованность (*) - просто кладёте эти данные в отдельный кэшик и забываете
2. Вам нельзя забивать на согласованность - данные иногда будут инвалидироваться => подолгу будут недоступны. Лучшее что вы можете сделать это повысить приоритет данных при вытеснении (такая возможность наверняка должна быть).
*) В терминах CAP-теоремы
Джонни Кэш ещё. Из категории, которая тоже много на что влияет в нашей жизни.
спасибо за фидбэк. рад если информация оказалась полезной, но это лишь начало. советую углубиться в упомянутые advanced алгоритмы (не зубрить их устройство, а просто почитать для расширения кругозора и возможно попробовать реализовать какой нибудь на практике). + в дополнение почитайте про методы инвалидации и возможные проблемы (e.g thundering herd problem)
Интересная статья. Только вливаюсь в программирование, поэтому эта информация очень к стати
А почему "внутренний кэш" мешает горизонтальному масштабированию, а внешний - "легко горизонтально масштабируется"? Это совершенно не верно, тип кэша никак не связан с простотой масштабирования. Более того, все приведенные примеры для внешних кэшей (Тарантул, Редис) не масштабируются горизонтально. А вот вполне себе внутренний Хазелкаст - как раз масштабируется.
И подобных неточностей в статье довольно много, кажется, что автор не очень хорошо понимает, как и для чего нужно кэширование и просто пересказывает википедию. Для студента или стажера - достаточно. Для миддла - уже категорически недостаточно информации и понимания. К сожалению, в статье нигде не указано, что она для студентов.
Redis Cluster вроде горизонтально масштабируется, а внутренний - это думать надо как все сделать!
джунам пойдет, а по факту - бери, что попроще и не выдумывай.
На сколько внешний медленнее внутреннего? Никто не переживает, вот и берут, то попроще.
В теории - да, в Redis Cluster есть шардинг. Но в реальном использовании там все не так просто и масштабирование нужно делать очень аккуратно, при этом еще и справляясь с кучей ограничений кластера. Внутренний на хазелкасте - масштабируется примерно так же, чуть сложнее для программиста, чуть проще для админа, разница не принципиальна.
Но, в любом случае, горизонтальное масштабирование не зависит от того, внутренний или внешний кэш.
Медианный latency внутреннего кэша примерно на два-четыре десятичных порядка меньше, чем доступ через сеть, хотя реальные значения зависят от множества параметров (как ни странно, нигде не увидел актуальных данных по latency доступа к современной серверной памяти и сетевых задержек внутри современного ДЦ).
На надо помнить, что для сети какой-нибудь 99.99 персентиль будет много выше медианы и может легко доходить до десятков ms, а время доступа к локальной памяти гораздо меньше подвержено флуктуациям.
Очень интересно. Сложный материал легким языком. Огонь! А Jitter это из этой серии?
Кэш. Теория кэширования. Устройство и разновидности кэша