4.3 路由与查询代理


4.3 路由与查询代理:把请求送对门

路由决定"这个请求该敲哪扇门",查询代理则是那扇门前帮用户把多片结果拼成一份完整答案的接待员。本节把"按分区键直连"和"汇总合并结果"两种路由模式讲清,并用一场跨片查询演练说明代理为什么要"尽量本地执行、只搬必要的部分"。

学习目标

阅读完本节,你应当能够:

  1. 解释路由如何根据分区键把请求送到正确分片。
  2. 区分"单点路由"与"汇总合并"两种模式并说清各自适用场景。
  3. 走一遍跨片查询:怎么避免把整片数据都搬上网。

一场送错方的调度事故

数据分好了,但如果来一个请求派不过去,前面全白搭。设想一个电商库,请求"查订单 T1001 的信息"。假设分片键是用户 id、T1001 属于某用户被哈希到节点 3,可路由层不清楚这个,随便把请求发给节点 1,节点 1 查不到、只好去问元数据、再转手——这一来一回,延迟翻倍,还白白消耗一次网络。路由层的职责,就是在前面把"该敲哪扇门"定准,别让用户在门口来回找路。

一、路由的核心:靠分区键查到门牌

路由能定准,靠的是「请求携带的分区键 + 元数据里的分片映射」。如果你查的是单个分片键(比如按用户 id),路由直接用元数据定位到那片节点,把请求直发过去——这叫点路由,快、几乎不跨片。如果你查的没有分区键条件(比如"全网所有 30 天未回访的用户"),路由就变成广播,把请求发给所有分片去查,再汇总。广播是"不得已而为之",每广播一次,全网节点就要各自出力一遍。

真正的分布式查询往往要混合两者:先按分区键定位到相关分片(点路由),再在相关分片内本地过滤,最后把"命中结果"汇合。这里的关键纪律是——先过滤、后搬移,只搬必要行,不搬整片

二、查询代理:把多片答案拼成一份

当查询跨多片时,需要一个角色在一头把各片返回的片段拼起来。这就是查询代理/汇总节点的活。它会:收集各片返回的子结果 → 按排序键归并 → 做整表聚合(求和、取 topN、去重)→ 把最终一份答案交还客户端。很多系统这里会做小优化:先在每片内各算一次 topK,代理只归并这些"候选",从而把网络搬运压到最小。

一次跨三片查询的完整旅程

三、路由模式的取舍

中心化路由:由一个集中的路由/代理节点统一调度,实现直观、好排查,但它本身可能成为流量单点——路由节点带宽、CPU 一旦打满,整个系统受限。无中心/直连路由:请求直接拿着分区键去敲元数据指出的那片节点,绕开集中代理,扩展性更好,但要各客户端都理解分片规则,迁移时兼容性工作重。工程上往往是"中心化放轻量的代理,复杂的全局路由交给元数据与客户端缓存"两种各司其职。

四、排错:当"查个东西回来很慢"时

慢不一定在数据本身,先排在路由。按四步排查:一是看这把查询是不是广播——广播查到全网,慢很正常,试着给它加分区键条件;二是看代理有没有把整片数据搬上网——看汇总前的子查询是不是只取了必要的列与行;三是看元数据有没有僵住——路由查元数据如果回到老版本的分片映射,会把请求送错门;四是看热点分片——某片被顶爆,路由把大量请求都导过去,其余片闲着。四步排查完,慢查询大多有眉目。

五、路由键选错了,路由再准也是白搭

路由层能定多准,一半取决于分区键挑得好不好。给你一个选键演练:折扣券系统的券表,需求是"按用户 id 查他名下所有券",同时也要偶尔"按券码查一张券归属"。前者是最常见的读写入口,后者是低频。如果你把分区键定为券码,那"查某用户全部券"就必然全网广播——因为同一用户的券散在所有片里;反之定为用户 id,这个高频查询就是干净的点路由,低频的"按券码查"才需要广播或换一种思路(比如给券码再建一张映射表)。判断口诀是:把最高频的查询条件设成分区键,把低频查询委曲成广播或旁路表。 这个选对/选错的差别,直接决定你系统八成请求到底在点路由还是广播,价值远大于路由实现本身那点技巧。

六、一张路由模式对号表

把两类来回念熟,遇到场景直接对号:

路由模式 代表性动作 最大优点 最大短板 典型适用
点路由 按分区键直发一片 快、几乎不跨 只在有分区键时可用 单用户读写
广播路由 全网都查再汇总 支持无键全表查询 全片出力、开销大 低频离线扫描
中心化代理 集中调度+归并 直观好排查 路由节点成单点 中小集群
直连路由 客户端自己算门牌 无单点、可扩展 各端都要懂分片规则 对扩展敏感的集群

把它贴在屏幕边,当你再看到"为什么这里要用广播""为什么加了个代理"这类疑问时,表格里基本都能找到答案。

七、一张路由排查的现场路演

纸上四步不如现场排一遍。假设线上有一句"查全网近 30 天未回访客户"的 SQL,导回很慢,你按顺序走:

  • 第一站,查广播:EXPLAIN 一看,这条查询没有分区键条件,网关走了广播,全网节点各自扫一遍——慢的根源先确认了。
  • 第二站,看上没上大件的搬:观察汇总行数,发现它把每个节点的"客户全列"都搬上来归并了——该只搬命中的列,于是给它加上"只要 user_id 和时间戳"的列裁剪。
  • 第三站,看元数据僵没僵:确认元数据的分片映射是最新版本,若退回旧版,路由会把请求送错门。
  • 第四站,看热点分片:如果这一个月有某片特别忙,路由把大量请求都导过去,就得考虑再加一片分流。

排完你会发现,这条慢查询的"慢"九成不是硬盘慢,而是广播加整列搬运叠加出来的。把广播换成"按活跃客户分布先拆小批"、把搬的列削窄,往往就能从分钟级回到秒级。这个路演的每一步都是上一节的四个慢查询排查点的落地,值得你在真实环境里也在心里走一遍。

本节要点回顾

  • 路由靠分区键+元数据定门:点路由快,广播是不得已。
  • 先过滤后搬移:只搬命中的行,不搬整片,是查询代理的纪律。
  • 中心化 vs 直连:一个直观有单点、一个自由要懂规则。
  • 慢查询先在路由:广播、整片搬运、元数据僵硬、热点分片四查。

路由能定准门,全靠元数据那张"数据在哪儿"的电话簿。可这本电话簿本身存哪、怎么在集群里保持一致、崩溃了怎么重建?下一节 4.4 专门讲元数据管理。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U