跳转至

Vertica 客户端连接路由(IP、Workload、用户角色)配置与实战

作者:JiangChong | 撰写时间:2026年11月

适用场景:Vertica 数据库需要把客户端连接按来源 IP、workload、用户或角色路由到不同节点/子集群;其中 workload 路由和用户/角色路由依赖 Eon 子集群。

关联文章:Vertica 客户端连接负载均衡配置、MPP 资源管理与工作负载隔离、Vertica 多租户实现最佳实践、Vertica 访问控制最佳实践、Vertica 低延迟优化最佳实践

相关系统表/版本说明:WORKLOAD_ROUTING_RULES、ROUTING_RULES、LOAD_BALANCE_GROUPS、NETWORK_ADDRESSES、SUBCLUSTERS、NODES、SESSIONS;23.3.x New Features、24.1.x New Features、24.2.x New Features

理解全文脉络

本文按三种连接路由方式组织:1.4 IP 路由(概览,完整排错见 Vertica 客户端连接负载均衡配置)、1.5 Workload 路由(本文重点)、1.6 用户/角色路由(24.1+)。之后第 2-9 节以 workload 路由为主线,给出监控、定位、配置、案例和 Bug 修复记录。只关心配置的读者读第 1 节(三种方式概览和配置入口),workload 的完整配置见第 4 节;正在排查“规则建了但不生效”的读者按第 2、3、7 节执行。


1. 原理理解

1.1 为什么 Eon 需要“连接路由”

传统单机数据库或共享磁盘数据库里,客户端连到哪个实例,查询就在哪个实例执行,通常没有“把连接定向到另一组计算节点”的需求。Eon 模式把计算和存储拆开:所有子集群共享同一份公共存储,但每个子集群有自己的计算节点。资源池只能做逻辑隔离——限制内存和并发,查询仍然在同一组节点上争抢 CPU、网络和磁盘 I/O;子集群才能做物理隔离。

隔离层级 隔离内容 适用模式 成本
资源池 内存、并发槽位 Enterprise / Eon 零硬件成本
子集群 CPU、内存、网络、磁盘 I/O Eon 需要额外计算节点

工作负载路由解决的是“连接落到哪个子集群”,不是“单条 SQL 用多少资源”。 一旦连接被路由到某个子集群,这个会话里的查询就在该子集群的执行节点上运行;它不是按每条 SQL 动态切换子集群的机制。

IP 路由不依赖 Eon 子集群,也可以用于 Enterprise 模式;1.4 会单独说明。

1.2 连接节点与执行节点

官方文档把参与路由的节点分成两个角色:

  • Connection node(连接节点):客户端首先连到的节点,通常位于默认子集群。它不一定是最终执行查询的节点,而是充当客户端与执行节点之间的代理。
  • Execution node(执行节点):目标子集群中真正执行查询的节点。

工作过程可以简化为:

flowchart TD
    A["客户端<br/>指定 workload 或启用角色"] --> B["Connection node<br/>默认子集群"]
    B -->|"匹配 WORKLOAD_ROUTING_RULES"| C["Execution node<br/>目标子集群"]
    C -->|"查询结果"| B
    B -->|"查询结果"| A

关键理解:路由发生在连接建立阶段,客户端不需要知道目标子集群的 IP 或名称,只需要知道自己的 workload(或使用正确的用户/角色)。 如果客户端没有指定 workload,也没有命中角色规则,连接通常留在默认子集群,专用子集群就会闲置。

上图是 workload/用户角色路由的“连接节点代理”路径;IP 路由是“客户端先被重定向到目标节点”,不经过连接节点代理。

1.3 三种路由方式对比

方式 路由依据 需要的对象 引入版本 典型场景
IP 路由 客户端源 IP 地址段 LOAD BALANCE GROUP + ROUTING RULE 早期版本 按办公网/应用网段固定分流
Workload 路由 客户端连接时指定的 workload WORKLOAD_ROUTING_RULES 23.3 ETL、BI、报表按任务类型分流
用户/角色路由 连接用户,或会话中已启用的角色 WORKLOAD_ROUTING_RULES + USAGE 授权 24.1 多租户、按团队/角色隔离

IP 路由和 workload 路由不是同一个对象:前者存于 v_catalog.routing_rules,后者存于 v_catalog.workload_routing_rules。不要假设两套规则会自动叠加;同时存在时,应以实际会话的 SHOW WORKLOAD、v_monitor.sessions 和 vertica.log 路由日志确认最终落点。

常见误解:工作负载路由不需要在客户端和服务端同时“开启负载均衡”。 客户端 ConnectionLoadBalance=1 和服务端 SET_LOAD_BALANCE_POLICY('ROUNDROBIN') 是原生连接负载均衡的开关;工作负载路由的必要条件只有两个:DBA 创建路由规则,客户端指定 workload(或启用角色)。原生负载均衡可以额外启用,用来分散初始连接,但不是工作负载路由的前置条件。EnableInteriorLoadBalancing 控制的是子集群内部连接分摊,也不是跨子集群 workload 路由的开关。

1.4 IP 路由(概览)

