Redis 模块作为 Redis Enterprise Software 的一部分进行捆绑和打包。下载模块(包括 RedisJSON),以使用最新的模块版本升级 Redis Enterprise Software。
准备好直接进入 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.SET
和 JSON.GET
都需要键名作为它们的第一个参数。在第一行中,我们将名为scalar的键的根(用句点字符:“.”表示)设置为字符串值。接下来,使用 JSON 对象(首先读取整个对象)然后按路径设置名为 object 的不同键的单个子元素。
在底层发生的是,每当您调用 JSON.SET
时,该模块都会通过流式词法分析器获取该值,该词法分析器会解析输入的 JSON 并从中构建树数据结构
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,它在性能方面也是一个强大的工具。初始性能基准已经表明,例如
上面的图表比较了对具有三个嵌套级别的 3.4KB JSON 有效负载执行的读取和写入操作的速率(操作/秒)和平均延迟。 RedisJSON 与在字符串中存储数据的两种变体竞争。这两种变体都实现为 Redis 服务器端 Lua 脚本,其中 json.lua 变体存储原始序列化的 JSON,msgpack.lua 使用 MessagePack 编码。
如果您有 21 分钟的时间,这里是来自 Redis Day TLV 的 RedisJSON 演示
您可以从今天开始使用 RedisJSON!
# docker run -d -p 6379:6379 --name redis-rejson redis/rejson:latest
我们仍然想添加许多功能,但总的来说,RedisJSON 非常简洁。如果您有功能请求或发现问题,请随时使用存储库的问题跟踪器。您始终可以发送电子邮件或 发推文 给我——我随时待命🙂
准备好进入 RedisJSON 了吗?请查看 Redis 开发者网站上的 RedisJSON 入门!