Shopify replaced Redis with MySQL for inventory reservations–and it scaled
Мы заменили Redis‑хранилище резервов на MySQL и смогли выдержать нагрузку в $5,1 млн продаж в минуту в 2025 году.
Ключевая идея — по одной строке на каждый товарный остаток, а не на одну строку на товар с колонкой количества. Это позволило использовать SKIP LOCKED, получая конкурентный доступ к отдельным единицам и избегая конфликтов при одновременных покупках.
Получилось два важных вывода. Во‑первых, старые ограничения (одна строка‑количество) устарели: современные версии MySQL уже поддерживают нужный уровень изоляции, и их стоит перепроверить при росте нагрузки. Во‑вторых, простая прототипная проверка (небольшой скрипт, мониторинг блокировок) раскрыла реальный узел — избыточное использование соединений, а не «медленные» запросы. В итоге система стала надёжнее: больше нет перепродаж и больше завершённых покупок, а база остаётся здоровой для всех остальных процессов.
Комментарии (113)
Тред критикует подход Shopify к резервированию товаров, предлагая альтернативы: отдельная строка на заказ-товар или фоновый возврат товаров в запас. Участники согласны, что денормализация повышает производительность, но может вызывать проблемы с согласованностью и блокировками. Рекомендуется шардирование таблицы запасов по ID магазина для снижения нагрузки. Некоторые считают Shopify шагом назад — вместо Redis используется диск-ориентированная БД, не справляющаяся с десятками тысяч одновременных соединений. Хотя готовые решения проще, в данном случае они могут быть неоптимальны.
Redis is fast – I'll cache in Postgres 🔥 Горячее 💬 Длинная дискуссия
Redis показал заметно лучшую производительность по сравнению с Postgres при использовании в качестве кэша. В тестах на чтение Redis обрабатывал больше запросов в секунду, при этом нагрузка на CPU у сервера с Redis была умеренной (~1280mCPU из доступных 2000mCPU), а потребление памяти стабильно держалось на уровне ~3800 МБ. Сервер HTTP стал узким местом в случае Redis, исчерпав свои CPU-ресурсы.
Для Postgres основным ограничением стал CPU самой базы данных, который постоянно работал на максимуме. Это подтверждает, что Redis эффективнее справляется с высоконагруженными сценариями кэширования, особенно когда требуется низкая задержка и высокая пропускная способность операций чтения.
Комментарии (235)
- Критика методологии бенчмарка: сравнение ненастроенных Postgres и Redis считается некорректным, так как Postgres требует тонкой настройки под железо для серьёзных тестов.
- Сомнения в целесообразности использования Postgres как кэша: отсутствие встроенного TTL, нагрузка на основную БД и сложности с вакуумом делают Redis более надёжным решением.
- Подчёркивается важность контекста: для небольших нагрузок (<1000 RPS) и упрощения стека использование Postgres может быть оправдано.
- Замечания о специфике теста: сравнение ограниченного Postgres (2 ядра) с неограниченным Redis, малый размер данных и отсутствие пайплайнинга искажают результаты.
- Обсуждаются альтернативы: использование UNLOGGED таблиц, специализированных клиентов (rueidis) или встроенного кэша приложения вместо распределённого решения.
Do the simplest thing that could possibly work 🔥 Горячее 💬 Длинная дискуссия
Разрабатывайте самое простое, что только может работать.
Это правило годится и для исправления багов, и для новых систем.
Многие инженеры мечтают о «идеальной» архитектуре: масштабируемой, распределённой, красивой. Это ошибка. Лучше глубже понять текущую систему и сделать самое простое решение.
Простое может выглядеть скучно
Джуны любят рисовать сложные схемы из кэшей, очередей, прокси. Настоящее мастерство — уметь делать меньше. Великий дизайн выглядит тривиально: «О, задача оказалась простой».
Unicorn и стандартный Rails REST API — примеры: всё нужное достигается очевидными средствами.
Практика
Нужно ограничение частоты запросов в Go-сервисе?
- Вариант 1: Redis + алгоритм «протекающего ведра».
- Вариант 2: счётчики в памяти (теряются при рестарте).
- Вариант 3: включить rate-limit в edge-прокси одной строкой конфига.
Если последнее покрывает требования — выбирайте его.
Развивайте продукт, начиная с минимума и усложняя только по новым требованиям. Это YAGNI как высший принцип.
Возражения
-
Слякоть из костылей
Костыль не прост — он добавляет сложности. Настоящее простое решение требует понимания всей системы и часто сложнее придумать. -
Что такое «просто»?
Простота — это минимум сущностей, минимум переходов, минимум новых инструментов. Она не всегда очевидна и требует инженерной работы. -
Масштабирование
Простое не значит «только сейчас». Unix-сокеты, CGI, файлы — примитивы, на которых построены крупные системы. Если завтра потребуется масштаб, выясните новые факты и добавьте минимально необходимое.
Делайте самое простое, что только может работать — и будете удивлены, как далеко это вас заведёт.
Комментарии (364)
- Участники сходятся в том, что «делай самое простое, что может работать» — полезная эвристика, но не универсальный закон.
- Опытные разработчики подчеркивают: простота ≠ легкость; требует глубокого понимания задачи и контекста.
- На больших системах «простое» быстро ломается из-за edge-case’ов и масштаба, поэтому часто приходится усложнять.
- Частая ошибка — проектировать «на вырост»: реакт, k8s и прочее для сайта из трёх страниц, лишь бы «в портфолио».
- Самый практичный совет: фиксируй реальные требования здесь и сейчас и строй под них, а не под гипотетическое будущее.
Why was Apache Kafka created? 💬 Длинная дискуссия
Почему появился Apache Kafka
LinkedIn, 2012 г.
Проблема интеграции
LinkedIn нужно было передавать данные активности (лайки, просмотры, публикации) в десятки систем: антифрод, ML-модели, веб-функции, витрины, Hadoop. Эти потоки — критичная инфраструктура, а не просто аналитика.
Старые трубы
- Пакетный конвейер: приложения писали XML на HTTP-сервер; раз в час файлы собирались, парсились и грузились в Oracle + Hadoop.
- Realtime-конвейер: метрики и логи уходили в Zenoss, но туда нельзя было добавить новые данные без ручной работы, а данные были изолированы.
Общие боли
- ручное сопровождение и добавление источников;
- постоянные бэклоги;
- point-to-point архитектура без обмена между системами.
Вывод
LinkedIn понял, что нужен один надёжный, масштабируемый и универсальный «шина событий», куда пишут все, а читают кто угодно. Так родился Kafka.
Комментарии (172)
- LinkedIn отказался от Kafka и создал собственную систему Northguard из-за невозможности масштабировать 32 трлн записей/день, 17 ПБ/день и 400 тыс. топиков.
- Участники спорят: Kafka мощна для «огненных шлангов» данных и многократного потребления, но требует экспертизы и ресурсов; для большинства задач достаточно Redis, NATS, RabbitMQ.
- Названа главная фишка Kafka — возможность переигрывать сообщения и строить разные консьюмеры поверх одного лога.
- Сравнивают NATS (Jetstream) и Apache Pulsar как более лёгкие альтернативы; Redpanda тоже упоминается.
- Мнения разделились: кто-то считает Kafka переоценённой и «бюрократичной», кто-то — незаменимой для больших данных.