IP 路由按客户端源 IP 地址段分流:客户端首先连到的节点根据 ROUTING_RULES 匹配源 IP,把连接重定向到 LOAD BALANCE GROUP 中的节点。它不区分 workload、用户或角色,适合“办公网/应用网段固定分流”的场景。

配置步骤:

  1. 服务端创建负载均衡组和路由规则(需要超级用户):
CREATE LOAD BALANCE GROUP lbg_analytics
  WITH SUBCLUSTER sc_analytics FILTER '0.0.0.0/0';

CREATE ROUTING RULE rr_analytics
  ROUTE '10.1.0.0/16' TO lbg_analytics;
  1. 客户端显式选择加入:vsql 用 -C,JDBC/ODBC 用 ConnectionLoadBalance=1。客户端不 opt-in,匹配到规则也不会被重定向。

  2. (可选)如果希望在无规则匹配时回退到经典集群级负载均衡,再开启(需要超级用户):

SELECT SET_LOAD_BALANCE_POLICY('ROUNDROBIN');

判定顺序:先匹配 ROUTING_RULES;无匹配时才检查经典策略;再回退到 Eon 默认的子集群内部负载均衡。SET_LOAD_BALANCE_POLICY 不是 IP 路由规则生效的前提。

验证路由决策:

SELECT DESCRIBE_LOAD_BALANCE_DECISION('10.1.2.3');

输出会显示匹配的规则、目标负载均衡组、候选地址和最终重定向节点;没有匹配规则时,会回退到经典负载均衡或由当前节点直接处理。

监控对象: v_catalog.load_balance_groups、v_catalog.routing_rules、v_catalog.network_addresses。完整排错见 Vertica 客户端连接负载均衡配置。

1.5 Workload 路由(本文重点)

Workload 路由按客户端连接时指定的 workload 匹配 WORKLOAD_ROUTING_RULES,由连接节点代理到目标子集群。客户端不需要 ConnectionLoadBalance,只需要在连接串中带 workload(或使用 SET SESSION WORKLOAD)。 适合 ETL、BI、报表等按任务类型分流。

核心配置:

CREATE ROUTING RULE ROUTE WORKLOAD etl TO SUBCLUSTER sc_etl;

客户端连接参数使用 workload=etl(JDBC/ODBC/Python 等)或 vsql --workload etl。监控、排错、案例和完整配置见第 2-9 节。

1.6 用户/角色路由(24.1+)

用户/角色路由仍使用 WORKLOAD_ROUTING_RULES,区别是匹配依据从“客户端指定 workload”变成“连接用户或已启用角色”。管理员需要把 workload 的 USAGE 授予用户或角色;客户端以该用户连接,或在会话中启用对应角色。

GRANT USAGE ON WORKLOAD analytics TO analytics_role;
ALTER USER analytics_user DEFAULT ROLE analytics_role;

用户也可以在会话中执行 SET ROLE analytics_role;。多条规则命中时按 PRIORITY 取最高,SHOW AVAILABLE WORKLOADS 可查看当前用户/角色可用的 workload。详细授权和优先级见 §3.5、§4.2。

版本差异:24.1 文档中该语句写作 GRANT USAGE ON ROUTING RULE ...;v26.2 SQL 参考中为 GRANT USAGE ON WORKLOAD ...。

1.7 版本演进(workload / 用户角色)

版本 能力变化 对本文的影响
23.3 引入 Workload Routing:客户端通过 --workload 等参数指定 workload,连接按 workload 路由到子集群 只能用 workload 维度路由,没有用户/角色路由和 PRIORITY
24.1 新增按用户/角色路由、GRANT USAGE、PRIORITY、SHOW AVAILABLE WORKLOADS;WORKLOAD_ROUTING_RULES 新增 PRIORITY 列 可以做多租户、按角色分流和优先级治理
24.2 ALTER ROUTING RULE 支持动态增删子集群 调整目标子集群不必删除重建规则
26.2 当前官方文档基线;GRANT (workload) 使用 GRANT USAGE ON WORKLOAD ... 语法 本文 SQL 以 v26.2 文档为准

版本判断方法:先执行 SELECT version();。如果版本低于 23.3,不能使用工作负载路由;如果低于 24.1,不能使用用户/角色路由和 PRIORITY。IP 路由和原生连接负载均衡属于更早的经典能力,版本判断以 ROUTING_RULES 字段矩阵为准。

1.8 路由失败来源总表

