
速度是好事。
坦白说,我们都曾因缓慢的服务或应用程序而感到沮丧。因此,我们非常重视速度对于像Weaviate这样的基础设施产品的重要性,它被用于驱动出色的服务和应用程序。因此,在过去的几个月里,我们一直在开发一个gRPC API并将其集成到我们的解决方案中,从Python客户端库开始。
这些是巨大的变化,但我们相信这些好处是值得的。首先,最新的Weaviate解决方案比我们之前的REST + GraphQL解决方案快得多。请看这些结果(浅色条形:gRPC,深色条形:REST + GraphQL)

这张图表本身就能说明一切(尽管 - 我们将在下面详细说明这一点以及更多内容)。由于这些更改是在底层进行的,因此您甚至不会真正知道哪些调用使用gRPC,哪些调用使用REST或REST + GraphQL。它将仅仅是使用依赖于gRPC的客户端和服务器配对的功能。
但许多人可能想深入了解。您可能想了解它是如何工作的,您需要做些什么才能确保充分利用它,以及您将从中学到多少好处。如果您是这样的人,请继续阅读,让我们告诉您为什么我们对这些变化感到如此兴奋。
什么是gRPC?
gRPC是一个开源框架,由于其灵活性和相对于REST等替代方案的速度,通常被采用用于构建API。
gRPC最初由Google为处理微服务而开发,但现在是开源的,并由云原生计算基金会维护。因此,gRPC是另一个作为网络基础设施生态系统关键组成部分的开源项目。
什么是RPC?
RPC,或“远程过程调用”,可用于从另一个设备远程执行设备上的函数或过程。(了解更多)
为什么使用gRPC?
gRPC在底层使用HTTP/2和协议缓冲区。对于Weaviate,这些属性提供了许多优势,例如更快的序列化、更低的延迟以及流式传输数据的能力。所有这些属性加起来有两个关键优势,即更快的速度和更健壮、更易于维护的代码。
速度
我们Weaviate的人喜欢GraphQL的很多方面。但使用GraphQL的一个主要缺点与它的有效负载有关。一个挑战是将数据编组为JSON,另一个是传输大型有效负载(对于请求和响应)。通过采用gRPC,可以大大减少这些挑战。
首先,gRPC使用协议缓冲区(protobufs)来定义数据结构,例如下图所示,以生成二进制有效负载而不是JSON。由于这些定义用于构建有效负载,并且有效负载是二进制的,因此每个有效负载更小,并且构建速度更快。
message GenerativeSearch {
string single_response_prompt = 1;
string grouped_response_task = 2;
repeated string grouped_properties = 3;
}
此外,gRPC在底层使用HTTP/2,由于其对并发请求和较低开销的支持,它比现有REST API的HTTP/1.1更快。
这些加起来为Weaviate中的gRPC API与当前GraphQL + REST解决方案相比,带来了巨大的速度和可靠性优势。
类型安全
gRPC的另一个优势是其增强的类型安全,这通过在protobufs中显式定义数据结构和类型来实现。这种方法大大减少了在使用GraphQL和JSON时遇到的常见挑战,例如数据类型的不明确性和确保可读性的困难。
在JSON和GraphQL的上下文中,确定数字的正确数据类型(例如,区分整数和浮点数)或解释空属性可能存在问题。在Weaviate中,这可能导致AutoSchema推断不适当的数据类型,从而可能导致数据完整性问题。
此外,解析复杂且深度嵌套的JSON响应,或构建复杂的GraphQL查询,可能会降低开发人员体验并增加出错的风险。这部分也是因为必须符合GraphQL模式的结构。这在Weaviate中实现GroupBy查询和响应等任务时一直是一个挑战。
gRPC通过促进请求和响应的数据结构的定制来解决这些问题。它对严格定义的数据类型的依赖简化了解析过程并提高了可靠性。
本质上,gRPC减轻了与GraphQL和JSON相关的常见陷阱——加上其在调整数据结构方面的灵活性——转化为改进的代码可读性和更流畅的开发体验。最终,我们相信这些优势将有助于创建更健壮、更可靠的产品。
量化gRPC驱动的Weaviate性能提升
我们已经说过gRPC解决方案可以提高速度。但是,它到底快多少?让我们看看两个关键场景——数据摄取和查询吞吐量。
测试设置
这些测试使用两个预向量化(sift1m和DBPedia)数据集,Weaviate版本1.23.9和Weaviate Python客户端版本4.4.4进行。sift1m数据集包含128维向量,DBPedia数据集包含1536维向量。
我们使用配置如下的Azure虚拟机:Standard_D8s_v5,Premium SSD LRS 64,Ubuntu 22.04,docker 25.0.3。测试过程是单线程的。
您可以在此处找到测试代码,包括数据集的链接以及运行测试的说明。
数据摄取
让我们从数据摄取时间的改进开始。下图显示了使用两种不同数据集插入约1M对象所花费的时间的相对改进。

