dot Redis 8 来了——而且是开源的

了解更多

RedisJSON:Redis JSON 存储

Redis 模块作为 Redis Enterprise Software 的一部分进行捆绑和打包。下载模块(包括 RedisJSON),以使用最新的模块版本升级 Redis Enterprise Software。

redis json image with Redis Stack

准备好直接进入 RedisJSON 吗?请查看 Redis 开发者站点上的 RedisJSON 入门

——

RedisJSON 是一个 Redis 模块,提供原生 JSON 功能——只需运行带有 RedisJSON 的 Docker 镜像,访问 GitHub 仓库,或在线阅读 文档

JSON 和 Redis 都无需介绍;前者是现代应用程序之间的标准数据交换格式,而后者在需要高性能数据管理的任何地方都无处不在。鉴于这种情况,几年前当我得知这两者不兼容时,我感到震惊。

Redis 不是一招鲜——实际上,恰恰相反。与通用的“一刀切”数据库不同,Redis(又名“数据库界的瑞士军刀”、“微服务的超级胶水”和“函数即服务 的执行环境”)为特定任务提供专用工具。开发人员使用这些工具(以抽象数据结构及其配套操作的形式公开)来为问题建模最佳解决方案。这正是使用 Redis 管理 JSON 数据不自然的原因。那么我们如何使用 RedisJSON 模块呢?

事实:尽管 Redis 拥有多种核心数据结构,但没有一种能够满足 JSON 值的要求。当然,您可以通过使用其他数据类型来解决这个问题:字符串非常适合存储原始序列化的 JSON,您可以使用哈希表示平面 JSON 对象。但是,这些变通模式施加了限制,使其仅在少数用例中才有用,即使这样,体验也留下了非 Redis 风格的回味。它们的笨拙与正常使用 Redis 的简单性和优雅性形成了鲜明对比。

但在去年 Salvatore Sanfilippo 的 @antirez 访问 Redis 的特拉维夫办事处之后,并且随着 Redis 模块 成为现实,一切都发生了变化。突然,天空不再是极限。现在模块让任何人都可以做任何事情,结果证明我可以成为那个特别的人。在中断了二十多年后,重新开始 C 语言开发,结果证明它并没有我想象的那么可怕,并且在 Dvir Volk 的 @dvirsky 的悉心指导下,我们诞生了 RedisJSON。

虽然您可能对它的名称不满意(我知道我不是——欢迎提出建议),但 RedisJSON 本身应该会让任何 Redis 用户都沉浸在 JSON 的快乐中。该模块提供了一种新的数据类型,该类型专为快速有效地操作 JSON 文档而定制。像任何 Redis 数据类型一样,RedisJSON 的值存储在可以使用专用命令子集访问的键中。这些命令(或模块公开的 API)旨在让从 JSON 世界来到 Redis 的用户和反之亦然的用户都能直观地使用。考虑一下这个例子,它展示了如何设置和获取值

127.0.0.1:6379> JSON.SET scalar . '"Hello JSON!"'
OK
127.0.0.1:6379> JSON.SET object . '{"foo": "bar", "ans": 42}'
OK
127.0.0.1:6379> JSON.GET object
"{"foo":"bar","ans":42}"
127.0.0.1:6379> JSON.GET object .ans
"42"
127.0.0.1:6379> ^C
~$ 

像任何行为良好的模块一样,RedisJSON 的命令都带有前缀。 JSON.SETJSON.GET 都需要键名作为它们的第一个参数。在第一行中,我们将名为scalar的键的根(用句点字符:“.”表示)设置为字符串值。接下来,使用 JSON 对象(首先读取整个对象)然后按路径设置名为 object 的不同键的单个子元素。

在底层发生的是,每当您调用 JSON.SET 时,该模块都会通过流式词法分析器获取该值,该词法分析器会解析输入的 JSON 并从中构建树数据结构

redis json commands

RedisJSON 以二进制格式将数据存储在树的节点中,并支持 JSONPath 的子集,以便轻松引用子元素。它拥有一系列专为每种 JSON 值类型量身定制的原子命令,包括:用于追加字符串的 JSON.STRAPPEND;用于乘数的 JSON.NUMMULTBY;以及用于修剪数组的 JSON.ARRTRIM……并让海盗们开心。所有这些都使用 RedisJSON。

由于 RedisJSON 被实现为一个 Redis 模块,因此您可以将其与任何 Redis 客户端一起使用,该客户端:a) 支持模块(目前没有)或 b) 允许发送原始命令(目前大多数)。例如,您可以使用来自您的 Python 代码的启用 RedisJSON 的 Redis 服务器与 redis-py,就像这样

import redis
import json

data = {
    'foo': 'bar',
    'ans': 42
}

r = redis.StrictRedis()
r.execute_command('JSON.SET', 'object', '.', json.dumps(data))
reply = json.loads(r.execute_command('JSON.GET', 'object'))

但这只是其中的一半。RedisJSON 不仅仅是一个漂亮的 API,它在性能方面也是一个强大的工具。初始性能基准已经表明,例如

ReJSON json.lua msgpack lua rate graph
REJSON json.lua msgpack lua average latency graph

上面的图表比较了对具有三个嵌套级别的 3.4KB JSON 有效负载执行的读取和写入操作的速率(操作/秒)和平均延迟。 RedisJSON 与在字符串中存储数据的两种变体竞争。这两种变体都实现为 Redis 服务器端 Lua 脚本,其中 json.lua 变体存储原始序列化的 JSON,msgpack.lua 使用 MessagePack 编码。

如果您有 21 分钟的时间,这里是来自 Redis Day TLV 的 RedisJSON 演示

https://www.youtube.com/embed/NLRbq2FtcIk

您可以从今天开始使用 RedisJSON!

# docker run -d -p 6379:6379 --name redis-rejson redis/rejson:latest

我们仍然想添加许多功能,但总的来说,RedisJSON 非常简洁。如果您有功能请求或发现问题,请随时使用存储库的问题跟踪器。您始终可以发送电子邮件发推文 给我——我随时待命🙂

准备好进入 RedisJSON 了吗?请查看 Redis 开发者网站上的 RedisJSON 入门