可能来源 典型现象 优先检查
客户端没有指定 workload SHOW WORKLOAD 为空,连接留在默认子集群 客户端连接串/驱动参数
workload 名称不一致 规则存在,但客户端 workload 拼写不同 WORKLOAD_ROUTING_RULES.WORKLOAD
规则不存在 客户端指定了 workload,但没有匹配规则 v_catalog.workload_routing_rules
规则指向的子集群不存在或已改名 连接未路由,或路由到错误目标 SUBCLUSTER_NAME 与 v_catalog.subclusters
目标子集群节点 DOWN/READONLY 连接成功但查询失败或变慢 v_catalog.nodes 的 node_state、is_readonly
用户/角色没有 USAGE 授权 SHOW AVAILABLE WORKLOADS 看不到目标 workload GRANT USAGE ON WORKLOAD
角色未启用/默认角色未设置 按角色配置的规则不生效 SET ROLE、ALTER USER ... DEFAULT ROLE
多条规则优先级相同 同一用户被随机路由到不同子集群 PRIORITY、SHOW WORKLOAD
客户端驱动不支持 workload 参数 连接串写了参数但不生效 驱动版本与连接参数
连接池复用旧连接 新配置只对新建连接生效,老连接仍走旧路径 连接池生命周期、maxLifetime
IP 路由与 workload 路由同时存在 实际落点与预期不一致 routing_rules + workload_routing_rules
IP 路由未生效 客户端连接未按源 IP 重定向 客户端是否 ConnectionLoadBalance=1 或 -C;routing_rules/load_balance_groups 是否存在
无匹配规则时经典回退未生效 连接落到当前节点 服务端 SET_LOAD_BALANCE_POLICY 是否为 NONE
IP 路由目标组无可用地址 连接回落到当前节点或报错 v_catalog.load_balance_groups、v_catalog.network_addresses、目标节点是否 DOWN
版本/模式不匹配 功能不存在,或没有子集群可路由 SELECT version();、子集群拓扑

2. 系统级监控

第 2-9 节以 workload 路由为主线;IP 路由的完整排错见 Vertica 客户端连接负载均衡配置,用户/角色路由的配置要点见 §1.6、§3.5、§4.2。

2.1 查看工作负载路由规则

先看数据库里到底有哪些规则、分别指向哪些子集群。v_catalog.workload_routing_rules 记录 workload 到子集群的映射:

SELECT workload,
       subcluster_name,
       priority
FROM v_catalog.workload_routing_rules
ORDER BY workload, priority DESC;

如何解读结果:

  • 返回 0 行:数据库里没有工作负载路由规则,客户端即使指定 workload 也不会被路由。
  • 同一个 workload 有多行:一条规则可以指向多个子集群,连接会在这些子集群之间随机选择;这不是重复配置。
  • subcluster_name 不在 v_catalog.subclusters 中:规则指向了不存在或已改名的子集群,属于悬空规则。
  • priority 列报“不存在”:当前版本低于 24.1,去掉 priority 列再查。

2.2 查看节点与子集群状态

规则正确不代表目标可用。路由目标子集群的节点必须处于可服务状态:

SELECT node_name,
       node_state,
       is_primary,
       is_readonly,
       subcluster_name,
       node_type
FROM v_catalog.nodes
ORDER BY subcluster_name, node_name;

如何解读结果:

  • node_state 不是 UP:目标子集群有节点不可用;如果该子集群所有节点都不在 UP,连接无法正常执行。
  • is_readonly = true:节点处于只读状态。常见于主子集群被关闭、降级或恢复过程中;此时路由过去也写不了数据。
  • 某个子集群的所有节点 is_primary = false:该子集群不是主子集群,读写能力受数据库状态影响,需要结合 is_readonly 判断。
  • subcluster_name 与规则中的目标不一致:先确认子集群是否被重命名或重建。

2.3 查看子集群节点数

v_catalog.subclusters 按“子集群 × 节点”展开。可以用它确认目标子集群是否存在、规模是否符合预期:

SELECT subcluster_name,
       COUNT(*) AS node_count
FROM v_catalog.subclusters
GROUP BY subcluster_name
ORDER BY subcluster_name;

如何解读结果:

  • 目标子集群不在结果中:规则目标写错,或子集群已被删除。
  • 目标子集群 node_count 明显小于规划值:可能有节点未加入或已下线,路由过去后并发能力不足。
  • 默认子集群节点数很多、专用子集群很少:检查是否仍有大量客户端没有带 workload,全部留在默认子集群。

2.4 查看 IP 路由规则(对比用)

如果数据库同时存在 IP 路由,先确认它是否会把连接导向别的目标:

SELECT name,
       source_address,
       destination_name
FROM v_catalog.routing_rules
ORDER BY name;

如何解读结果:

  • routing_rules 有记录、workload_routing_rules 也有记录:两套机制都可能影响连接落点,必须结合客户端源 IP 和 workload 一起判断。
  • destination_name 指向的负载均衡组不存在或成员已变更:IP 路由可能出现类似“连到已移出子集群的节点”的问题,参见第 5 节真实案例。
  • 只关心 workload 路由时,routing_rules 为空并不代表配置错误;它只说明没有 IP 路由规则。

2.5 查看用户会话落点

确认某个应用用户的连接实际落在哪些节点。v_monitor.sessions 的 node_name 通常是会话的连接节点,不一定是执行节点:

SELECT user_name,
       node_name,
       client_hostname,
       login_timestamp
FROM v_monitor.sessions
WHERE user_name = 'analytics_user'
ORDER BY login_timestamp DESC;

如何解读结果:

  • 所有会话都集中在同一个 node_name:客户端可能没有启用连接负载均衡,或者连接池只建立了一条长连接;先解决连接分布,再谈子集群路由。
  • 会话分散在多个连接节点:说明客户端侧负载均衡在工作;workload 路由会在连接节点之后把会话代理到目标子集群。
  • 找不到目标用户:确认连接使用的数据库用户是否正确,以及会话是否已经被连接池复用。

