Откуда берется сравнение с Redis и почему HurriCache — это не «еще один аналог»
Redis — это безусловный индустриальный стандарт и великолепный инструмент, доказавший свою надежность годами эксплуатации. Задача HurriCache — решить те задачи с которыми Redis, с однопоточной архитектурой классических in-memory решений, изначально не справлялся, и в некоторой степени не предназначен для них.
На экстремально высоких нагрузках ключевые особенности Redis иногда превращаются в узкие места:
Непредсказуемые задержки (Latency Spikes): Выбросы p99/p99.9 из-за фонового рехешинга или исполнения длительных Lua-скриптов;
Просадки на записи и удалении: Падение пропускной способности при интенсивной смешанной CRUD-нагрузке;
Ограничение одного ядра: Необходимость администрирования десятков мелких инстансов Redis для утилизации мощностей современных многоядерных серверов.
HurriCache создан как узкоспециализированный, ultra-high-load «горячий» слой для предельно быстрых и регулярных операций над данными в оперативной памяти (без встроенной персистентности на диск). Это не прямая замена Redis — системы преследуют разные архитектурные цели, но в своем целевом профиле нагрузки HurriCache позволяет выжать максимум из современного железа.
Архитектура HurriCache
В основе HurriCache лежит кастомная, сильно оптимизированная Partitioned Hash Map.
Если не уходить в глубокие детали реализации, главное её свойство — полное отсутствие глобального рехешинга (Stop-the-World rehashing). При проектировании структуры использовались отдельные концептуальные идеи из absl::flat_hash_map, однако под узкоспециализированные задачи HurriCache собственная Partitioned Hash Map демонстрирует ощутимо более высокую производительность.
Оптимизация достигается за счет нескольких ключевых решений:
Шардирование структуры в памяти: данные разбиваются на независимые партиции, что избавляет от просадок p99/p99.9 latency, неизбежно возникающих при расширении обычных словарей;
Аппаратное ускорение: активное применение SIMD-инструкций (SSE, AVX, CRC32) для параллельного вычисления хэшей;
Cache-friendly подходы: упаковка данных под размер кеш-линий процессора (64 bytes) и использование аппаратных
prefetch, сводящее к минимуму CPU stalls при обращении к бакетам.
Остальные внутренние детали реализации структуры данных являются коммерческой тайной.
Архитектурная схема узлов и взаимодействия
Упрощенно структура кластера и потоки данных выглядят так:

Разбор компонентов схемы:
-
SmartClient: Служит единой точкой входа для приложения. Он разделяет служебный и дата-трафик:
Routing-запросы: периодически запрашивает актуальные данные о топологии кластера у
HurriCache Coordinator Server.Data-запросы: отправляет CRUD-операции и работы с контейнерами напрямую в
HurriCache Serverконкретной ноды-владельца ключа.
-
Анатомия узла (Node 1 / Node 2): Каждый узел представляет собой изолированный процессинг со своим набором компонентов, связываемых через gRPC Layer:
HurriCache Server: основной модуль обработки CRUD-запросов и выполнения атомиков прямо над
Partitioned HashMap.HurriCache Coordinator Server: многофункциональный управляющий модуль — отдаёт актуальную карту маршрутизации (
Routing Data) клиентам, отвечает за глобальное управление распределением шардов, процесс миграции данных между нодами и непрерывно проверяет жизнеспособность (health check) соседних узлов.Replication Server: модуль фоновой репликации, обменивающийся данными напрямую с
Replication Serverсоседних нод кластера для обеспечения отказоустойчивости.Routing Data & Partitioned HashMap: локальное хранилище состояния топологии и непосредственная in-memory структура данных.
Что такое SmartClient
SmartClient — это умный клиентский слой (SDK), реализующий клиентскую маршрутизацию (client-side sharding). Вместо использования прокси-серверов или тяжелой перемаршрутизации на стороне хранилища, SmartClient полностью берет на себя логику выбора целевого узла, обеспечивая минимальный RTT и предсказуемую задержку.
Ключевые подходы к работе
Локальная карта топологии: SmartClient фоново запрашивает у координатора состояние кластера и держит в памяти актуальную таблицу маршрутизации (
Master/Backupноды для каждого шарда). Это позволяет отправлять gRPC-запрос сразу на целевой сервер без промежуточных хопов.Гибкий расчет KeyHint: До отправки сетевого вызова клиент может вычислить детерминированный
KeyHint(включающий хэш ключа, напримерWeekHashилиStrongHash). Если клиент этого не делает,KeyHintгенерируется сервером (например, при вызовахcreateKeyValue). По значениюKeyHintSmartClient мгновенно определяет нужныйShardIDи обращается напрямую к целевому узлу.Автоматический Fallback и Reroute: В случае неактуальности локальной карты топологии или переезда шарда, узел HurriCache возвращает ошибку перемаршрутизации (со статусом
FAILED_PRECONDITIONи новыми метаданными роутинга в gRPC Trailers). SmartClient прозрачно для приложения обновляет локальную таблицу роутинга и делает бесшовный retry на правильную ноду.
Почему маршрутизация вынесена на сторону клиента (Client-Side Routing)
В классических прокси-схемах или при реализации рероутинга внутри узлов хранилища сервер, получивший запрос «не по адресу», вынужден самостоятельно пересылать его на правильную ноду. В HurriCache от этой схемы осознанно отказались:
Исключение двойного RTT и процессорных оверхедов: Внутренний пересыл — это синхронная межнодовая сетевая операция. На обработку одного такого запроса блокируются ресурсы минимум двух узлов (потока-прокси на первой ноде и потока-исполнителя на целевой).
Сохранение линейной пропускной способности: Внутренний роутинг превращает узлы кластера в транзитные прокси, из-за чего пропускная способность падала бы кратно росту объема данных и количества шардов.
Дешевая коррекция на клиенте: Если SmartClient ошибается с выбором ноды (например, при рассинхронизации топологии), сервер не пересылает тело запроса, а возвращает легкий gRPC-заголовок с корректными метаданными роутинга. Повторная отправка происходит прямо с клиента, что не нагружает межнодовую сеть и позволяет кластеру масштабироваться линейно под высокой нагрузкой.
Поддерживаемые операции в HurriCache
HurriCache предоставляет богатый набор примитивов, разработанных с акцентом на строгость типов, нативную атомарность и безопасность в распределенной среде.
-
1. Базовые Key-Value операции (Скаляры)
createKeyValue: Создание новой пары «ключ-значение». Главное отличие от Redis — отсутствие lazy create (upsert): если ключ уже существует, система вернет ошибку. Это предохраняет данные от случайного перезаписывания.getValue: Чтение значения по ключу.getAndDeleteValue: Атомарное чтение и последующее удаление объекта за один запрос (Get-and-Delete).updateValue: Явное обновление только существующего значения.remove: Универсальное удаление объекта любого типа или контейнера из памяти.
2. Контейнеры и коллективные типы HurriCache поддерживает привычные по функциональности Redis структуры данных, но добавляет к ним нативные атомарные операции вроде
GetAndDeleteдля внутренних элементов:Set: Упорядоченные (
OrderedSet) и неупорядоченные (HashSet).Map: Упорядоченные (
OrderedMap) и неупорядоченные (HashMap).List: Двусвязный список (
Linked List).Vector: Динамический массив (
Array List).Queue: Строгая очередь FIFO.
Встроенная система распределенных блокировок Благодаря нативной поддержке Multi-tenancy, HurriCache позволяет любому клиенту изолированно заблокировать целевой объект. Блокировка регулируется на уровне движка с помощью типов:
enum LockType : uint8_t { NO_LOCK = 0, WRITE_LOCK = 1, READ_LOCK = 2, GLOBAL = 3 };
-
Lock-Free Атомики (Out-of-the-Box) Если в Redis для реализации атомарных цепочек (например, CAS) приходится писать Lua-скрипты, блокирующие исполняющий поток, то HurriCache поддерживает безблокировочные атомики «из коробки» прямо в кластерном режиме:
Создание:
atomicCreate.Чтение и запись:
atomicLoad,atomicStore,atomicLoadAndDelete.Модификация и обмен:
atomicExchange,atomicAdd,atomicSub.Побитовые операции:
atomicOr,atomicAnd,atomicXor.CAS операции:
atomicCompareAndSet(CAS) для построения высоконагруженных lock-free алгоритмов поверх кэша.
Сравнение архитектур Redis и HurriCache
Главное архитектурное различие между системами кроется в подходе к параллелизму и организации данных в памяти. Redis исторически опирается на однопоточную исполняющую модель (Single-Threaded Event Loop) и единый глобальный словарь — это исключает состояния гонки, но упирается в производительность одного ядра CPU и приводит к просадкам p99 latency при фоновом рехешинге.
HurriCache, напротив, изначально спроектирован под многопоточную асинхронную архитектуру. В его основе лежит кастомная Partitioned Hash Map, которая устраняет задержки Stop-the-World за счет шардирования структуры данных прямо в памяти и агрессивного использования возможностей железа:
SIMD-ускорение: инструкций SSE, AVX и аппаратного CRC32 для мгновенного параллельного вычисления хэшей;
Cache-friendly: структуры данных оптимизированы под размер кеш-линий процессора (64 bytes);
Аппаратный Prefetch: инструкция явного предвыборки данных в кеш L1/L2 процессора до обращения к памяти, что сводит к минимуму CPU stalls при перемещении по цепочкам бакетов.
Для работы с сетью HurriCache использует глубоко кастомизированный gRPC Engine. За счет прямого управления асинхронными Completion Queues, оптимизированного сборкой под LTO и выравниванием thread_local переменных, система линейно масштабирует пропускную способность по всем доступным ядрам CPU там, где Redis упирается в потолок одного треда. (Это далеко не все изменения в gRPC Engine)
Сравнение API Redis vs HurriCache
Сравнение интерфейсов отражает кардинальное различие в идеологии двух систем: универсальный текстовый/RESP-протокол Redis с динамической типизацией против строго детерминированного, высокопроизводительного Protobuf-контракта в HurriCache.
Протокольная основа и строгость типов: Redis использует собственные текстовые/RESP-команды (
SET,HSET,LPUSH), где аргументы передаются как массивы строк, а тип контейнера определяется динамически в момент создания. В HurriCache контракт задан строго через gRPC-сервисHurriCacheGrpcService. Каждая операция имеет четко типизированную RPC-сигнатуру, что дает высокую производительность на сериализации (благодаря Protobuf-аренам) и автогенерацию типобезопасных клиентов под любые языки без написания парсеров.-
Семантика создания объектов (Explicit vs Lazy): В Redis создание ключей происходит по схеме lazy create/upsert: команда
SETилиLPUSHсоздаст объект, если его не существовало, или перезапишет/допишет в него. HurriCache разделяет создание и модификацию:Создание скаляров и контейнеров строго явное (
createKeyValue,createContainer), возвращающееKeyHintResponseдля будущей мгновенной маршрутизации.Попытка пересоздать существующий ключ вернет ошибку. Это исключает случайные перезаписи данных на сетевом уровне.
-
Атомарность и работы с контейнерами: В Redis составные операции (например, «прочитать и сразу удалить элемент контейнера» или CAS-сравнение) требуют написания Lua-скриптов или сложных цепочек
WATCH/MULTI/EXEC. В API HurriCache такие паттерны извлечения внедрены на уровне нативных RPC-вызовов:getAndDeleteValue(для скаляров),getAndRemoveFront/getAndRemoveTail(для списков и очередей).getAndRemoveElementAtPositionиgetAndDeleteValueInContainer(для карт и множеств). Операции выполняются за один RTT на уровне ядра хранилища без накладных расходов на интерпретатор Lua.
-
Полноценные Lock-Free Атомики (out-of-the-box): У Redis для работы со счетчиками есть только базовые
INCR/DECRBY, а для сложной атомарной логики снова нужен Lua. HurriCache предоставляет полноценный набор атомарных примитивов для безблокировочной разработки:Низкоуровневые битовые операции:
atomicOr,atomicAnd,atomicXor.Обмен и сравнение:
atomicExchangeи нативныйatomicCompareAndSet(CAS), что позволяет строить распределенные lock-free алгоритмы прямо поверх кэша.
Явное управление блокировками и TTL: В Redis блокировки строятся поверх сторонних алгоритмов (вроде Redlock через
SET NX EX). В HurriCache явное управление блокировками объектов встроенное: методыlockObjectиunlockObjectподдерживают различные уровни гранулярности (READ_LOCK,WRITE_LOCK,GLOBAL), интегрированные с системой Multi-tenancy. Настройки TTL (setTtl,getTtl) при этом едины и применимы ко всем типам данных (включая сложные контейнеры и атомики).
Результаты тестов
Чтобы проверить реальную производительность HurriCache под нагрузкой, была проведена серия стресс-тестов.
Конфигурация тестового стенда:
Топология: 1-нодовая конфигурация (Single Node)
CPU: Intel Core i9-11900K (11th Gen) @ 3.50GHz (8 ядер / 16 потоков)
RAM: 128 GB DDR4 (двухканальный режим)
Сеть:
loopback(127.0.0.1) — тест измеряет чистую производительность движка и gRPC-стека без ограничений физической сетиПараметры нагрузки: 32 параллельных клиентских потока по 100 000 операций на поток (всего 3,2 млн операций на тест)
Размер данных: Ключ — 150 байт, Значение — 500 байт
Тип операции |
HurriCache (Без пайплайнинга) |
Redis (Без пайплайнинга) |
Redis (С пайплайном) |
Чтение (Read) |
85000 RPS |
~5000 RPS |
~60000 RPS |
Запись (Write) |
77000 RPS |
~3000 RPS |
~20000 RPS |
Атомики (создание, чтение, инкремент, CAS) |
~100000 RPS |
Н/Д (требует Lua) |
Н/Д |
Смешанный тест (20% Create / 60% Read / 20% Update) |
80 000 – 100 000 RPS (доп. порог ошибок до 15%) Заложена самим тестом |
Примечание по кластеру: При тестировании кластерной конфигурации HurriCache показал практически линейный рост производительности по мере добавления новых нод благодаря маршрутизации на стороне SmartClient и отсутствию межнодовых пересылок запросов.
Примечание по контейнерам: В данном тестировании проверялись только базовые скалярные операции и атомики. Контейнерная часть (Lists, Sets, Maps) на текущий момент реализована функционально, но пока не проходила этап точечных низкоуровневых оптимизаций, поэтому ее бенчмарки будут опубликованы в следующих материалах.
Разбор результатов
Преимущество на записи: HurriCache показывает 77K RPS на запись против 3K RPS у Redis без пайплайна (и 20K RPS с пайплайном). Это следствие отсутствия глобального блокирующего словаря и эффективного применения
prefetchвместе с lock-free структурами.Стабильность на смешанной нагрузке: В профиле 20% Create / 60% Read / 20% Update HurriCache держит планку в 80K–100K RPS даже при жестком ограничении на допустимый порог ошибок (до 15%). Отсутствие глобального рехешинга сохраняет предсказуемую задержку при постоянной перезаписи и создании новых ключей.
Запас по атомикам: Нативные lock-free атомики выдерживают около 100K RPS за счет выполнения операций прямо на уровне процессора без накладных расходов на интерпретацию скриптов.
Пайплайнинг не требуется: HurriCache выдает производительность, превышающую пакетный Redis-пайплайнинг, работая при этом в честном синхронном режиме «запрос-ответ» благодаря асинхронным Completion Queues в gRPC.
Потенциальные потребители функционала
Изначально HurriCache разрабатывался под жесткие требования телеком-отрасли — систем онлайн-чарджинга (OCS) и биллинга, где от задержки списания средств зависит пропуск трафика в реальном времени. Впоследствии фокус проекта расширился на более широкий спектр high-load систем, сталкивающихся с ограничениями традиционных in-memory хранилищ на многоядерных серверах.
Основная целевая аудитория системы — инженеры и архитекторы с экстремальными требованиями к пропускной способности (RPS) и строгому соблюдению SLA по задержкам (p99/p99.9 latency).
1. Телеком, Системы Чарджинга и Биллинга (Real-Time OCS)
Проблема: Необходимость атомарно проверять и списывать баланс абонента за миллисекунды во время звонков или сессий передачи данных. Задержка или сбой приводит к некорректной тарификации либо обрыву связи.
Решение HurriCache: Нативные lock-free атомики и предсказуемая задержка без просадок на рехешинг позволяют обрабатывать высококонкурентные транзакции биллинга прямо в памяти с нулевым риском блокировки потоков.
2. High-Load и AdTech сервисы (Рекламные движки и Real-Time Bidding)
Проблема: Обработка миллионов аукционов в секунду требует миллисекундных ответов. Выбросы задержек (p99 latency spikes), вызванные фоновым рехешингом Redis или блокировками single-thread потока, приводят к пропуску ставок и прямой потере выручки.
Решение HurriCache: Lock-free структура
Partitioned HashMapс предсказуемым профилем задержек и аппаратным ускорением SIMD/prefetch обеспечивает стабильный RPS без Stop-the-World просадок.
3. Финансовый сектор, Финтех и Торговые платформы
Проблема: Потребность в атомарных операциях без накладных расходов. В Redis реализация условной логики (CAS, списание/начисление лимитов, балансы) требует Lua-скриптов, которые выполняются блокирующим образом и режут общий throughput.
Решение HurriCache: Нативные аппаратные атомики (
atomicCompareAndSet,atomicAdd,atomicExchange) позволяют строить распределенные безблокировочные алгоритмы (Lock-Free Data Structures) с производительностью порядка ~100K RPS на ноду.
4. Игровые бэкенды (Gamedev & Real-time Multiplayer)
Проблема: Высокая конкуренция за изменение состояния персонажей, игровых комнат, сессий и матчмейкинга в реальном времени.
Решение HurriCache: Встроенная поддержка гранулярных блокировок (
READ_LOCK,WRITE_LOCK) на уровне отдельных объектов вместе с нативной Multi-tenancy позволяет безопасно и изолированно управлять состоянием игроков из сотен параллельных потоков.
5. Распределенные микросервисные архитектуры
Проблема: Перегрузка прокси-слоев (Envoy, HAProxy) и узлов базы данных из-за постоянной перемаршрутизации (rerouting) некорректно отправленных запросов.
Решение HurriCache: Использование
SmartClientиKeyHintпозволяет перенести всю тяжелую логику шардирования на сторону клиентского приложения, снижая сетевой оверхед (RTT) и утилизируя 100% ресурсов серверного железа исключительно на обработку данных.
6. Проекты, вертикально масштабирующие In-Memory инфраструктуру
Проблема: Современные серверы оснащаются 64+ ядрами CPU, однако однопоточные решения утилизируют только одно ядро, заставляя инженеров разворачивать десятки мелких инстансов Redis и усложнять эксплуатацию.
Решение HurriCache: Полноценная многопоточная архитектура на базе асинхронных gRPC Completion Queues масштабируется вертикально по ядрам CPU на одном узле, заменяя целый кластер традиционных single-threaded кэшей.
Модель распространения, лицензирование и поддержка
Модель дистрибуции HurriCache строится по принципу Open-Core / Commercial, строго разделяя ядро системы и экосистему клиентских библиотек.
1. Модель исходного кода и Open Source контрибьютинг
Код движка (Core): Исходный код самого сервера HurriCache на текущем этапе закрыт (Proprietary) для защиты проприетарных алгоритмов in-memory структуры данных.
Клиентские SDK (SmartClient): Код всех клиентских библиотек и коннекторов полностью открыт (Open Source). Сообщество приветствуется в качестве контрибьюторов — можно разрабатывать интеграции для новых языков программирования, улучшать алгоритмы роутинга и оптимизировать сетевой стек.
2. Редакции и варианты лицензий
-
Single-Node редакция (Community / Developer Edition):
Формат: Готовый, преднастроенный Docker-образ
Лицензия: Бесплатный контракт / EULA на коммерческое и некоммерческое использование.
Условия: Полнофункциональный single-node движок без искусственных ограничений по RPS, количеству тредов или памяти. Запрещен реверс-инжиниринг и перепродажа в виде управляемого SaaS-сервиса.
-
Cluster / Enterprise редакция (Distributed Edition):
Формат: Helm-чарты, приватный Docker Registry, нативные пакеты для корпоративных Linux-дистрибутивов. Возможны узкоспециализированные билды
Лицензия: Коммерческая Enterprise-лицензия (Per-Node / Per-Core).
Условия: Включает модули автоматической репликации (
Replication Server), динамическую перемаршрутизацию, балансировку шардов и миграцию данных (Coordinator Server).
3. Модель технической поддержки
-
Community Support (для Single-Node и Open Source SDK):
Поддержка осуществляется через GitHub Issues.
Обработка багрепортов и предложений функционала происходят в порядке очереди без гарантированного SLA по времени ответа и исправления.
-
Enterprise Support (для кластерных пользователей):
Персональный выделенный канал связи и фиксированный SLA на реагирование и выкатку хотфиксов.
Прямые консультации по архитектуре, профилированию задержек и оптимизации клиентского кода.
Где попробовать и потестировать
Для тех, кому интересно покрутить HurriCache на собственных стендах, посмотреть исходный код клиентского SDK или провести самостоятельные нагрузочные тесты:
Java Client (SmartClient SDK): github.com/hurricache/hurricache-java-client
-
Single-Node Docker Image:
docker pull docker.io/alexaborisov/fastcache-standalone:26.34 docker pull docker.io/alexaborisov/fastcache-standalone:latest
Docker-образ буду обновлять по мере возможности и выхода свежих оптимизаций.
Буду рад любому фидбеку, issues и контрибьютам в репозиторий клиента на разных языках программирования!