注意:本文已编辑,以反映 Redis JSON 2.0 和 Redis Search 2.2 的正式发布情况
2019年7月,我们发布了由 Redis JSON 和 Redis Search 组合驱动的实时文档存储,具备原生索引、查询和全文搜索功能,并进行了内测。在内测期间,我们极大地提高了该产品的性能和稳定性,简化了打包以更易于上手,并增强了驱动程序支持。今天,我们很高兴地宣布,RedisJSON/Redis JSON(由 RediSearch/Redis Search 提供支持)现已进行公测并正式可用,且可在我们的云服务中使用。
Redis JSON 是一个源代码可用的实时文档存储,允许您通过使用动态、分层的 JSON 文档模型构建现代应用程序。我们的早期客户已开始将其应用于各种数据栈架构场景:作为缓存、作为查询加速器以加速热点,以及作为主数据库。我们在开发者社区中也看到越来越多的采用。仅在过去3个月, Redis JSON 和 Redis Search 的Docker拉取量总计达到一百万次。
Redis 连续第五年成为最受欢迎的数据库(Stack Overflow 调查),我们希望 RedisJSON 具备社区所熟悉的 Redis 的简单性、可伸缩性,最重要的是速度,因此我们从头开始专门构建了它。鉴于性能是 Redis 的关键优势,我们决定检查它与之前版本以及市场上同类产品的表现。为了对 RedisJSON、MongoDB 和 ElasticSearch 进行公平比较,我们依赖于行业标准 Yahoo! Cloud Serving Benchmark (YCSB)。
每种产品都有不同的架构和不同的功能集。对于给定的用例,一种产品可能比另一种更适合。完全透明地说,我们知道 MongoDB 和 ElasticSearch 已经存在更长时间了。由您,开发者,来选择解决手头问题的正确工具。我们在这篇博客中为基准测试结果添加了大量上下文,因为有许多变量在起作用,可能与您的用例不同。我们发现:
此外,在负载下,Redis JSON 在更高百分位数下的读取、写入和搜索延迟远比 ElasticSearch 和 MongoDB 更稳定。Redis JSON 在增加写入比例时也能处理越来越高的整体吞吐量,而 ElasticSearch 在写入比例增加时则降低了可处理的整体吞吐量。
如前所述,Redis Search 和 Redis JSON 在开发时非常重视性能。在每个版本中,我们都希望确保您能够体验到稳定快速的产品。无论是寻找提高模块效率的空间,还是进行性能回归调查,我们都依赖于一个全自动框架,对每次代码提交到仓库都运行端到端性能测试(详情在此),并在需要时通过附加遥测和分析工具/探测器进行性能调查。
这使我们能够以一种简洁有条理的方式,在每个版本中不断提升性能。特别是对于 Redis Search,结合吞吐量和延迟的改进,2.2 版本在数据摄取和查询性能方面都比 2.0 版本快达 1.7 倍。
下面的两个图表显示了运行纽约出租车基准测试(详情在此)的结果。该基准测试测量了摄取大约 1200 万文档(2015年纽约黄色出租车完成的乘车记录)时观察到的吞吐量和延迟。
从这些图表中可以看出,Redis Search 的每个新版本都带来了显著的性能提升。
为了评估搜索性能,我们索引了 590 万维基百科摘要。然后运行了一系列全文搜索查询(详情在此)。
如上所示,通过从 v2.0 升级到 v2.2,您将受益于更快的写入/读取/搜索(延迟图表),从而提高运行 Search 和 JSON 的相同硬件上可实现的吞吐量。
为了评估 Redis JSON 的性能,我们决定将其与 MongoDB 和 ElasticSearch 进行基准测试对比。在谈论文档存储时,这些解决方案经常会被提及。它们都可在本地部署,可在云端使用,提供专业支持,并致力于提供可伸缩性和性能。当然,一切取决于用例,将来我们计划将此基准测试扩展到其他提供类似功能范围的供应商。让我们看看我们的方法。
我们使用了成熟的 YCSB,它能够基于常见工作负载评估不同的产品,测量直到饱和时的延迟/吞吐量曲线。除了 CRUD YCSB 操作外,我们还添加了一个双词搜索操作,专门帮助开发者、系统架构师和 DevOps 从业者为他们的用例找到最佳的搜索引擎。生成的文档大小约为 500 字节,每个解决方案都创建一个二级索引,索引一个文本字段和一个数字字段。
对于所有测试的解决方案,都使用了最新可用的稳定 OSS 版本:MongoDB v5.0.3、ElasticSearch 7.15 和 Redis JSON (Redis Search 2.2 + Redis JSON 2.0)。
我们在通过我们的基准测试基础设施配置的 Amazon Web Services 实例上运行了基准测试。这三种解决方案都是分布式数据库,在生产环境中通常以分布式方式使用。这就是为什么所有产品都使用了相同的通用型 m5d.8xlarge 虚拟机,带有本地 SSD,每个设置由四个虚拟机组成:一个客户端 + 三个数据库服务器。基准测试客户端和数据库服务器都在独立的 m5d.8xlarge 实例上运行,这些实例在最佳网络条件下放置,它们密集地打包在一个可用区内,实现了稳态分析所需的低延迟和稳定的网络性能。
测试在三节点集群上执行,部署详情如下:
除了主要的基准测试/性能分析场景外,我们还运行了网络、内存、CPU和I/O的基线基准测试,以了解底层的网络和虚拟机特性。在整个基准测试过程中,网络性能保持在测量限制以下,无论是在带宽还是在PPS(每秒数据包数)方面,以产生稳定、超低延迟的网络传输(每数据包 p99 < 100微秒)。
我们将首先提供每个独立操作的性能 [100%写入] 和 [100%读取],最后进行一组混合工作负载测试,以模拟真实应用场景。
从下面的图表中可以看出,此基准测试显示 Redis JSON 的数据摄取速度比 ElasticSearch 快 8.8 倍,比 MongoDB 快 1.8 倍,同时保持每操作亚毫秒级延迟。值得注意的是,99%对 Redis 的请求在不到 1.5 毫秒内完成。
此外,Redis JSON 是我们在测试中唯一一个在每次写入时原子性更新索引的解决方案。这意味着任何后续搜索查询都能找到更新后的文档。ElasticSearch 不具备这种细粒度能力;它将摄取文档放入内部队列,此队列由服务器刷新(不受客户端控制),每 N 个文档或每 M 秒刷新一次。他们称这种方法为接近实时(NRT)。Apache Lucene 库(为 ElasticSearch 实现了全文搜索能力)设计用于快速搜索,但索引过程复杂且繁重。如这些 WRITE 基准测试图所示,ElasticSearch 因此“按设计”的限制付出了巨大代价。
结合延迟和吞吐量改进,在独立写入方面,Redis JSON 比 MongoDB 快 5.4 倍,比 ElasticSearch 快 >200 倍。
类似于写入,我们可以观察到 Redis 在读取方面表现最佳,读取次数是 ElasticSearch 的 15.8 倍以上,是 MongoDB 的 2.8 倍以上,同时在整个延迟范围内保持亚毫秒级延迟,如下表所示。
结合延迟和吞吐量改进,在独立读取方面,Redis JSON 比 MongoDB 快 12.7 倍,比 ElasticSearch 快 >500 倍。
现实世界的应用工作负载几乎总是读、写和搜索查询的混合。因此,了解当接近饱和时产生的混合工作负载吞吐量曲线更加重要。
作为起点,我们考虑了 65% 搜索和 35% 读取的场景,这代表了常见的真实世界场景,其中我们进行更多搜索/查询而非直接读取。最初 65% 搜索、35% 读取和 0% 更新的组合也导致 ElasticSearch 和 Redis JSON 的吞吐量相等。尽管如此,YCSB 工作负载允许您指定搜索/读取/更新的比例以匹配您的需求。
“搜索性能”可以指代不同类型的搜索,例如“匹配查询搜索”、“分面搜索”、“模糊搜索”等。我们在 YCSB 中首次添加的搜索工作负载仅专注于“匹配查询搜索”,模拟分页的双词查询匹配,按数字字段排序。“匹配查询搜索”是任何支持搜索能力的供应商进行搜索分析的起点,因此,每个 YCSB 支持的数据库/驱动程序都应该能够轻松地在其基准测试驱动程序中启用此功能。
在每次测试变体中,我们混合增加了 10% 写入,并以相同比例减少了搜索和读取的百分比。这些测试变体的目标是了解每个产品如何处理数据的实时更新,我们认为这是事实上的架构目标,即写入会立即提交到索引,读取始终是最新的。
从图表中可以看出,持续更新数据并增加 Redis JSON 上的写入比例不影响读取或搜索性能,并增加整体吞吐量。数据产生的更新越多,ElasticSearch 性能受影响越大,最终导致读取和搜索变慢。
查看 ElasticSearch 从 0% 更新到 50% 更新的可实现操作数/秒演变,我们注意到在 0% 更新基准测试中始于 1万操作数/秒,受影响严重,操作数/秒减少达 5 倍,在 50% 更新率基准测试中仅达到 2.1千操作数/秒。
类似于我们在上面的独立操作基准测试中观察到的情况,MongoDB 搜索性能比 Redis JSON 和 ElasticSearch 慢了两个数量级,MongoDB 的最高整体吞吐量达到 424 操作数/秒,而 Redis JSON 最高可达 1.6万操作数/秒。
最后,对于混合工作负载,Redis JSON 可实现的操作数/秒是 MongoDB 的 50.8 倍以上,是 ElasticSearch 的 7 倍以上。如果我们集中分析每种操作类型的延迟在混合工作负载期间的表现,与 MongoDB 相比,Redis JSON 可实现低至 91 倍的延迟,与 ElasticSearch 相比低 23.7 倍的延迟。
类似于测量直到饱和时的吞吐量曲线,在所有解决方案共同的可持续负载下进行完整的延迟分析也同样重要。这将帮助您了解在延迟方面对于所有发出的操作,哪个解决方案最稳定,以及受应用逻辑(例如,Elastic查询缓存未命中)引发的延迟峰值影响最小的方案。如果您想深入了解为什么我们应该这样做,Gil Tene 提供了关于延迟测量的注意事项的深度概述。
参考上一节的吞吐量图表,着重于包含所有三个操作的 10% 更新基准测试,我们进行了两种不同的可持续负载变体测试:
在下面的第一张图表中,展示了从 p0 到 p9999 的百分位数,显然 MongoDB 在每次搜索时间上性能远逊于 Elastic 和 Redis JSON。此外,着重比较 ElasticSearch 和 Redis JSON,ElasticSearch 明显更容易出现更高延迟,很可能是由垃圾回收(GC)触发或搜索查询缓存未命中引起的。Redis JSON 的 p99 低于 2.61 毫秒,相比之下,ElasticSearch 的搜索 p99 达到了 10.28 毫秒。
在下面的读取和更新图表中,我们可以看到 Redis JSON 在所有延迟范围内表现最佳,其次是 MongoDB 和 ElasticSearch。
Redis JSON 是唯一在所有分析的延迟百分位数中保持亚毫秒级延迟的解决方案。在 p99 时,Redis JSON 的延迟为 0.23 毫秒,其次是 MongoDB,5.01 毫秒,和 ElasticSearch,10.49 毫秒。
在写入方面,MongoDB 和 Redis JSON 即使在 p99 时也保持亚毫秒级延迟。另一方面,ElasticSearch 显示出高尾延迟(>10 毫秒),很可能与导致 ElasticSearch 搜索延迟峰值的原因(GC)相同。
仅关注 ElasticSearch 和 Redis JSON,同时保持 6000 操作数/秒的可持续负载,我们可以观察到读取和更新模式与在 250 操作数/秒下进行的分析相同。Redis JSON 是更稳定的解决方案,p99 读取延迟为 3 毫秒,相比之下,ElasticSearch 的 p99 读取延迟为 162 毫秒。
在更新方面,Redis JSON 保持 p99 为 3 毫秒,相比之下,ElasticSearch 的 p99 为 167 毫秒。
着重关注搜索操作,ElasticSearch 和 Redis JSON 的 p50 延迟起始于个位数毫秒(Redis JSON 的 p50 为 1.13 毫秒,ElasticSearch 的 p50 为 2.79 毫秒),而 ElasticSearch 在更高百分位数上因 GC 触发和查询缓存未命中而付出代价,这在 ≥ p90 百分位数上清晰可见。
Redis JSON 保持 p99 低于 33 毫秒,相比之下,ElasticSearch 的 p99 百分位数高达 163 毫秒,是 Redis JSON 的 5 倍。
我们非常重视性能,希望邀请其他合作伙伴和社区成员参与协作,共同创建针对搜索和文档工作负载的标准基准测试定义。Redis JSON 和 Redis Search 的性能数据和工具将在未来几个月向社区开放。
类似于上面的自管(本地部署)基准测试数据,我们还将在未来几周内对 Redis Cloud 的DBaaS性能进行基准测试,与其他同类云文档数据库进行对比。除了基准测试外,我们还发布了一篇技术博客,关于如何使用 Redis JSON 构建一个快速、灵活且可搜索的产品目录。
最后,我们还扩展了 Redis Search,增加了向量相似性搜索,现已处于内测阶段。
要开始使用 Redis JSON,您可以在所有区域的 Redis Cloud 上创建免费数据库。或者,您可以使用Redis JSON Docker容器。我们更新了redis.io上的文档,以便轻松开始使用查询和搜索功能。此外,正如我们在最近的客户端库公告中提到的,这里列出了几种流行语言的客户端驱动程序,以帮助您开始。
Redis JSON | |
Node.js | node-redis |
Java | Jedis |
.NET | NRedisJSON NRediSearch |
Python | redis-py |
这里有一些帮助您入门的链接
* – RedisJSON* 和 RediSearch 命名约定是历史遗留问题,* 可以忽略