2.6 客户端侧自检命令

在应用的数据库会话里执行:

SHOW WORKLOAD;

输出会显示当前会话的 workload。为空或不是预期值,说明客户端没有正确设置。

SHOW AVAILABLE WORKLOADS;

输出当前用户及其已启用角色可用的 workload 列表(24.1+)。列表为空,通常意味着没有 USAGE 授权,或角色未启用。


3. 逐步定位根因

3.1 第 1 步:确认版本与模式

先确认数据库版本和子集群拓扑,避免在错误的前提下排查:

SELECT version();

判断:

  • 版本低于 23.3:没有工作负载路由,只能使用 IP 路由或升级。
  • 版本低于 24.1:不能用用户/角色路由和 PRIORITY;如果配置了相关语法,会直接报错。
  • 数据库没有子集群:工作负载路由没有目标可路由,先检查 v_catalog.subclusters。

如果版本/模式不满足,后面的步骤没有意义,直接进入升级或架构调整评估。

3.2 第 2 步:确认客户端是否带上 workload

在出问题的应用会话里执行 SHOW WORKLOAD;。

判断:

  • 返回空或 NONE:客户端没有显式指定 workload。检查连接串、驱动参数、连接池初始化配置。
  • 返回了预期 workload,但连接没有落到目标子集群:进入第 3 步。
  • 返回了另一个 workload:检查是否有默认角色、连接池模板或环境变量覆盖了配置。

阈值:如果应用有 10 个以上连接,至少抽查 2-3 个会话的 SHOW WORKLOAD,不要只看一个连接。

3.3 第 3 步:确认规则是否存在且目标正确

执行 2.1 的规则查询,并对照 v_catalog.subclusters。

判断:

  • 没有对应 workload 的规则:创建规则。
  • 规则存在但 subcluster_name 不在子集群列表中:修正规则目标。
  • 同一个 workload 的多条规则指向不同子集群:确认这是有意的多目标随机路由;如果不是,删除错误规则。
  • workload 名称和客户端参数只差大小写或空格:统一命名,避免“看起来一样但不匹配”。

3.4 第 4 步:确认目标子集群健康

执行 2.2 和 2.3 的查询。

判断:

  • 目标子集群有节点 node_state != 'UP':先恢复节点;路由到不健康子集群会让连接变慢或失败。
  • 目标子集群 is_readonly = true:确认数据库是否处于只读状态、主子集群是否被关闭或降级。
  • 目标子集群节点数不足:扩容或调整规则,不要把所有 workload 压到一个小子集群。

阈值:目标子集群至少要有 1 个 UP 且非只读的节点;生产环境建议至少保留与 K-Safety 匹配的冗余节点。

3.5 第 5 步:确认用户/角色是否有 USAGE(24.1+)

在应用会话执行 SHOW AVAILABLE WORKLOADS;。

判断:

  • 列表里没有目标 workload:管理员没有授予 USAGE,或授予给了错误的用户/角色。
  • 列表里有目标 workload,但 SHOW WORKLOAD 不是它:客户端没有选择该 workload,或角色没有启用。
  • 列表随角色变化:说明角色授权生效,但默认角色/会话角色配置不稳定,需要统一。

3.6 第 6 步:确认优先级和角色冲突

执行 2.1 的查询,重点看同一个用户可能命中的多条规则:

SELECT workload,
       subcluster_name,
       priority
FROM v_catalog.workload_routing_rules
ORDER BY priority DESC, workload;

判断:

  • 多条规则 priority 相同:数据库会在最高优先级的规则中随机选择,表现为“有时快、有时慢”。给不同业务层级设置可区分的优先级。
  • 用户有多个角色,每个角色都授予了不同 workload:确认默认角色和 SET ROLE 的实际启用顺序。
  • 需要临时强制某条规则:在会话中执行 SET SESSION WORKLOAD TO <workload>;,它忽略优先级。

3.7 第 7 步:确认连接落点与路由日志

用 2.5 的会话查询确认连接节点分布,再到 vertica.log 中搜索路由相关日志。下面是 IP 路由的官方日志示例(workload 路由的日志格式以目标版本为准):

Routing table decision: Success. Load balance redirect to: [10.20.110.23] port [5433]

判断:

  • 日志显示重定向到目标节点/子集群:路由生效,问题可能在目标子集群的资源或 SQL 本身。
  • 日志显示没有匹配规则(IP 路由场景):回到第 3 步检查规则。
  • 日志显示重定向到错误节点:检查规则目标、负载均衡组成员和子集群成员关系。
  • 日志完全没有记录:确认客户端是否真的连到了这个数据库/节点,以及日志级别是否足够。

3.8 第 8 步:确认驱动和连接池

最后检查客户端侧:

  • 驱动版本是否支持 workload 参数;升级驱动后是否重新测试。
  • 连接池是否复用旧连接:修改连接串后,老连接不会自动带上新参数。
  • 连接池是否设置了合理的 maxLifetime;长期存活的连接会绕过新配置。
  • 应用是否在连接建立后执行了 SET SESSION WORKLOAD TO NONE 或切换了角色。

