Redis 模块作为 Redis Enterprise 软件的一部分进行捆绑和打包。 下载模块(包括 RedisJSON) 以使用最新模块版本升级 Redis Enterprise 软件。
准备立即使用 RedisJSON?查看 RedisJSON 入门 在 Redis 开发人员网站上!
——
RedisJSON 是一个 Redis 模块,提供原生 JSON 功能——只需运行 Docker 镜像 适用于 Redis with RedisJSON,访问 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 世界的用户直观地理解,反之亦然。 请考虑以下示例,该示例显示了如何设置和获取值
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_ 的键的根(用句点字符表示:“.”) 设置为字符串值。 接下来,一个名为 _object_ 的不同键被设置为一个 JSON 对象(首先完全读取),然后通过路径设置一个子元素。
幕后发生的事情是,每当您调用 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 非常棒。 如果你有功能请求或发现问题,请随时使用仓库的问题跟踪器。 你也可以 发邮件 或 在 Twitter 上发推文 给我——我全天候可用 🙂
准备开始使用 RedisJSON?查看 RedisJSON 入门 在 Redis 开发人员网站上!