У тебя сервер на 32 ядра, а Redis грузит только одно.
На вид неэффективно. Но при этом Redis остается одной из самых быстрых in-memory баз.
Почему так?
Основной bottleneck обычно не CPU
Для типичных операций Redis вроде GET, SET, INCR CPU почти не тратится.
В реальных условиях упираешься в другое:
- пропускная способность сети (ответы клиентам)
- пропускная способность памяти (RAM <--> CPU cache)
- системные вызовы, TCP, epoll и другая возня ядра
В таких условиях добавление потоков не дает прироста, потому что ограничение в другом.
Почему мультипоточность сделала бы Redis медленнее?
Если бы несколько потоков трогали одну область данных, понадобились бы:
Локи
Чтобы безопасно читать или писать ключи. Ожидание блокировок добавляет задержки.
Context Switching
Переключение между 32 потоками сжигает ресурсы и ломает кэш-локальность.
Cache Coherence
Когда один поток обновляет данные, которые кэшировал другой, аппаратная часть должна инвалидировать кэши по ядрам.
Это создает "cache thrashing" и ест производительность.
Во многих сценариях эти накладные расходы больше, чем сама работа Redis-команды.
Секрет - однопоточный event loop
Redis работает на неблокирующем event loop (epoll/kqueue).
Он умеет держать тысячи соединений и обрабатывать только те сокеты, у которых есть данные.
Плюсы:
- без блокировок
- предсказуемые задержки
- строгий порядок операций
- минимальный overhead
Работая в памяти, один поток способен обработать сотни тысяч или даже миллионы команд в секунду.
Но небольшая поправка = Redis не полностью однопоточный
Redis однопоточен только в части, которая работает с данными.
Остальное вынесено в фоновые потоки.
✔️Главный поток
Выполняет команды и трогает dataset.
✔️BIO-потоки
Для долгих задач:
lazy delete (UNLINK)
синхронизация AOF
фоновые задачи модулей
✔️I/O threads (с версии Redis 6+)
Для чтения запросов и отправки ответов по сети.
При этом сами данные не трогаются, значит = без локов.
Так Redis получает выгоду от распараллеливания, не ломая простоту и предсказуемость.
Redis специально остается однопоточным в части доступа к данным, чтобы избежать локов, гонок и непредсказуемости.
При этом дополнительные потоки используются там, где они реально помогают.
В результате Redis часто обходится быстрее сложных многопоточных систем.
👉 Java Portal