判断:如果新连接正常、老连接异常,优先怀疑连接池生命周期,而不是规则配置。


4. 解决方案

4.1 立即措施:把 workload 写进连接串

最小改动是让客户端在建立连接时明确指定 workload。以下参数来自 v26.2 官方文档:

vsql:

vsql -h node01 -U analytics_user -d analytics_db --workload analytics

vsql 也支持通过 VSQL_WORKLOAD 环境变量指定 workload(来源:v26.2 官方文档 19-connecting-to-opentext-analytics-database.md)。

JDBC:

jdbc:vertica://node01.example.com:5433/analytics_db?user=analytics_user&password=***&workload=analytics

ODBC:

Database=analytics_db;Servername=node01.example.com;Port=5433;UID=analytics_user;PWD=***;Workload=analytics

Python(vertica-python):

conn_info = {
    'host': 'node01.example.com',
    'port': 5433,
    'user': 'analytics_user',
    'password': '***',
    'database': 'analytics_db',
    'workload': 'analytics',
}

Node.js(vertica-nodejs):

const client = new Client({
  user: "analytics_user",
  host: "node01.example.com",
  database: "analytics_db",
  password: "***",
  port: 5433,
  workload: "analytics",
});

连接后补设:

SET SESSION WORKLOAD TO analytics;

为什么这样做: workload 是客户端连接属性,连接建立后再改只影响当前会话,不能改变已经建立的连接池连接;所以优先在连接串里设置,SET SESSION WORKLOAD 只作为临时补救。

4.2 立即措施:授权用户或角色

24.1 及以上版本,按用户/角色路由需要把 workload 的使用权授予用户或角色;即使是按 workload 名称路由,也建议用 SHOW AVAILABLE WORKLOADS 确认权限可见。该语句需要超级用户权限。v26.2 的 SQL 参考语法是:

GRANT USAGE ON WORKLOAD analytics TO analytics_role;
GRANT USAGE ON WORKLOAD analytics TO analytics_user;

版本差异: 24.1 文档中该语句写作 GRANT USAGE ON ROUTING RULE <workload> TO ...;v26.2 SQL 参考中为 GRANT USAGE ON WORKLOAD <workload> TO ...。跨版本迁移时,以目标版本的 GRANT 参考页为准。

为什么优先授予角色: 用户离职、轮换或新增成员时,只需调整角色成员,不用逐用户改授权;同时便于审计“哪些角色能进入哪个子集群”。

设置默认角色,让用户登录时自动启用:

ALTER USER analytics_user DEFAULT ROLE analytics_role;

注意: DEFAULT ROLE 不能和其他 ALTER USER 参数写在同一条语句里(官方文档明确限制)。

4.3 短期优化:创建或修正路由规则

创建按 workload 的路由规则,官方 v26.2 语法如下:

CREATE ROUTING RULE ROUTE WORKLOAD etl TO SUBCLUSTER sc_etl;

一个 workload 路由到多个子集群(连接会随机选择其中一个):

CREATE ROUTING RULE ROUTE WORKLOAD analytics
  TO SUBCLUSTER sc_analytics, sc_analytics_2
  PRIORITY 20;

注意: 官方语法是 CREATE ROUTING RULE ROUTE WORKLOAD ...,不是 CREATE WORKLOAD ROUTING RULE ...。库内部分旧文章使用了后者,执行前请以目标版本官方 SQL Reference 的 CREATE ROUTING RULE 页面为准。

PRIORITY 只对 workload 路由规则有效,默认 0;多条规则命中时取最高值。为什么建议留出间隔: 如果两条规则都写 0,数据库会在它们之间随机选择,表现为路由不稳定;用 10、20 这样的层级值可以避免同值竞争。

24.2 及以上版本可以用 ALTER ROUTING RULE 动态增删目标子集群;如果版本低于 24.2,调整目标通常需要删除并重建规则。变更前先记录原规则,变更后用 SHOW WORKLOAD 和 v_catalog.workload_routing_rules 回归验证。

4.4 变更与回滚

建议按以下顺序变更:

  1. 记录当前规则:SELECT * FROM v_catalog.workload_routing_rules;
  2. 在测试会话设置 workload,确认 SHOW WORKLOAD 和目标子集群。
  3. 创建/修改规则。
  4. 用新连接验证,而不是复用旧连接池。
  5. 观察目标子集群 CPU、会话数和查询延迟。
  6. 异常时回滚:会话级执行 SET SESSION WORKLOAD TO NONE;,或删除/恢复规则。

回滚原则: 先恢复客户端连接串和规则,再处理子集群;不要在生产高峰直接删除子集群或大规模重启连接池。


5. 深入案例

案例 1:ETL 未带 workload,全部落到默认子集群(虚构)

📝 虚构案例

场景描述:某零售企业 Eon 数据库有 3 个子集群:default_subcluster、sc_etl、sc_bi。ETL 作业通过 JDBC 连接,连接串只写了库名和用户,没有 workload 参数。运维发现每天凌晨 ETL 时段默认子集群 CPU 达到 85%,而 sc_etl 只有 15%。

