Comments 50
Зря опустили отдельное семейство кэшей -- кэш, который находится в адресном пространстве приложения. Нет сетевых задержек, можно исключить накладные расходы на [де]сериализацию (и, как следствие, нагрузку на систему распределения памяти), масштабируемость при правильной реализации близка к теоретически максимальной, возможно применение более эффективных алгоритмов приёмки и вытеснения чем LRU/LFU.
Да, есть нюансы в виде дублирования данных кэша, необходимости как-то инвалидировать такой кэш и вообще выработать стратегию обеспечения свежести данных (но это нужно и при работе с обычным кэшем), и обеспечения прогрева кэша при старте приложения (опять-таки в нагруженных системах это всё равно делают и для внешнего кэша, просто происходит это реже, при введении в строй новых разделов кэша или при восстановлении после аварии).
Всё-таки это совсем в другой класс, и там конечно можно налопатить на порядок (или на порядки) больше RPS/thoughput.
Вопрос стоял именно в том, чтобы взять кеш-сервисы как обвязку базам, и посмотреть, как современные версии традиционных баз справляются с такой нагрузкой.
В новый дотнет завезли концепцию HybridCache. Ну, то есть понятно, что идея, в общем-то лежит на поверхности, но готовая обвязка это всегда хорошо.
Довольно странная статья. На мой взгляд, вопрос в заголовке в целом сомнителен и имеет смысл в каком-то достаточно узком круге проблем. Кеш решает гораздо больше проблем. Например, сам запрос может выполняться чуть дольше по времени, чем клиент способен ждать и вы просто не решите эту проблему никак, хоть заскейлитесь. Другая часть проблем давно и успешно решается горизонтальным масштабированием, причем, там сразу ещё решается проблема отказоустойчивости.
Например, сам запрос может выполняться чуть дольше по времени, чем клиент способен ждать и вы просто не решите эту проблему никак, хоть заскейлитесь
И как кэш решает эту "проблему"?
Всё зависит сильно от задачи. В каких-то случаях может быть позволительно считать данные или их часть в фоне и класть данные в кэш и пользовательскими запросами ходить в него, например. А может и вовсе какие-то запросы могут быть предварительно прогреты для целых групп пользователей.
Вообще-то это делается не так, если у вас какие-то запросы к БД длительностью в минуты (что абсурдно), или большие вычисления, или асинхронные иные операции. Пользователь оставляет запрос на получение результата, и когда результат готов, он или посылается ему чем-то типа вебсокета, либо кладется в БД в таблицу сообщений пользователям. Но кэшу в данной задаче места не видно.
Ну вот оставьте начало задачи с текущим выполнением запроса за минуты и добавьте туда требование бизнеса показать результат за пары секунд. И вскоре вы обмажетесь кэшами, дублированием данных в более приспособленных бд, промежуточными подсчетами, хайперлоглогами и прочим добром)
materialized view или её ручная реализация с пересчётом по job'у или событию.
или её ручная реализация с пересчётом по job'у или событию
Так именно об этом я и писал в ветке
Разработчики распределенных дб, таких как Cassandra и CockroachDB в своих книгах так и советуют делать. В мире где уже во всю пашут распределенных дб. Вопрос применения кешей достаточно странный. Так как внутренние реализации этих баз уже имеют свои кеши.
Cdc подход. Распределенные дб и такое поддерживают. Так и обновлять materialized view
Хранит готовый результат запроса, очевидно. СУБД обычно этого не делают и исполняют запрос каждый раз.
Серьезно?
Системы с кэшем имеют всегда свойство - что-то с кэшем случается, система как ни в чем не бывало работает дальше
Что будет у вас если кэш решит почиститься?
Система попросит БД выполнить запрос и запишет результат в кэш
Во-первых, вы используете кэш как хранилище, а не как кэш
Во-вторых, ещё и оборачиваете работу с ним нетривиальной логикой
Посмотрите в статье, под кэшем подразумевается просто прокладка между БД и клиентом для улучшения производительности.
Кто использует? Все в этой ветке комментариев (включая меня) говорят о том, что это именно промежуточное хранение данных для ускорения повторного доступа к данным.
Это самая тривиальная логика работы кэша: не попали - идем за данными в более медленное хранилище.
Я не очень понимаю, почему вы считаете нетривиальной базовую логику работы с кэшами (не только для БД, но и вообще любыми). Не готов судить, что "подразумевают" авторы статьи, но вот что думают по этому поводу в AWS, например - Relational Database Caching Techniques - Database Caching Strategies Using Redis
Конкретный пример - доступность в случаях отказа основного хранилища. Даже минута простоя дорого обходится.
Принимал участие в инцидентах, где без кеша не работало бы вообще ничего и достаточно долго.
По итогам проводили серию chaos тестирований, чтобы добиться работы основных сценариев при недоступности хранилища на срок до 4 часов.
Удивлен, что нет KeyDB, учитывая что протокол полностью совместим с Redis.
Ну и read-only нагрузка - достаточно специфичный вариант, не сказать что это типичная нагрузка.
Да и в целом, для read-only - горизонтальное масштабирование зарешает (например, запуск нескольких независимых инстансов redis с одинаковыми данными). Опционально можно сделать шардинг инстансов по ключам, чтобы данные не дублировать.
Леш, редис не скалируется на запись (ибо она однопоточная), и отсюда на R/W нагрузке совсем по другому себя будет вести. Редис в большинстве кейсов с приличным W будет проигрывать упомянутым СУБД с хорошим конкаренси (особенно когда они не в serializable режиме)
Ну в целом да, но при 1.000.000 RPS сколько обычно операций на запись - больше 10%? упремся ли мы в одно ядро? Довольно важно, ~100К writes-PS main thread потянет на нормальном железе, там больше будет деградации при синках на диск (будет интересно посмотреть с aof на nvme например). Ну и кластер, write-нагрузку без кластера не смасштабировать.
Ну в целом да, но при 1.000.000 RPS сколько обычно операций на запись - больше 10%
Сколько работаю, ни разу ещё не было "обычно". Это какое-то среднее по больнице, которое ничего не даёт. У каждой задачи своя специфика.
Это общие слова, сори, и кажется, мы не спорим, либо я не понимаю, о чём. О чём?
Я не утверждаю, что "кеш не нужен", и это можно прочитать в выводах. кеш гарантирует низкий лэтенси, гарантирует хороший throuphput и база – по-прежнему риск. но риск уже меньше - традиционные базы сделали хороший шаг вперед.
Да хотя бы 1% запросов на запись. Или 3%. Просто 0% это совсем сферический конь в вакууме, очень трудно придумать реальный юз кейс кроме раздачи статики.
Предельное число запросов, что на чтение что на запись порядка 100К RPS на ядро на этих xeon gold при датасете в 10 млн 256-байтных ключей, и все эти параметры, кстати, важны. Если точно - около 160K RPS. Значит, если у вас valkey и 1M RPS, то вы "почуствуете" родовую травму редиса (main thread, не "однотредовость" - строго говоря, это неверно) только если R/W ratio > 10 (грубо). 1% или 3% - скорее всего, не почуствуете. Лучше, конечно, было бы это явно промерить - да, я согласен, про это написано в специальном разделе, в ближайшее время мы это проиллюстрируем.
Tarantool, буквально созданный для того, чтобы на нем лепить умные кэши: "Ну да, ну да. Пошел я нафиг."
Полезная статья, тоже вопросом кэша часто интересовался .
А почему не рассмотрели Dragonfly как современную альтернативу "немасштабируемому" Redis и Memcached?
Dragonfly is an in-memory data store built for modern application workloads.
Fully compatible with Redis and Memcached APIs, Dragonfly requires no code changes to adopt. Compared to legacy in-memory datastores, Dragonfly delivers 25X more throughput, higher cache hit rates with lower tail latency, and can run on up to 80% less resources for the same sized workload.
Valkey показывает примерно в 2,5 раза больший RPS по сравнению с Redis при схожих условиях. При этом, увеличение числа ядер свыше 6–8 уже не даёт существенного прироста.
Так это получается при больших нагрузках надо переходить на Valkey?? Я думал просто перелицензированный Redis.
Странный комментарий! Нет ни понимания статьи, ни единой аргументации, просто ноль, голый вася. Что характерно для современного ИТ, комментировал некий noname. Вот так :)
Даже сложные вещи умный человек может объяснить в двух словах. А если он объяснить этого не хочет, напускает тумана, использует заходы типа "у вас нет никакого понимания" и "уж я-то знаю", значит, либо он не очень умный, либо у него манипулятивная цель. Поверьте, ничего идти от основ организации не нужно. Неважно, чем отличаются принципы хранения данных, потому что вы не поняли ни исторический контекст создания кеш-слоя ни смысл этой статьи. И не знаете, что Redis (при всех его недостатках) используется в гигантском количестве огромных проектов.
Алексей, очень интересная статья!
Может у вас есть в общем доступе больше информации какие именно ключи вы использовали при сборке СУБД, какие параметры конфигов меняли ?
Здравствуйте! А есть графики по потреблению памяти (ОЗУ) с ростом количества соединений / запросов?
К сожалению, системно это не собиралось. Памяти конечно PPC модель потребляет заметно больше, и это и есть основная причина и ограничение для постгреса в ~5000 процессов на 128-гиговой машине.
Мы собрали достаточно большое количество предложений и вероятно будем делать регулярно работающий тестовый стенд. Он будет включать сбор метрик по потреблению CPU, памяти, и подробную статистику по latency запросов (кстати данные по latency как раз есть, однако к ним к самим много вопросов). Если есть какие-то еще предложения относительно того, какие метрики нужно собрать в отчеты - пишите!
Но это очень серьёзная машина с более чем 700 ГБ памяти
Хм!
А сколько сейчас памяти у типичного сервера? И вообще, какой сейчас конфиг у типичного сервера для базы данных?
А то у меня на рабочей машине сейчас 256Гб. И я хочу больше - чтобы совсем в свап не лезло.
Зависит от задач и бюджетов - года три назад, я бы сказал, что у типичного сервера баз данных 512 ГиБ оперативки и 8 (16HT) ядер, сейчас скажу, что 1.5 ТиБ памяти и 32 (64HT) ядра...
а где посмотреть конфиги для СУБД? проходил ли какой-то тюнинг настроек?
Очень странный кейс в духе: "Представим, что специализированных кэшей не существует, у нас бесконечно много денег. Вытянут ли базы данных нагрузку, если их использовать как кэш". Никакого экономического анализа целесообразности такой замены нет. Что там с latency ответов в обоих сценариях? Использовался ли pipelining для redis-like кэшей?
Просто нагрузили базу примитивными запросами, убрав и записи и репликацию.
И автор всё равно приходит к выводу: "я понимаю, что кейс странный, я бы такое использовать на продакшене не стал". Я, конечно, рад за PostgreSQL, что он не сдох, но не вижу смысла его использовать таким образом на практике.
Нет, не надо ничего придумывать. В статье показывается, что современные СУБД умеют справиться и с очень большой простой нагрузкой, выраженной в RPS, и с достаточно большим количеством одновременных соединений. И это основные причины, почему в хайлоад-проектах стали использовать кеши (но не все). Всё, больше никаких смыслов других в статье нет.
C latency всё нормально, не все графики вошли в статью. Пайплайнинг для редиса очевидно тут наоборот не нужен, поскольку это всегда искусственное "завышение" RPS в разы, а мы честно меряем отдельные запросы.
Нужен ли нам сейчас кеш-слой перед СУБД