新闻资讯

关注百度智能云最新动态,了解产业智能化最新成果

百度 Redis 多模数据库建设 - 原生支持 JSON 数据类型

2023-08-23 15:08:02

1 背景

随着业务的快速发展,开发人员在开发应用程序时对数据存储多样性的需求也更强烈,在一个服务中可能既需要像 Redis 这样的 KV 数据库,也需要文档数据库 MongoDB、图数据库 Neo4j、时序数据库 Influxdb 等多种 NoSQL 服务。但同时管理和维护这么多套服务无论对运维还是开发同学都是非常麻烦的,此外,大家还希望多种数据能够相互融合、统一访问,其实这也就是最近几年很火的多模数据库


多模数据库 Multi-Model 是指同一个数据库支持多个数据模型,可以同时满足应用程序对于结构化、半结构化、非结构化数据的统一管理需求。



如上图所示,当前在 DB-Engine 中,排名前 10 的数据库中有 8 款都宣称自己为多模数据库,而且越来越多的数据库产品支持更多的数据存储类型。


在 Gartner 发布的 2021年《Top 16 Cloud Database Management Systems》中,数据库的多模能力成为数据库评比的重要指标。多家云厂商都推出了自己的多模数据库产品,如 Microsoft CosmosDB、RedisLabs Modules、阿里 Lindorm 等。


在信通院发布的数据库发展研究报告(2021年)》中,提出了 7 个数据库发展趋势,其中『多模数据库实现一库多用』作为第一个趋势:


后关系型阶段,数据结构越来越灵活多样。面对这些多种结构的数据,应用程序对不同数据提出了不同存储要求, 数据的多样性成为数据库平台面临的一大挑战,数据库因此需要适应多类型数据管理的需求。多模数据库支持灵活的数据存储类型,将各种类型的数据进行集中存储、查询和处理,可以同时满足应用程序对于结构化、半结构化和非结构化数据的统一管理需求。未来在云化架构下,多类型数据管理是一种新趋势, 也是简化运维、节省开发成本的一个新选择。



可见,多模数据库因其统一数据存储和访问、开发运维成本低等优点,也已经逐渐成为数据库发展的一个重要方向,且正在快速发展。


此外,需要实时处理的数据也正在快速增长,IDC 在《The Digitization of the World, From Edge to Core》中指出,『到 2025 年,在全球范围内将创建 175 ZB 数据,其中 30% 的数据将被实时处理』,而 2021-2022 年这个数字只有 10% 左右。在数据实时存储和计算方面,像 Redis 这类的内存数据库必将在其中扮演重要的角色。

2 百度 Redis 多模数据库建设方案

BDRP 作为公司级 Redis 服务,为手百、Feed、地图、度秘、安全实验室等多个核心业务提供存储服务,不仅有内存版本 Redis,还提供了磁盘型 Redis 存储服务。但这些服务存储的数据类型主要以 KV 为主,部分场景下业务使用不便,需要其他类型的 NoSQL 服务。即使对其他数据类型存储量不大,业务同学仍需要部署额外的存储服务,管理和运维成本都很高;数据分开存储在多个服务中不利于统一管理和访问;此外在数据的实时存储方面,基于磁盘的 NoSQL 服务性能和延迟跟内存版的 Redis 也有较大差距,所以 BDRP 团队提出实现 Redis 的多模数据库以更好地支持业务快速发展。


Redis 自 4.0 版本开始支持模块 Module 系统,开发者可以定制相应的模块以满足需求。我们可以开发不同的数据类型模块来支持更丰富的数据类型,同时所有的数据都在同一个 keyspace 下,可以实现跨不同数据类型的统一访问,方便业务逻辑的实现。



如上图所示,通过 module 方式完成不同数据类型模块开发后,将对应的模块部署、加载到集群所有的 Redis 实例,依赖 BDRP 在数据分片、流量控制和路由、动态扩缩容、高可用和自愈的基础能力,即可实现 Redis 多模数据库方案。而且这种方式也具有极强的灵活性,只需要聚焦模块本身的功能开发,甚至业务同学可以和我们共建 Module 以提供更丰富的多模能力。

3 百度 Redis JSON

我们不可能一下子完成所有数据类型的支持,我们应首先支持应用场景最多、业务最需要的数据类型。RedisLabs 最早开始在 Redis 上实现多种数据模型,他们的实践经验给我们提供了参考,如下图所示,RedisLabs 支持 JSON、Search、Graph、TimeSeries、Bloom 模块以实现对文档、搜索、图、时序等数据库和服务的支持,同时我们可以看出 JSON 模块是用户使用最多的模块。



JSON 作为一个常用的数据表达方式,非常适用于提供实时性能的现代应用程序,比如内容管理、产品目录、移动应用程序开发、会话管理等。在百度内部业务中也有对 JSON 的操作需求,如手百、度秘、安全实验室等业务。


当前 Redis 中 JSON 存储方案的弊端


当前业务在 Redis 中使用 JSON 时,通常需要将 JSON 序列化为 string 类型存储在 Redis中,该方式有以下问题:

    •  · 非原子更新方式可能导致数据错乱,多个客户端更新导致 JSON 数据覆盖 


    •  · 业务实现成本较高,需要与 Redis 交互多次,业务侧需要额外的 JSON 序列化和反序列化逻辑


    •  · 完整的 JSON 相对较大,网络带宽开销较高,Redis CPU消耗大,请求延迟高,服务易抖动


    •  · 稳定性隐患,请求变大导致 AOF 快速膨胀,也容易导致主从复制缓冲区超限使主从复制失败