诊断过程:

  1. 在 ETL 会话执行 SHOW WORKLOAD;,返回为空。
  2. 查询 v_catalog.workload_routing_rules,确认存在 etl → sc_etl 规则。
  3. 查询 v_monitor.sessions,ETL 用户的连接全部落在 default_subcluster 的节点。
  4. 结论:规则没问题,客户端没有指定 workload,连接没有进入路由分支。

修复方案:

jdbc:vertica://node01:5433/retail_db?user=etl_user&password=***&workload=etl

重启连接池,确保新连接生效。

效果对比:

  • 修复前:默认子集群 CPU 85%,sc_etl CPU 15%
  • 修复后:默认子集群 CPU 55%,sc_etl CPU 65%
  • ETL 窗口内 BI 查询 P95 从 8 秒降到 3 秒

案例 2:角色优先级冲突导致随机路由(虚构)

📝 虚构案例

场景描述:某金融机构给 svc_bi 用户授予了 bi_role 和 qa_role,两个角色分别绑定 bi 和 qa 两个 workload 规则,优先级都是 0。报表有时落在 sc_bi,有时落在 sc_qa,导致同一张报表的延迟在 2 秒到 12 秒之间波动。

诊断过程:

  1. SHOW AVAILABLE WORKLOADS; 显示两个 workload 都可用。
  2. v_catalog.workload_routing_rules 显示两条规则 priority = 0。
  3. 多次新建连接执行 SHOW WORKLOAD;,workload 在 bi 和 qa 之间随机出现。
  4. 结论:两条规则同优先级,数据库随机选择。

修复方案:

24.1+ 支持 PRIORITY,可用 ALTER ROUTING RULE 调整现有规则的优先级(具体语法以目标版本 SQL Reference 为准);如果版本不支持 ALTER,则删除旧规则后按新优先级重建。调整后的目标状态是:

CREATE ROUTING RULE ROUTE WORKLOAD bi
  TO SUBCLUSTER sc_bi
  PRIORITY 20;

CREATE ROUTING RULE ROUTE WORKLOAD qa
  TO SUBCLUSTER sc_qa
  PRIORITY 10;

同时在连接串中固定 workload=bi,避免依赖角色优先级。

效果对比:

  • 修复前:同一报表 P95 延迟在 2-12 秒之间波动
  • 修复后:报表稳定落在 sc_bi,P95 延迟稳定在 2-3 秒

案例 3:子集群重命名后规则悬空(虚构)

📝 虚构案例

场景描述:运维把 sc_etl 重命名为 sc_etl_v2,但路由规则仍指向旧名称。部分 ETL 作业连接后没有进入目标子集群,个别作业报连接错误。

诊断过程:

  1. v_catalog.workload_routing_rules 中 subcluster_name 仍是 sc_etl。
  2. v_catalog.subclusters 中只有 sc_etl_v2,没有 sc_etl。
  3. vertica.log 中没有成功的路由重定向记录。
  4. 结论:规则目标悬空。

修复方案:

先删除指向旧名称的规则,再按当前版本语法重建(示例为 workload 形式):

CREATE ROUTING RULE ROUTE WORKLOAD etl TO SUBCLUSTER sc_etl_v2;

重建后用新连接执行 SHOW WORKLOAD; 验证。

效果对比:

  • 修复前:ETL 连接未路由,默认子集群压力升高
  • 修复后:ETL 全部落到 sc_etl_v2,路由日志出现成功重定向

案例 4:路由规则指向已移出子集群的节点(真实)

📋 真实案例 · 来源:could not send SSL negotiation packet Connection refused

场景描述:某运营商 Vertica 环境,客户端加了 -C 启用连接负载均衡后,连接经过路由规则被重定向到某个节点,但该节点已经不属于目标子集群,最终报 Connection refused。

诊断过程:

  1. 确认客户端已加 -C,说明连接会走路由/负载均衡逻辑。
  2. 检查 routing_rules 与负载均衡组的成员关系。
  3. 对照 v_catalog.nodes 的 subcluster_name,发现目标节点已不在该子集群。
  4. 结论:路由规则/负载均衡组保留了过期的节点成员关系。

修复方案: 校正路由规则和负载均衡组,使目标成员与当前子集群拓扑一致;变更后用新建连接验证。

说明: 这是 IP 路由规则的真实案例,不是 workload 路由;但它和 workload 路由共享同一类风险——规则目标与子集群实际成员不一致。workload 路由同样需要定期核对 WORKLOAD_ROUTING_RULES.SUBCLUSTER_NAME 与 v_catalog.subclusters。

案例 5:主子集群关闭导致数据库只读(真实)

📋 真实案例 · 来源:Eon双主子集群的注意事项

场景描述:某 Eon 测试环境有两个主子集群。直接关闭其中一个主子集群后,数据库进入只读状态;节点仍然显示 UP,但 is_readonly 变为 true。

诊断过程:

SELECT node_name, node_state, is_primary, is_readonly,
       node_address, subcluster_name, node_type
FROM v_catalog.nodes;

输出显示所有节点 node_state = UP,但 is_readonly = true。这说明“节点 UP”不等于“可写”;子集群角色和数据库整体状态同样重要。