基于gRPC的数据导入显示,对于两个数据集,与基于REST的替代方案相比,时间减少显著。特别是DBPedia导入时间几乎减半,从超过42分钟减少到约23分钟,因为它包含更大的有效负载(比sift数据集更长的向量)。
随着数据集大小的增长,这种改进也会扩大。以目前的速度,插入一亿个对象——一个相对常见的数量——将快32多个小时!
这当然不是什么小事。而且这还不是全部——改进也扩展到了正在运行的数据库中。
查询
查询吞吐量是数据库操作的核心。这里的改进也非常有意义。下图显示了在每个给定场景中使用gRPC和REST + GraphQL可以服务的查询速率。

该图表显示,与REST + GraphQL的结果相比,使用gRPC返回结果的每个查询所需的时间减少了40-70%。这导致可以服务的查询数量显著提高,提高了2.6倍以上。
解释这些结果
查询吞吐量通常以每秒查询数(QPS)来衡量。该图表显示基于10,000个查询的平均值的查询吞吐量值。
不同的设置与向量索引(HNSW索引)参数ef相关。
该参数设置了HNSW搜索算法中使用的动态候选列表的大小,并驱动了速度和准确性之间的权衡。在此测试中,它将影响每个查询的ANN搜索部分。无论如何,您可以看到即使在较高的ef数字下,gRPC驱动的改进也显着。
如您所见,数据摄取和查询吞吐量方面的性能提升都非常显著。我们希望到目前为止,您正在向屏幕大喊,让我们告诉您如何使用它!所以,开始吧
如何在Weaviate中利用gRPC
从您的角度来看,利用新的gRPC API涉及确保可以创建正确的套接字并使用支持它的客户端/服务器解决方案。
第一步:打开 gRPC 消息的端口
首先,必须打开适当的端口以允许 gRPC 消息通过。Weaviate 仍然使用 REST 端点执行各种功能,并且 gRPC 流量通过与 REST 流量不同的套接字发送。通常,服务器端口为 50051,但可能会有所不同。例如,Weaviate Cloud 使用端口 443 以及不同的 URL,为 gRPC 和 REST 流量提供两个不同的套接字。
对于 Docker 用户
如果您使用 Docker 实例化 Weaviate,请检查 gRPC 流量是否已正确转发,例如如下所示。
---
services:
weaviate:
# ...
ports:
- 8080:8080
- 50051:50051
# Note the port mapping above for port 50051
# Remainder of `docker-compose.yml` not shown
...
第二步:支持 gRPC 的 Weaviate 和客户端库
接下来,您需要一个支持 gRPC 的 Weaviate 版本(最低 v1.23.7)和一个匹配的客户端版本。原因是 gRPC 需要匹配的服务器和客户端 protobuf 文件才能进行调用、消息等。因此,任何更新都必须与服务器端和客户端同步。
作为经验法则,我们建议您使用最新的服务器/客户端版本。通过使用最新版本的 Weaviate 服务器和客户端进行构建,您可以自动获得性能改进。
目前,Python 客户端是唯一充分利用 gRPC API 的客户端。但是,我们正在开发其他客户端支持。我们的 JavaScript/TypeScript 客户端正在开发一个重大更新,其他客户端也将陆续推出。
未来我们将就这些主题进行更多介绍 😉。
GraphQL API 呢?
如我们之前所说,我们喜欢 GraphQL。而且我们也知道你们中的许多人也喜欢。我们的客户端库仍然大量依赖 GraphQL API。因此,目前没有弃用现有的 GraphQL API 的计划。
但是,出于上述所有原因,我们正在将我们的客户端迁移到幕后使用 gRPC。因此,随着时间的推移,您首选的 Weaviate 客户端将越来越少地使用 GraphQL API。
结论
将 gRPC 集成到 Weaviate 中标志着我们在提供最快速、最可靠和最强大的基础设施以支持服务和应用程序方面迈出的重要一步。
向 gRPC 的转变代表着在提高 Weaviate 用户的 数据摄取速率和查询吞吐量方面迈出的重大飞跃。随着我们不断完善我们的技术栈,我们鼓励您利用这些进步,确保您的项目受益于最高水平的效率和可靠性。我们期待看到您将使用 Weaviate 提供的令人难以置信的服务和应用程序,现在借助 gRPC 得到了涡轮增压。
准备开始构建了吗?
请查看 快速入门教程,或使用 Weaviate Cloud (WCD) 的免费试用版构建令人惊叹的应用程序。