你在 Netflix 内部追查一个异常账号,可能不只想知道“它是谁”,还要顺着设备、账户和其他关系继续查下去。图越走越深,数据又不断变化,一次查询便可能跨过多台服务器。难点不只是找到答案,还要尽快把答案拼完整。
Netflix Technology Blog 介绍了实时分布式图(Real-Time Distributed Graph,RDG)的查询执行层。它试图在持续变化、拥有十亿级边的图上,应对从高吞吐安全查询到深度个性化追踪的不同请求。Netflix 把“如何返回低于 100 毫秒的响应”列为核心挑战,并为此设计了 gRPC execution API。不过,现有材料全部来自 Netflix 自述,以下规模和延迟数据没有独立测试可交叉验证。
数据存好了,还不等于能用
图用“节点”表示账户、作品或设备,用“边”表示观看、连接等关系。查询图,常常不是查一条记录,而是沿着关系连续走几步。例如,从一个账户找到相关设备,再从设备找到其他账户。
数据量大到一台机器放不下时,节点和边会分散到多台服务器。一次查询可能跨多个分片——也就是被拆开的数据区块。系统必须决定请求发往哪里,并行取回结果,还要处理超时与局部故障。
这正是查询执行层的工作。它把“找哪些节点和关系”转成实际执行任务,分发到存储节点,再汇总答案。对应用开发者来说,这层服务像一位调度员:使用者只需说明要查什么,不必亲自处理数据放在哪台机器上。
Netflix 的 RDG 系列此前已经介绍两块基础设施。第一篇讨论数据处理管线:系统使用 Apache Flink——一种处理持续到来事件的流式计算工具——把事件转换成节点、边等图结构。第二篇讨论存储层。Netflix 称其能处理 billions of nodes and edges,并维持 single-digit-millisecond latency,即个位数毫秒延迟。第三篇才把镜头转向查询:数据进入了系统,也存得足够快之后,怎样让不同业务真正问出问题。
gRPC在这里是一道服务边界
gRPC 是一套服务间调用框架。它通常用 Protocol Buffers 定义消息格式和可调用的方法,并通过 HTTP/2 传输。在 RDG 中,Netflix 为查询层设计了 gRPC execution API。它位于查询客户端和分布式执行服务之间,明确双方可以发送什么请求、返回什么结果。
这个选择值得关注,因为查询层面对的并非一种固定工作负载。安全查询可能数量很大,强调稳定和吞吐;个性化追踪则可能沿关系深入探索,执行路径更长。统一的执行接口,可以让上层应用通过同一道边界提交请求,把跨分片路由、并发执行和结果汇总留给后端。
但“为何押注 gRPC”目前只能讲到这里。供稿片段能确认 Netflix 采用并设计了这套接口,也能说明它承担客户端与执行服务之间的边界;材料没有披露具体设计取舍,不能进一步断言 gRPC 如何改善调度,也不能说它比 REST 或 GraphQL 更快。
真正重要的是把复杂性关在里面
这项工作的看点,不是简单地给图数据库套上一层远程调用接口,而是服务边界如何配合分布式执行。图查询天然可能四处取数。如果每个内部团队都要理解分片位置、并发、超时和故障,系统虽然存下了图,却没有真正降低使用门槛。
查询执行层把这些复杂性集中起来。上层表达“我要找什么”,执行服务负责“去哪里找、怎样同时找、如何收回结果”。对需要同时服务安全和个性化等不同场景的内部平台,这种职责划分本身就很关键。
局限与未知
- Netflix 把 sub-100ms response 写成查询层需要解决的挑战;现有片段没有证明系统已在各种负载下稳定达到这一指标。
- “十亿级节点和边”“个位数毫秒延迟”均为 Netflix 自述,未给出负载规模、延迟分位数、测试条件或端到端口径。
- 材料没有提供 gRPC 接口定义、分布式执行流程、故障处理细节,也没有与 REST、GraphQL 等方案进行对照,因此不足以完整回答“为什么选择 gRPC”。