修复方案:

  1. 先把需要关闭的子集群降级为次子集群:SELECT DEMOTE_SUBCLUSTER_TO_SECONDARY('subcluster2');
  2. 再执行子集群停止。
  3. 需要恢复时重启子集群,再执行 SELECT PROMOTE_SUBCLUSTER_TO_PRIMARY('subcluster2');

与路由的关系: 如果 workload 规则指向的子集群被关闭或降级,连接即使成功路由过去,也可能遇到只读或不可写。排查路由问题时,必须同时看 node_state 和 is_readonly,不能只看节点是否 UP。


6. 完整诊断流程实战(虚构)

📝 虚构场景 · 完整演练

背景:某制造企业 Eon 数据库有 default_subcluster、sc_bi、sc_etl 三个子集群。某天上午 BI 报表变慢,应用连接串中已经写了 workload=bi,但部分连接似乎没有进入 sc_bi。

时间 动作 命令/SQL 观察与判断
09:00 确认版本与拓扑 SELECT version();、SELECT subcluster_name, COUNT(*) FROM v_catalog.subclusters GROUP BY subcluster_name; v26.2,三个子集群都存在
09:05 抽查应用会话 在应用会话执行 SHOW WORKLOAD; 有的连接返回 bi,有的返回空
09:10 查看规则 SELECT workload, subcluster_name, priority FROM v_catalog.workload_routing_rules; 规则 workload = bi,但 subcluster_name = sc_bi_old
09:15 查看子集群 SELECT subcluster_name FROM v_catalog.subclusters; 当前名称是 sc_bi,没有 sc_bi_old
09:20 查看节点状态 2.2 的节点查询 sc_bi 节点均为 UP 且非只读
09:25 查看连接落点 2.5 的会话查询 未路由的连接集中在默认子集群
09:30 查看日志 搜索 Routing table decision 没有成功的重定向记录
09:35 定位根因 规则目标与子集群名称不一致;连接池中部分旧连接没有带 workload 规则悬空 + 旧连接未刷新
09:45 修复 重建规则到 sc_bi;重启连接池;新连接串保留 workload=bi 规则和客户端同时修正
10:00 验证 SHOW WORKLOAD;、规则查询、v_monitor.sessions 新连接均显示 bi,落点集中在 sc_bi
10:15 观察 目标子集群 CPU、查询 P95 BI P95 从 15 秒降到 4 秒,默认子集群 CPU 回落

结论: 这次不是单点故障,而是“规则目标过期 + 连接池旧连接”叠加。只改规则或只重启应用都不够;必须同时保证规则目标和客户端连接都正确。


7. 快速诊断 SQL 工具箱

诊断目标 SQL / 命令
查看版本 SELECT version();
查看 workload 路由规则 SELECT workload, subcluster_name, priority FROM v_catalog.workload_routing_rules ORDER BY workload, priority DESC;
查看节点/子集群状态 SELECT node_name, node_state, is_primary, is_readonly, subcluster_name FROM v_catalog.nodes ORDER BY subcluster_name, node_name;
查看子集群节点数 SELECT subcluster_name, COUNT(*) FROM v_catalog.subclusters GROUP BY subcluster_name;
查看 IP 路由规则 SELECT name, source_address, destination_name FROM v_catalog.routing_rules ORDER BY name;
查看负载均衡组 SELECT name, type, object_name, filter, policy FROM v_catalog.load_balance_groups ORDER BY name;
查看网络地址 SELECT name, node, address, port, is_enabled FROM v_catalog.network_addresses ORDER BY node, name;
验证 IP 路由决策 SELECT DESCRIBE_LOAD_BALANCE_DECISION('10.1.2.3');
查看用户会话落点 SELECT user_name, node_name, client_hostname, login_timestamp FROM v_monitor.sessions WHERE user_name = 'analytics_user' ORDER BY login_timestamp DESC;
当前会话 workload SHOW WORKLOAD;
当前用户可用 workload SHOW AVAILABLE WORKLOADS;
临时强制 workload SET SESSION WORKLOAD TO analytics;
清除会话 workload SET SESSION WORKLOAD TO NONE;

