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、用户或角色,适合“办公网/应用网段固定分流”的场景。
配置步骤:
- 服务端创建负载均衡组和路由规则(需要超级用户):
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;
-
客户端显式选择加入:vsql 用
-C,JDBC/ODBC 用ConnectionLoadBalance=1。客户端不 opt-in,匹配到规则也不会被重定向。 -
(可选)如果希望在无规则匹配时回退到经典集群级负载均衡,再开启(需要超级用户):
判定顺序:先匹配
ROUTING_RULES;无匹配时才检查经典策略;再回退到 Eon 默认的子集群内部负载均衡。SET_LOAD_BALANCE_POLICY不是 IP 路由规则生效的前提。
验证路由决策:
输出会显示匹配的规则、目标负载均衡组、候选地址和最终重定向节点;没有匹配规则时,会回退到经典负载均衡或由当前节点直接处理。
监控对象: 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、报表等按任务类型分流。
核心配置:
客户端连接参数使用 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 路由,先确认它是否会把连接导向别的目标:
如何解读结果:
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 客户端侧自检命令¶
在应用的数据库会话里执行:
输出会显示当前会话的 workload。为空或不是预期值,说明客户端没有正确设置。
输出当前用户及其已启用角色可用的 workload 列表(24.1+)。列表为空,通常意味着没有 USAGE 授权,或角色未启用。
3. 逐步定位根因¶
3.1 第 1 步:确认版本与模式¶
先确认数据库版本和子集群拓扑,避免在错误的前提下排查:
判断:
- 版本低于 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 路由的日志格式以目标版本为准):
判断:
- 日志显示重定向到目标节点/子集群:路由生效,问题可能在目标子集群的资源或 SQL 本身。
- 日志显示没有匹配规则(IP 路由场景):回到第 3 步检查规则。
- 日志显示重定向到错误节点:检查规则目标、负载均衡组成员和子集群成员关系。
- 日志完全没有记录:确认客户端是否真的连到了这个数据库/节点,以及日志级别是否足够。
3.8 第 8 步:确认驱动和连接池¶
最后检查客户端侧:
- 驱动版本是否支持 workload 参数;升级驱动后是否重新测试。
- 连接池是否复用旧连接:修改连接串后,老连接不会自动带上新参数。
- 连接池是否设置了合理的
maxLifetime;长期存活的连接会绕过新配置。 - 应用是否在连接建立后执行了
SET SESSION WORKLOAD TO NONE或切换了角色。
判断:如果新连接正常、老连接异常,优先怀疑连接池生命周期,而不是规则配置。
4. 解决方案¶
4.1 立即措施:把 workload 写进连接串¶
最小改动是让客户端在建立连接时明确指定 workload。以下参数来自 v26.2 官方文档:
vsql:
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",
});
连接后补设:
为什么这样做: 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 参考页为准。
为什么优先授予角色: 用户离职、轮换或新增成员时,只需调整角色成员,不用逐用户改授权;同时便于审计“哪些角色能进入哪个子集群”。
设置默认角色,让用户登录时自动启用:
注意: DEFAULT ROLE 不能和其他 ALTER USER 参数写在同一条语句里(官方文档明确限制)。
4.3 短期优化:创建或修正路由规则¶
创建按 workload 的路由规则,官方 v26.2 语法如下:
一个 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 变更与回滚¶
建议按以下顺序变更:
- 记录当前规则:
SELECT * FROM v_catalog.workload_routing_rules; - 在测试会话设置 workload,确认
SHOW WORKLOAD和目标子集群。 - 创建/修改规则。
- 用新连接验证,而不是复用旧连接池。
- 观察目标子集群 CPU、会话数和查询延迟。
- 异常时回滚:会话级执行
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%。
诊断过程:
- 在 ETL 会话执行
SHOW WORKLOAD;,返回为空。 - 查询
v_catalog.workload_routing_rules,确认存在etl → sc_etl规则。 - 查询
v_monitor.sessions,ETL 用户的连接全部落在default_subcluster的节点。 - 结论:规则没问题,客户端没有指定 workload,连接没有进入路由分支。
修复方案:
重启连接池,确保新连接生效。
效果对比:
- 修复前:默认子集群 CPU 85%,
sc_etlCPU 15% - 修复后:默认子集群 CPU 55%,
sc_etlCPU 65% - ETL 窗口内 BI 查询 P95 从 8 秒降到 3 秒
案例 2:角色优先级冲突导致随机路由(虚构)¶
📝 虚构案例
场景描述:某金融机构给 svc_bi 用户授予了 bi_role 和 qa_role,两个角色分别绑定 bi 和 qa 两个 workload 规则,优先级都是 0。报表有时落在 sc_bi,有时落在 sc_qa,导致同一张报表的延迟在 2 秒到 12 秒之间波动。
诊断过程:
SHOW AVAILABLE WORKLOADS;显示两个 workload 都可用。v_catalog.workload_routing_rules显示两条规则priority = 0。- 多次新建连接执行
SHOW WORKLOAD;,workload 在bi和qa之间随机出现。 - 结论:两条规则同优先级,数据库随机选择。
修复方案:
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 作业连接后没有进入目标子集群,个别作业报连接错误。
诊断过程:
v_catalog.workload_routing_rules中subcluster_name仍是sc_etl。v_catalog.subclusters中只有sc_etl_v2,没有sc_etl。vertica.log中没有成功的路由重定向记录。- 结论:规则目标悬空。
修复方案:
先删除指向旧名称的规则,再按当前版本语法重建(示例为 workload 形式):
重建后用新连接执行 SHOW WORKLOAD; 验证。
效果对比:
- 修复前:ETL 连接未路由,默认子集群压力升高
- 修复后:ETL 全部落到
sc_etl_v2,路由日志出现成功重定向
案例 4:路由规则指向已移出子集群的节点(真实)¶
📋 真实案例 · 来源:could not send SSL negotiation packet Connection refused
场景描述:某运营商 Vertica 环境,客户端加了 -C 启用连接负载均衡后,连接经过路由规则被重定向到某个节点,但该节点已经不属于目标子集群,最终报 Connection refused。
诊断过程:
- 确认客户端已加
-C,说明连接会走路由/负载均衡逻辑。 - 检查
routing_rules与负载均衡组的成员关系。 - 对照
v_catalog.nodes的subcluster_name,发现目标节点已不在该子集群。 - 结论:路由规则/负载均衡组保留了过期的节点成员关系。
修复方案: 校正路由规则和负载均衡组,使目标成员与当前子集群拓扑一致;变更后用新建连接验证。
说明: 这是 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”不等于“可写”;子集群角色和数据库整体状态同样重要。
修复方案:
- 先把需要关闭的子集群降级为次子集群:
SELECT DEMOTE_SUBCLUSTER_TO_SECONDARY('subcluster2'); - 再执行子集群停止。
- 需要恢复时重启子集群,再执行
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. 最佳实践清单¶
- 先确认版本和子集群拓扑,再谈路由。 低于 23.3 没有 workload 路由,低于 24.1 没有用户/角色路由和
PRIORITY;没有子集群就没有路由目标。 - 把 workload 写进连接串,不要只依赖连接后设置。 连接池复用旧连接时,
SET SESSION WORKLOAD不会自动应用到所有连接。 - 优先把
USAGE授予角色,而不是个人。 人员变动时只改角色成员,授权更稳定、更易审计。 - 给关键业务设置默认角色。 用户登录即启用角色,避免“忘记
SET ROLE”导致规则不生效。 - 规则目标使用子集群名称,并在重命名/重建后立即核对。
WORKLOAD_ROUTING_RULES.SUBCLUSTER_NAME与v_catalog.subclusters不一致时,路由不会按预期工作。 - 优先级不要全部用默认 0。 多条规则同值时随机选择,表现为“时快时慢”;用 10、20 等层级值表达明确顺序。
- 连接池必须设置合理的生命周期。 修改连接串后,老连接不会自动更新;通过
maxLifetime和滚动重启让新配置生效。 - 监控三张表:规则、节点、会话。
workload_routing_rules看规则,nodes看目标健康,sessions看实际落点。 - 变更后用新连接验证。 在目标会话执行
SHOW WORKLOAD,并检查v_monitor.sessions和vertica.log路由日志。 - 把 IP 路由和 workload 路由分开治理。 两套规则同时存在时,不要假设优先级自动叠加;先确认实际生效的规则,再调整。
- IP 路由规则的客户端 opt-in 和经典策略要分开看。 客户端
ConnectionLoadBalance=1/-C是连接被重定向的前提;SET_LOAD_BALANCE_POLICY只影响无规则匹配时的经典回退,不是路由规则生效的前提。workload 路由两者都不需要。 - 按场景选择路由方式。 固定网段用 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 节列出的缓存问题。