即使通过 Hash 来表示 JSON 的方式,使用起来也非常受限,不支持嵌套 JSON,也不支持丰富的 JSON 访问查询。所以开发一款支持 JSON 数据类型的模块能够填补内存文档数据库这一空白,方便业务使用 JSON,扩展百度 Redis 的应用场景,是非常具有价值的事情。


JSON 实现


尽管 RedisLabs JSON 模块是开放源代码的,但其许可协议限制了云厂商的使用,大多数云厂商也是不支持如上模块功能的,唯一支持模块系统的阿里也都是自研的,所以我们只能自己实现一款 JSON 模块。对于内存 JSON 数据库而言,性能是最重要的一个维度,我们使用 C++ 语言开发,性能比社区版本更优。在接口方面,与 RedisLab 的 RedisJSON 模块命令接口保持一致,所以当前开源的 RedisJSON SDK 可以直接用来访问百度 Redis JSON 服务。


BDRP JSON 的实现标准遵循 RFC7159/ECMA-404,更全面地了解 JSON,大家可以阅读下面相关文档:
JSON 模块中实现了 JSON 原生数据结构的存储,可以通过 Key 直接访问 JSON 以及通过 JSON Path 访问任意子元素,并且支持 JSON 的持久化和主从复制。


JSON 操作


用户可以通过 JSON Path 语法选择访问元素,JSON Path 是一种非常方便访问 JSON 中元素的方式,具体大家可以参考: https://goessner.net/articles/JsonPath/
当前 JSON 模块中 JSON Path 支持有以下限制:

    • 仅支持单个 Value 的嵌套访问,不支持范围嵌套访问

支持:book[0].content[2].title
不支持:book[0..2] .store.book[*].author

    • 不支持 script 功能,例如

..book[?(@.isbn)]
..book[?(@.price<10)]

支持对 JSON 子元素进行原子更新操作,比如 JSON.NUMINCRBY、JSON.STRAPPEND、JSON.ARRAPPEND 等命令可以实现数值、字符串和数组的原子更新,这就解决了使用 Redis string 数据类型表示 JSON 时无法实现原子更新的问题。

支持的 JSON 操作命令请参考Baidu Redis JSON 命令


JSON 操作示例


  •  · 通过 JSON Path 操作和访问元素



  •  · String 命令 VS JSON 命令
    例如,对 json: { "num": 5, "arr": [2, 8, 10] } 进行操作,我们希望在 arr 中增加一个元素。

使用 string 数据存储和操作 json

    • 操作麻烦,用户需要 GET 查询、反序列化、修改、序列化、SET 更新等一系列操作

    • 先 GET 再 SET,两次网络请求,资源开销大

    • 不能做到原子更新,arr 中新添加元素可能被覆盖

使用 JSON 命令操作 json,只需一条 JSON.ARRAPPEND 命令



*注:当前 JSON 模块还未平台化,大家想要尝试,可以加如流群:6055819,我们会提供测试环境让大家测试。


性能


BDRP 和 RedisLabs  对一个完整的 JSON 文档读写 QPS 对比,如下图所示,在小 JSON 文件的读写上,BDRP 较 RedisLabs 有 30%+ 的性能提升,在中大 JSON 文件的读操作上有一倍以上的提升。



*注:小 JSON 为 380 字节,中 JSON 为 1.4 KB,大 JSON 为 3.5 KB。另外,RedisLabs RedisJSON 性能没有给出详细数据,只能根据图片进行了估算,其性能测试大家可以参考: https://oss.redis.com/redisjson/performance/

4 总结和规划

当前多模数据库已成为数据库发展的一个新趋势,我们根据 BDRP 集群架构和 Redis 特点设计了 BDRP 多模数据库方案。并且开发了 JSON 模块提供了内存文档数据库的支持,更好地满足业务对 JSON 实时存储和访问的需求,可以作为 MongoDB 这种磁盘文档型数据库的互补,满足简单文档增删改查、高实时性的需求。在接口方面,完全兼容 RedisLabs RedisJSON 模块,方便业务使用。后续,我们也会持续优化和打磨 JSON 模块,根据业务的需求丰富命令,提供更好的体验。


一直以来,业务的需求是我们前行的最大动力,根据业务线上遇到的实际问题,不断提升产品能力,为大家提供更好的 Redis 存储服务,在社区最近发布的 Redis 7.0 RC1 版本中,我们团队与开源社区合作开发了多个重量级功能,如多从库共享复制缓冲区、bypass 内存分配器优化 CoW 开销以及 AOF 注释格式和按时间点回档等功能,这些优化和提升都离不开业务同学给我们的反馈和支持。当前内存多模数据库仍在发展初期,但内存较磁盘有更高的性能、更低的延迟,能够更好的满足业务实时存储的场景,所以我们也正在探索支持更多的数据类型,如 BloomFilter、GIS 和 TimeSeries 等,如果大家对 Redis 新模块的需求和建议,欢迎反馈和交流。