8. 最佳实践清单

  1. 先确认版本和子集群拓扑,再谈路由。 低于 23.3 没有 workload 路由,低于 24.1 没有用户/角色路由和 PRIORITY;没有子集群就没有路由目标。
  2. 把 workload 写进连接串,不要只依赖连接后设置。 连接池复用旧连接时,SET SESSION WORKLOAD 不会自动应用到所有连接。
  3. 优先把 USAGE 授予角色,而不是个人。 人员变动时只改角色成员,授权更稳定、更易审计。
  4. 给关键业务设置默认角色。 用户登录即启用角色,避免“忘记 SET ROLE”导致规则不生效。
  5. 规则目标使用子集群名称,并在重命名/重建后立即核对。 WORKLOAD_ROUTING_RULES.SUBCLUSTER_NAME 与 v_catalog.subclusters 不一致时,路由不会按预期工作。
  6. 优先级不要全部用默认 0。 多条规则同值时随机选择,表现为“时快时慢”;用 10、20 等层级值表达明确顺序。
  7. 连接池必须设置合理的生命周期。 修改连接串后,老连接不会自动更新;通过 maxLifetime 和滚动重启让新配置生效。
  8. 监控三张表:规则、节点、会话。 workload_routing_rules 看规则,nodes 看目标健康,sessions 看实际落点。
  9. 变更后用新连接验证。 在目标会话执行 SHOW WORKLOAD,并检查 v_monitor.sessions 和 vertica.log 路由日志。
  10. 把 IP 路由和 workload 路由分开治理。 两套规则同时存在时,不要假设优先级自动叠加;先确认实际生效的规则,再调整。
  11. IP 路由规则的客户端 opt-in 和经典策略要分开看。 客户端 ConnectionLoadBalance=1/-C 是连接被重定向的前提;SET_LOAD_BALANCE_POLICY 只影响无规则匹配时的经典回退,不是路由规则生效的前提。workload 路由两者都不需要。
  12. 按场景选择路由方式。 固定网段用 IP 路由,按任务类型用 workload,按身份/租户用用户/角色;不要把 IP 路由当成 workload 路由的替代。

9. 相关 Bug 修复记录

检索各版本 Resolved issues 后,直接涉及工作负载路由的修复只有 1 条(VER-88467);另有若干连接/子集群负载均衡修复会影响客户端连接落点和路由排查结果。按影响程度整理如下。

下表的「数据库版本」取自各 Resolved issues 文件中该条目所在的小节标题(例如 24.1.0-0),表示该修复出现在这个构建的已解决问题清单中;「来源」链接指向对应版本的 Resolved issues 文件。

9.1 工作负载路由直接相关

来源 数据库版本 编号 模块 问题与修复 与本文的关系
24.1.x Resolved issues 24.1.0-0 VER-88467 Client Drivers - VSQL 执行 CREATE ROUTING RULE 为不存在的子集群创建工作负载路由规则时,错误消息返回错误的对象 ID;修复后返回 TO SUBCLUSTER 子句中提供的子集群名称 排查悬空规则时,升级后可凭错误消息直接定位子集群名称;旧版本可能只看到无意义对象 ID

9.2 连接/子集群负载均衡相关(影响路由落点)

来源 数据库版本 编号 模块 问题与修复 与本文的关系
24.3.x Resolved issues 24.3.0-4 VER-97470 Client Drivers - VSQL EnableInteriorLoadBalancing 的内部缓存未清除,ALTER DATABASE 修改后 DESCRIBE_LOAD_BALANCE_DECISION 仍返回旧结果,客户端负载均衡行为不变 修改连接/子集群负载均衡后“看起来没生效”,先确认是否命中该修复版本
24.4.x Resolved issues 24.4.0-1 VER-97469 Client Drivers - VSQL 子集群内部负载均衡更改未立即生效 与 VER-97470/VER-97299 同类;升级后需用新连接复测
25.1.x Resolved issues 25.1.0-0 VER-97299 Client Drivers - VSQL 同 VER-97470:内部缓存未清除,ALTER DATABASE 设置 EnableInteriorLoadBalancing 不影响 DESCRIBE_LOAD_BALANCE_DECISION 25.1 仍存在该问题;按修复版本升级后再验证路由行为
26.2.x Resolved issues 26.2.0-4 118875, 118388 Client Drivers - JDBC 直接 TLS 连接会禁用原生(客户端)负载均衡;现在直接 TLS 支持原生负载均衡 TLS + 连接负载均衡场景下,连接分布不均可能被误判为 workload 路由失败
9.3.x Resolved issues 9.3.0-0 VER-68494 Client Drivers - Misc 节点故障后更新连接负载均衡的可用节点列表 节点故障后连接仍指向旧节点,可能表现为路由/连接异常
12.0.x Resolved issues 12.0.4-0 VER-84907 Client Drivers - ADO 启用负载均衡时取消 ADO.NET 请求有时抛异常 客户端侧异常,不一定与路由规则有关;排查时先区分驱动问题

9.3 其他 workload 相关但非路由的修复

来源 数据库版本 编号 模块 问题与修复 说明
25.4.x Resolved issues 25.4.0-0 4536473 WLA - Workload Analyzer LAP 投影的 dc_optimizer_events 错误显示 "no histogram",影响 workload analyzer 准确性 属于 workload 分析器,不是连接路由;使用 WLA 分析 workload 性能时需注意版本
26.2.x Resolved issues 26.2.0-0 4967176 UDX 多个会话可共享同一个 Java UDx JVM,降低 Java UDx workload 的内存开销 性能优化,不是路由修复

另检索到 VER-75093、VER-75095、VER-74616、VER-64351 等仅在描述中出现 "workloads" 的通用性能修复(节点间加密、Tuple Mover 重负载),与工作负载路由无关,未列入本文。

结论: 如果目标是修复“规则已建但连接没路由”,优先检查版本与配置;VER-88467 只改善错误消息,不改变路由行为。如果修改了 EnableInteriorLoadBalancing 或客户端负载均衡参数后行为没有变化,优先核对是否命中 9.2 节列出的缓存问题。


扩展阅读