RedisJSON
RedisJSON — это модуль для базы данных Redis, расширяющий её функциональность для работы с документами в формате JSON (JavaScript Object Notation). Он предоставляет возможность хранить, индексировать и выполнять запросы к JSON-данным непосредственно в Redis, используя собственный набор команд, а не сериализовать и десериализовать JSON в строки. Модуль реализует спецификацию JSONPath для навигации по структуре документа и поддерживает операции на уровне отдельных полей, что делает его эффективным инструментом для работы с вложенными и полуструктурированными данными.
История и развитие
RedisJSON был разработан компанией Redis Ltd. (ранее Redis Labs) как часть экосистемы модулей Redis, призванной расширить возможности оригинальной базы данных «ключ-значение». Первая стабильная версия модуля (v1.0) была выпущена в 2018 году. Основной целью создания модуля была необходимость обработки сложных JSON-документов без необходимости их полной загрузки и перезаписи при каждом изменении. До появления RedisJSON разработчики были вынуждены либо хранить JSON как строку (что делало невозможным атомарные операции над отдельными полями), либо использовать сторонние библиотеки для сериализации. Модуль решает эту проблему, предоставляя нативный тип данных JSON в Redis.
В 2020 году RedisJSON был интегрирован в Redis Stack — единый пакет, включающий Redis, модули для поиска, временных рядов, графов и JSON. В 2021 году вышла версия 2.0, которая добавила поддержку индексации и полнотекстового поиска по JSON-документам через модуль RediSearch. Это позволило выполнять сложные запросы, такие как фильтрация по вложенным полям, агрегация и сортировка, без необходимости извлекать весь документ. На момент 2024 года RedisJSON остаётся одним из ключевых модулей Redis Stack, активно поддерживаемым и обновляемым.
Архитектура и принцип работы
Хранение данных
RedisJSON хранит JSON-документы как отдельные значения, ассоциированные с ключами Redis. Внутренне модуль использует бинарный формат сериализации, оптимизированный для быстрого доступа к отдельным элементам. В отличие от хранения JSON в виде строки, где любое изменение требует десериализации, изменения и повторной сериализации всего документа, RedisJSON позволяет модифицировать только нужные части документа на уровне байтов. Это достигается за счёт структуры данных, которая хранит каждый элемент JSON (объект, массив, строку, число, логическое значение, null) как отдельный узел в дереве.
Команды
RedisJSON предоставляет набор команд, начинающихся с префикса JSON.. Основные команды включают:
JSON.SET— установка или обновление значения по указанному пути (JSONPath). Если ключ не существует, он создаётся.JSON.GET— получение значения по указанному пути. Возвращает JSON-строку.JSON.DEL— удаление элемента по указанному пути.JSON.ARRAPPEND— добавление элемента в конец массива.JSON.ARRPOP— удаление и возврат последнего элемента массива.JSON.NUMINCRBY— увеличение числового поля на заданное значение (атомарная операция).JSON.STRAPPEND— добавление строки к существующему строковому полю.JSON.OBJKEYS— получение списка ключей объекта.JSON.TYPE— определение типа данных по указанному пути.
Все команды поддерживают работу с JSONPath, что позволяет обращаться к вложенным элементам, например: $.store.book[0].title.
Индексация и поиск
Начиная с версии 2.0, RedisJSON интегрирован с модулем RediSearch. Это позволяет создавать вторичные индексы над JSON-документами. Для этого используется команда FT.CREATE с указанием типа данных JSON и определением полей, подлежащих индексации. Например, можно создать индекс над полями name и price в документах, хранящихся в виде JSON. После этого становятся доступны команды полнотекстового поиска, такие как FT.SEARCH, FT.AGGREGATE и FT.EXPLAIN. Индексация поддерживает все типы данных JSON, включая числа, строки, массивы и объекты, а также позволяет выполнять запросы с фильтрацией по диапазонам, географическим координатам и тегам.
Применение
Веб-разработка и API
RedisJSON широко используется в веб-приложениях для кэширования ответов API, которые возвращают JSON. Поскольку многие современные API (REST, GraphQL) отдают данные в формате JSON, хранение их в RedisJSON позволяет быстро обслуживать запросы без обращения к основной базе данных. Например, можно кэшировать профиль пользователя, список товаров или конфигурацию приложения. При изменении данных достаточно обновить только нужное поле, а не весь документ.
Управление сессиями
В распределённых системах RedisJSON применяется для хранения сессионных данных пользователей. JSON-документ может содержать идентификатор пользователя, время последней активности, настройки интерфейса, корзину покупок и другие данные. Благодаря атомарным операциям можно безопасно обновлять отдельные поля, например, увеличивать счётчик действий или изменять статус сессии.
Интернет вещей (IoT)
В системах IoT устройства часто передают данные в формате JSON. RedisJSON позволяет хранить и обрабатывать телеметрию (температуру, влажность, координаты) в реальном времени. С помощью индексации можно быстро находить устройства по заданным параметрам, например, все датчики с температурой выше 30°C.
Игровая индустрия
В многопользовательских играх RedisJSON используется для хранения состояния игровых объектов: инвентаря, характеристик персонажа, достижений. JSON-структура позволяет легко моделировать вложенные данные, такие как списки предметов с их свойствами. Атомарные операции, такие как JSON.NUMINCRBY, удобны для изменения здоровья или опыта.
Аналитика и агрегация
С помощью RediSearch и RedisJSON можно выполнять сложные аналитические запросы над JSON-документами. Например, агрегировать продажи по категориям, вычислять среднюю цену товаров или находить топ-10 самых популярных записей. Это возможно благодаря командам FT.AGGREGATE, которые поддерживают группировку, сортировку и вычисление статистических функций.
Преимущества и ограничения
Преимущества
- Атомарность операций на уровне полей: Изменение одного поля не требует блокировки всего документа, что повышает производительность в многопоточных средах.
- Эффективность: Модуль оптимизирован для работы с вложенными структурами, что снижает накладные расходы на сериализацию.
- Интеграция с RediSearch: Возможность полнотекстового поиска и индексации делает RedisJSON полноценной документной базой данных.
- Простота использования: Команды интуитивно понятны и следуют синтаксису JSONPath, знакомому разработчикам.
Ограничения
- Зависимость от Redis Stack: Для использования RedisJSON требуется установка модуля или использование Redis Stack. В стандартной установке Redis модуль отсутствует.
- Объём памяти: Хранение JSON в бинарном формате может потреблять больше памяти, чем хранение в виде строки, особенно для простых документов.
- Сложность запросов: Хотя RediSearch и мощный, он не поддерживает все возможности SQL, такие как JOIN или сложные подзапросы.
- Отсутствие транзакционности: Redis не поддерживает транзакции в классическом понимании (ACID), хотя и предоставляет механизмы MULTI/EXEC для атомарного выполнения группы команд.
Пример использования
Предположим, необходимо хранить информацию о товарах в интернет-магазине. Каждый товар представлен JSON-документом:
``json { "id": 123, "name": "Ноутбук", "price": 75000, "category": "Электроника", "specs": { "cpu": "Intel i7", "ram": 16, "storage": 512 }, "inStock": true } ``
Команда для сохранения документа:
`` JSON.SET product:123 $ '{"id":123,"name":"Ноутбук","price":75000,"category":"Электроника","specs":{"cpu":"Intel i7","ram":16,"storage":512},"inStock":true}' ``
Для получения названия товара:
`` JSON.GET product:123 $.name ``
Для увеличения цены на 10%:
`` JSON.NUMINCRBY product:123 $.price 7500 ``
Для проверки наличия товара:
`` JSON.GET product:123 $.inStock ``
Сравнение с альтернативами
MongoDB
MongoDB — документная база данных, которая также хранит данные в формате BSON (бинарный JSON). В отличие от RedisJSON, MongoDB предоставляет полноценную поддержку транзакций, сложные запросы с агрегацией и репликацию. Однако RedisJSON выигрывает в скорости операций чтения/записи благодаря хранению в памяти и отсутствию дисковых операций. RedisJSON лучше подходит для сценариев, где критична низкая задержка (например, кэширование), а MongoDB — для долговременного хранения и сложной аналитики.
PostgreSQL с JSONB
PostgreSQL поддерживает тип данных JSONB, который позволяет индексировать и запрашивать JSON-документы. PostgreSQL предоставляет более мощные возможности по сравнению с RedisJSON, включая поддержку SQL, транзакций и сложных JOIN. Однако RedisJSON превосходит PostgreSQL по скорости выполнения простых операций (GET/SET) и масштабируемости в распределённых системах. RedisJSON часто используется как кэш перед PostgreSQL.
Elasticsearch
Elasticsearch — поисковый движок, который также хранит JSON-документы и предоставляет мощные возможности полнотекстового поиска. В отличие от RedisJSON, Elasticsearch ориентирован на поиск и аналитику, а не на быстрые операции чтения/записи. RedisJSON может использоваться как быстрый кэш для результатов поиска из Elasticsearch, но не заменяет его в задачах сложного поиска и агрегации больших объёмов данных.
Источники
- Документация RedisJSON на официальном сайте Redis (redis.io/docs/stack/json/)
- Redis Stack Documentation: JSON Data Type
- Статья «RedisJSON – A JSON Data Type for Redis» в блоге Redis Labs (2018)
- Спецификация JSONPath (RFC 9535)
- Сравнительный анализ RedisJSON и MongoDB в статье «Redis vs MongoDB: Which One to Choose?» (2023)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →