Vertica Eon Communal Storage 运维实战¶
作者:JiangChong | 撰写时间:2026年09月
适用场景:运维 Vertica Eon 集群、排查 HDFS 公共存储故障时阅读本文。目标读者是熟悉 Vertica Enterprise 模式、刚接触 Eon 的 DBA。 关联文章:Vertica 读取 HDFS 文件的原理分析(Vertica 按块读取 HDFS 文件的机制);本文是 HDFS 系列桥梁文章:HDFS 架构原理、HDFS 读写流程与副本放置策略、HDFS 高可用(QJM、ZKFC、Federation)、HDFS 小文件问题与治理、纠删码 vs 三副本存储策略、HDFS 数据湖存储底座(与 Iceberg 的关系)、Vertica Eon Communal Storage 运维实战。
理解全文脉络:Eon 模式把「数据」和「算力」拆开——数据的权威副本全部存放在公共存储(本文场景即 HDFS),节点本地只留 depot 缓存,因此 Eon 集群绝大多数故障本质上是「公共存储不可用或变慢」在数据库侧的表现。本文先用官方文档把架构讲清楚,再从 6 个真实案例归纳故障模式,最后给出可直接落地的运维清单。
阅读前回顾(30 秒)¶
系列上一篇 HDFS 数据湖存储底座(与 Iceberg 的关系) 讲过:Eon 公共存储可以落在 HDFS 上,与 Iceberg 湖仓表共用同一套 HDFS。本文把镜头对准 Eon 本身:Eon 把「数据的真相」从节点本地搬到公共存储,节点只留 depot 缓存——因此 Eon 的多数故障不是「节点坏了」,而是「公共存储(HDFS)不可用或变慢」在数据库侧的表现。记住这一句,第 2 节的 6 个故障就都能看懂;术语不熟随时回查第 1.3 节速查表,文末附新手 FAQ。
1 Eon 公共存储原理:数据在公共存储,depot 只是本地缓存¶
1.1 communal storage 与 depot 的分工¶
按照官方文档(60.ofdocs/vertica_docv26.2/chapters/09-eon-mode.md)的定义,Eon 与 Enterprise 两种模式的根本差异在于数据存在哪:
- Enterprise 模式:每个节点在自己的本地文件系统中存放一部分数据、承担一部分计算;
- Eon 模式:计算过程与共享(communal)存储层分离,数据的权威副本(definitive copy)全部存放在公共存储中,由此实现计算资源按需快速伸缩——加节点等于加算力,不需要搬数据。
可以打个比方:公共存储是总仓库,节点本地磁盘上的 depot 是每个门店的货架。查询时先看货架,没有才去仓库取,并顺手在货架上放一份,方便下次再查;加载数据时先放到货架,再统一搬进仓库。depot 丢了大不了多跑几趟仓库,仓库才是唯一的真相——这一句是理解后面所有故障的关键。
一句话配一张图:
flowchart LR
Q["查询 / 加载"]
Q --> DEP["节点 depot<br/>货架(本地磁盘缓存)"]
CS["公共存储 HDFS<br/>总仓库(数据权威副本)"]
CS -->|"miss:从仓库取数,顺手放上货架"| DEP
DEP -->|"写入:先落货架,再统一搬进仓库"| CS
官方文档「Depot management」章节给出了 depot 的完整定义:节点按需从公共存储取数并在本地磁盘缓存,一个子集群内所有节点的缓存合起来构成该子集群的 depot。两个配置参数控制 depot 的读写角色,默认都是 1(启用):
| 参数 | 默认值 | 作用 |
|---|---|---|
| UseDepotForReads | 1 | 查询先查 depot,miss 则从公共存储拉取并缓存;设为 0 则绕过 depot 直接读公共存储 |
| UseDepotForWrites | 1 | 加载数据先写 depot 再上传公共存储;设为 0 则直接写公共存储 |
depot 的容量规划与限制同样是官方文档明确规定的:depot 默认占用所在文件系统空间的 60%,可用 --depot-size 调整(上限 80%);官方建议每节点本地磁盘至少 2TB,其中 60% 给 depot,其余 40% 分给 catalog 与 data location。有一个容易踩的坑:UseDepotForWrites=1 时,单事务加载量若超过子集群全部 depot 之和,加载会直接失败——官方文档给出的解法是把 UseDepotForWrites 设为 0,让数据直写公共存储。
两种模式在运维视角的差异可以用下表概括:
| 维度 | Enterprise 模式 | Eon 模式 |
|---|---|---|
| 数据权威副本 | 分布在各节点本地磁盘 | 全部在公共存储(communal storage) |
| 节点本地磁盘 | 承载数据 + 计算 | 仅 depot 缓存与 catalog |
| 扩展计算资源 | 需同时考虑数据重新分布 | 计算与存储分离,按需增减节点 |
| 故障影响面 | 节点故障影响其持有的数据 | 节点故障影响小;公共存储故障影响全部节点 |
1.2 公共存储上的目录与文件组织¶
以 HDFS 作为公共存储时,创建数据库时通过 --communal-storage-location 指定位置,格式为 webhdfs:// 或 swebhdfs:// 协议(官方文档明确:不能用 hdfs:// 协议)。典型建库命令来自官方文档:
$ admintools -t create_db -x bootstrap_params.conf \
--communal-storage-location=webhdfs://mycluster/verticadb \
--depot-path=/home/dbadmin/depot --shard-count=6 \
-s vnode01,vnode02,vnode03 -d verticadb -p 'YourPasswordHere'
这条命令把 HDFS 上的目录、本地 depot 路径、分片数一次性定死,--shard-count 应取节点数的倍数或约数,保证分片在各节点间均匀分配。如果使用了 HA NameNode 或 Kerberos,还需要在 bootstrap_params.conf 里声明 HadoopConfDir 与 Kerberos 系列参数(详见 3.2 节)。
结合真实案例与官方文档,公共存储上的组织方式可以归纳为两层:
- 数据文件:
<communal-storage-location>/<数据库名>/<编号目录>/<sal_storage_id>_0.gt。例如案例中的/verticaeon/db1/535/02521acd13e8794a7ee89cb7c97377b900e0000002af99bf_0.gt。以.gt结尾、哈希命名的文件就是 Vertica 的存储容器(storage container)文件,编号子目录对应分片/存储对象的组织单元;本地 depot 与公共存储的文件名一一对应(案例报错中 depot 路径与 webhdfs 路径除前缀外完全相同)。 - 元数据目录:
<communal-storage-location>/<数据库名>/metadata/<数据库名>/,其中的cluster_config.json记录了 catalog 最后同步的版本与时间戳;nodes/子目录存放各节点元数据——官方文档在移除节点时提示清理metadata/verticadb/nodes/v_verticadb_node0004一类的文件。
两层组织画成目录树就是:
webhdfs://mycluster/verticadb/ # 公共存储根(建库时 --communal-storage-location 定死)
├── db1/ # 数据库
│ ├── 535/ # 编号目录(分片/存储对象的组织单元)
│ │ └── 02521acd...af99bf_0.gt # 存储容器文件(哈希命名,与 depot 一一对应)
│ └── metadata/db1/ # 元数据目录(catalog 的公共存储副本)
│ ├── cluster_config.json # 记录 catalog 最后同步版本与时间戳
│ └── nodes/v_verticadb_node0004/ # 各节点元数据
Eon 数据库的 catalog(全部元数据)就存在公共存储上,Vertica 会按 CatalogSyncInterval 参数定期同步,默认每 5 分钟一次。这一点运维时必须牢记:catalog 是 revive 复活数据库的依据,计划 revive 或复制的停机前最好手动执行一次 SELECT sync_catalog();(官方文档「Synchronizing metadata」章节明确推荐此做法),否则可能丢最后几分钟的元数据变更。另外,公共存储上的数据会先按 shard(分片)划分——每个 namespace 有独立的 shard count,节点订阅至少一个分片并负责其中的数据。
1.3 术语速查¶
| 术语 | 一句话解释 |
|---|---|
| communal storage | 公共存储,数据库全部数据的持久化权威副本所在(HDFS、S3、MinIO、Ceph、FlashBlade 等) |
| depot | 节点本地磁盘缓存,查询与加载的中间层,丢了可重建 |
| shard | 分片,公共存储中数据划分的最小逻辑单元,节点按订阅关系承担对应数据 |
| namespace | 命名空间,一组 schema/表的集合,每个 namespace 有独立的 shard count |
| subcluster | 子集群,一组节点的集合;primary(主子集群)承担主职责,secondary(次子集群)随时可停 |
| storage container | 存储容器(.gt 文件),Vertica 读写数据的基本文件单元 |
| SAL | Storage Abstraction Layer,Vertica 访问外部存储的抽象层,日志前缀为 [SAL] |
术语背后有一条主线:节点订阅分片 → 分片数据落在公共存储 → 节点查询时经 depot 缓存取数。下面第 2 节的所有故障,都是这条链路中某一环出了问题。
本节要点:Eon = 数据权威副本在公共存储(总仓库)+ 节点 depot 缓存(货架)。记三个默认值:depot 占本地文件系统 60%、catalog 每 5 分钟同步一次、建库必须用 webhdfs://。仓库才是唯一真相——后面所有故障都是这条链路的某一环断了。
2 常见故障模式与处理¶
本节 6 个故障全部来自知识库真实案例,每个按「现象 → 诊断线索 → 根因 → 处理」组织。共同的第一原则:Eon 故障先分清是数据库的问题还是 HDFS 的问题——报错里带 WebHDFS exception、UnknownHostException、StandbyException、lease 相关字样的,几乎都是 HDFS 侧问题在数据库的投影。
按现象关键词直接导航到对应小节:
| 现象关键词 | 小节 | 一句话根因 |
|---|---|---|
| FileAlreadyExistsException / 60 秒超时 | 2.1 | HDFS 写慢 → lease 被收回 |
| 空间不释放、清理不生效 | 2.2 | tombstone 标记后 reaper 清理停滞 |
| StandbyException(READ/WRITE) | 2.3 | 别只盯主备——先验证文件块是否损坏 |
| UnknownHostException / Invalid hostname | 2.4 | 往往是 ulimit 改了没重启进程 |
| 停主子集群后全库只读 | 2.5 | 没先 DEMOTE |
| 启动卡在 Inviting cluster | 2.6 | Kerberos 票据错误 / catalog 过大 |
2.1 写公共存储报 FileAlreadyExistsException(HDFS lease 超时)¶
现象:加载(COPY)或数据同步任务报 ERROR 8076: Could not copy file [...] to [webhdfs://...]: Seen WebHDFS exception,HTTP 响应码 403,Exception type: FileAlreadyExistsException,message 形如「xxx.gt for client 某节点IP already exists」。
诊断线索:这个报错是「果」,真正的「因」在 vertica.log 的 Uploader 日志里。案例中的关键日志序列非常典型,从创建文件到超时正好 60 秒:
2020-12-30 15:04:18.033 Uploader [SAL] Waited for data for [http://...?op=CREATE...]; 1 still running
...
2020-12-30 15:05:18.137 Uploader [SAL] Error writing to webhdfs://...; attempting recovery
(60305 ms since last HDFS operation); Error Message: Over 60 seconds without any data transfer for [...]
2020-12-30 15:05:18.137 Uploader [SAL] Completed recovery for webhdfs://...; 0 bytes are consistent on server and recovery is complete.
2020-12-30 15:05:18.139 Uploader [SAL] ... FileAlreadyExistsException
根因:HDFS 的 lease 机制。HDFS NameNode 上有 lease manager:client 持有某个文件的 lease 超过 60 秒且没有数据传输活动,lease 就会被强制收回。当 HDFS 写吞吐不足时(典型原因:DataNode 堆内存给得太小、网络带宽不足、磁盘数量太少或磁盘故障),Vertica 从 CREATE 到数据传完超过 60 秒,lease 被收回;Vertica 检测到超时后执行 recovery,恢复完成再次重试时文件已存在,于是抛出 FileAlreadyExistsException。结论:根因是 HDFS 写慢,不是 Vertica 的问题,修 Vertica 修不好它。
处理(按优先级,来自案例原文):
1. 排查并提升 HDFS 写性能。最直接的抓手是调大 NameNode/DataNode 的 Java 堆内存:案例中某运营商把 DataNode 堆从 1GB 调到 8GB 后问题消失;另一个案例把 DN 堆从 32GB 调到 64GB(物理内存 112GB)后报错不再发生。
2. 将有问题的 DataNode 从 Hadoop 中隔离(踢出),先止血。
3. 临时措施:降低 Vertica 参数 MaxUploaderWorkerThreadsPerDataTarget(默认 8)为 4、2 甚至 1,降低并发写压力。案例明确提醒:这只是避免报错影响业务的临时手段,不解决性能问题,根本解法还是排除 HDFS 写慢的原因。
同一根源还有两个变体报错,看到时直接按本案例思路处理:读方向的 FileColumnReader: ... Over 60 seconds without any data transfer for ...(读也受 60 秒超时影响),以及 Could not copy file ... due to file size mismatch. expecting X bytes, returned Y bytes(写中途中断导致大小不一致)。
📋 真实案例 · 来源:Eon同步文件到hdfs报FileAlreadyExistsException错误
2.2 公共存储空间不释放(clean_communal_storage 不生效)¶
现象:系统表统计的投影数据量与 HDFS 实际占用差异巨大。案例环境为 Vertica 10.1.1-7、HDFS 3 副本:从 projection_storage 统计所有投影单副本总量 160TB,而 hadoop fs -du -s -h /VerticaEON 统计单副本总量 227TB,两者相差约 67TB;执行 select clean_communal_storage('true'); 和 select flush_reaper_queue(); 后,第二天空间依然没有降低。
诊断线索:先做减法——两个口径都是「单副本」量,差值 67TB 不是副本膨胀造成的,而是清理机制未生效的泄露文件;再核对 HDFS 是否有快照,快照会阻止文件被删除。
根因:Eon 模式删除数据后,公共存储上的文件不会立即消失,而是先打上 tombstone(墓碑)标记,由后台 reaper 服务按批次删除。AHM 不推进、批次参数过大导致单轮删除耗时过长,或 HDFS 使用率已满导致删除动作无法完成,都会让清理停滞。
处理:按案例给出的顺序执行。先调低批量参数,减小单次清理的规模:
-- 可逐步调低参数值,检查效果,问题修复后恢复默认值
SELECT SET_CONFIG_PARAMETER('TombstoneProcessingBatchSize',500); /*default 1000*/
SELECT SET_CONFIG_PARAMETER('S3DeleteBatchSize',500); /*default 1000*/
再 drop/truncate 测试表,随后按固定顺序推进清理(顺序不能乱):
select make_ahm_now();
select sync_catalog();
select clean_communal_storage(true);
select flush_reaper_queue();
过 1~2 分钟查看公共存储空间是否释放。这里每个命令各司其职:make_ahm_now() 把 AHM(Ancient History Marker,历史数据可清理的最早时间点)推进到当前时刻,让历史版本的存储文件进入可删除状态;sync_catalog() 把 catalog 同步到公共存储;clean_communal_storage(true) 清理公共存储上的孤儿文件;flush_reaper_queue() 让 reaper 立即处理队列,而不是等后台周期任务。如果 HDFS 使用率已经 100%,必须先手动删除一些文件,再执行后面三个命令——空间满了,删除动作本身也写不进去。
📋 真实案例 · 来源:Eon公共存储文件不删除问题
2.3 查询/加载报 Operation category READ/WRITE is not supported in state standby¶
现象:查询报 ERROR 8912: FileColumnReader: unable to open position index [...],HTTP 403,Exception type: StandbyException,message 为 Operation category READ is not supported in state standby;加载方向存在对应的 Operation category WRITE is not supported in state standby 变体。报错的 URL 里 op=OPEN/op=CREATE 指向的正是公共存储文件。
诊断线索:StandbyException 是 HDFS 侧返回的错误——Vertica 通过 webhdfs 协议访问了处于 standby 状态的 NameNode,而 standby NN 拒绝一切读写。第一步先确认 NN 主备状态(hdfs haadmin -getServiceState),但别只盯着主备切换。案例中的关键转折是:文件在 HDFS 上明明存在(hadoop fs -ls 可见),hadoop fs -get 却取不出来:
[dbadmin@node1 OTPS]$ hadoop fs -ls /verticaeon/db1/535/02521acd13e8794a7ee89cb7c97377b900e0000002af99bf_0.gt
-rw-rw---- 3 dbadmin verticadba 59708 2023-12-08 10:12 /verticaeon/db1/535/02521acd13e8794a7ee89cb7c97377b900e0000002af99bf_0.gt
[dbadmin@node1 OTPS]$ hadoop fs -get /verticaeon/db1/535/02521acd13e8794a7ee89cb7c97377b900e0000002af99bf_0.gt
get: Could not obtain block: BP-937276932-...:blk_1109886349_36207621 file=/verticaeon/db1/535/02521acd13e8794a7ee89cb7c97377b900e0000002af99bf_0.gt
Could not obtain block 说明文件块已经损坏——这才是真正的根因,StandbyException 只是表象。报错中的文件名(不含 _0.gt 的部分)就是 sal_storage_id,可以反向定位它属于哪张表、哪个 projection、哪个分片:
select * from storage_containers
where sal_storage_id in
('02521acd13e8794a7ee89cb7c97377b900e0000002af99bf','02510405ed5df9e27b9a2120096e16f301a000000279bbf7');
从结果中的 schema_name、projection_name、shard_name、start_epoch 就能判断文件归属的账期和分区。
根因与处理:公共存储 HDFS 上的文件块损坏(如数据节点坏盘),任何读到该文件的查询和 mergeout 都会报错。处理思路来自案例结论:查看损坏文件的生成时间,跳过对应账期,把其他账期数据查询备份出来,再重跑损坏文件所在账期;或者从 HDFS 侧修复损坏块。加载(WRITE)方向的变体案例走的是另一条处理路径:案例结论是调整 HDFS 客户端的 failover 重试参数 dfs.client.failover.connection.retries 与 dfs.client.failover.connection.retries.on.timeouts(默认都是 0,网络不稳定时建议加大),并提示根源可能是 datanode 数量太少。
📋 真实案例 · 来源:查询表报Operation category READ is not supported in state standby错误、Eon模式数据库加载数据报Operation category WRITE is not supported in state standby错误
2.4 insert/读取报 Invalid hostname(UnknownHostException)¶
现象:报错文本为 FileColumnReader: unable to open position index [...]: ... Exception type: UnknownHostException; Invalid hostname: local host is: (unknown); destination host is: "namenode2":9000,错误指向 HDFS 的 NameNode。
诊断线索与根因:该报错出现在 HDFS 主备切换场景,案例中 namenode1 为 active、namenode2 为 standby。第一次处理做了主备切换应急,很快不再报错;但 3 个月后复发,深入排查才挖出真根因——集群的 max open files 配置改过了,但 Hadoop 进程没有重启,参数未生效。检查进程实际限制即可证实:
[root@node1]# jps
85935 Datanode
[root@node1]# cat /proc/85935/limits
...
Max open files 4096 4096 files
...
ulimit -n 的全局配置改了,但进程级限制要在进程重启后才更新。文件句柄不足导致 HDFS 侧连接资源耗尽,Vertica 侧建连/解析失败,最终以 UnknownHostException 的形式暴露。
处理:重启 Hadoop 相关进程使 max open files 生效(案例重启后数据库未再报错);主备切换(hdfs haadmin -transitionToActive -forcemanual namenode2)只作为应急止血手段。教训沉淀为一条通用规则:任何 HDFS 参数调整后都必须重启进程,并用 /proc/<pid>/limits 验证生效——这与 HDFS 高可用原理相关,参见 HDFS 高可用(QJM、ZKFC、Federation)。
📋 真实案例 · 来源:Eon数据库执行insert报 Invalid hostname
2.5 双主子集群直接关闭子集群导致数据库 READONLY¶
现象:双主子集群(两个 primary subcluster)场景下直接关闭其中一个,admintools 先给出警告,强制关闭后整个数据库进入只读状态:
[dbadmin@node1 ~]$ admintools -t stop_subcluster -c subcluster2 -d eondb -Fi
Info: no password specified, using none
Subcluster is critical, shutting the subcluster down will cause the whole database shutdown
关闭后查询节点状态,所有节点 is_readonly = t:
select node_name,node_state,is_primary,is_readonly,node_address,subcluster_name,node_type from nodes;
根因:主子集群承载着主分片订阅,是数据库的「法定人数」。直接关闭会让其订阅的分片失去归属,数据库自动进入 READONLY 保护状态,拒绝一切写入——DBA 为了维护子集群停服,结果把整个库弄成只读,业务影响面反而更大。
正确做法:先降级为次子集群,再关闭;恢复时先启动再升回主子集群:
结论:多主子集群场景下,停其中任何一个主子集群前必须先 DEMOTE,否则整个数据库 READONLY。 如果数据库只有一个主子集群,因数据库至少要保留一个 primary,此时 DEMOTE 操作不被允许,停它等于整库停机,只能按停机窗口安排。
📋 真实案例 · 来源:Eon双主子集群的注意事项
2.6 启动卡在 Inviting cluster(Kerberos 票据 / catalog 过大)¶
现象:Eon 数据库启动一直卡在 Inviting cluster 阶段,无法正常启动;vertica.log 中可见 Kerberos 票据相关报错。
根因有两类:
- Kerberos 票据问题(最常见):Eon 模式启动过程中会验证数据库参数
KerberosKeytabFile指向的票据文件——Eon 数据库进程要以系统 principal 访问公共存储(HDFS),keytab 文件不存在或内容不正确时无法完成认证,启动就只能卡住。企业模式不存在这个问题,因为本地数据不需要 Kerberos。官方文档有明确要求:为数据库(system)用户创建 Kerberos principal,并授予其对公共存储所在 HDFS 位置的读写权限。 - catalog 过大:启动要经历 catalog 邀请(invite)阶段,catalog 越大邀请越慢;下文节点替换案例中 catalog 平均每节点 50GB、最大 90GB,新节点卡在等待邀请、反复重启无效,最终靠 revive_db 复活 + 手工逐节点拉起才恢复。
处理中有两个值得记住的细节(均为案例验证):
- 尝试删除
/$catalog/vertica.conf中的KerberosKeytabFile配置项再启动——失败。数据库启动时会自动修复该文件,把删掉的参数加回来。所以不能靠改配置绕过,必须提供正确的票据。 - 复活数据库时报公共存储文件权限错误时,需要在 bootstrap_params.conf 中添加 Kerberos 认证参数(HadoopConfDir、KerberosServiceName、KerberosRealm、KerberosKeytabFile 等)——与官方文档「create a bootstrapping file」的步骤一致。
- 在进行票据替换之前,一定要在验证环境测试票据是否有效,不要盲目在生产环境操作。
catalog 过大这一类的典型现场,就是节点替换后无法启动:某运营商 27 节点 Eon 集群(12.0.4-16)替换故障节点后,新节点一直卡在等待邀请,先后尝试调整网络广播模式、kill 新节点、多次重启均失败,最后通过 revive_db 从公共存储复活数据库:
admintools -t revive_db --display-only --communal-storage-location=webhdfs://hacluster/verticaeon/db1 -d db1 -x /home/dbadmin/vertica/bootstrap_params.conf
admintools -t revive_db --communal-storage-location=webhdfs://hacluster/verticaeon/db1 -d db1 -x /home/dbadmin/vertica/bootstrap_params.conf
admintools -t start_db -d db1 -F
复活成功但仍无法启动,最终靠手工拉起每个节点进程恢复,全程停服约 15 小时。期间验证了一个参数生效细节:TSCatalogInvite = 0(跳过 catalog 邀请阶段,用于超大 catalog 场景)直接改 vertica.conf 无效,必须用 catalog editor 修改:
该案例同时暴露了隐患:大 catalog 会拖垮启动与节点替换,后续需要业务侧控制对象数量。
📋 真实案例 · 来源:Eon数据库因为票据不对导致的启动失败、Eon数据库复活时报公共存储文件权限错误、Eon 数据库替换节点过后节点启动卡在等待邀请步骤且重启数据库失败
本节要点:6 个故障一个套路——先按关键词分清「HDFS 侧还是 Vertica 侧」,再走「现象→诊断→根因→处理」。
3 运维最佳实践¶
3.1 子集群操作:先 DEMOTE,节点维护选低峰¶
多主子集群的停机流程已在 2.5 详述,这里补充节奏层面的经验。Eon 数据库性能问题案例(某税务系统 70 节点、28+14+14+14 四个子集群)记录了两个影响运维时机的细节:
- 一是节点替换、故障节点恢复时会执行 drop remove subscription 操作,把宕机节点的分片从相邻节点摘除,这会产生 GCL-X 锁,导致短时性能下降;
- 二是 GCL-X 锁 30 分钟内无法获取时可能导致集群宕机,而触发条件往往是公共存储 NameNode 状态异常、性能低下。因此节点维护应安排在业务低峰,且维护前先确认公共存储(NN/DN)健康。另一个案例(某电信运营商)显示两个主子集群 IO 性能异常同样会导致 mergeout 产生大量 GCL-X 锁——主子集群的硬件与网络值得单独监控。
📋 真实案例 · 来源:Eon数据库性能问题原因
3.2 节点替换与复活:bootstrap 参数与 catalog 治理¶
复活与替换场景的第一前提是准备正确的 bootstrap_params.conf,包含 HadoopConfDir 与 Kerberos 系列参数——少了它,复活直接报公共存储权限错误(见 2.6)。
其次,节点替换卡在等待邀请时的排查顺序(来自案例实操)是:防火墙/SELinux → 节点间网络(用 nc 测试 4803/4804 端口 UDP 连通性,确认无僵尸 spread 进程)→ 怀疑 catalog 过大时评估 TSCatalogInvite → 最终手段 revive_db + 手工拉起节点。catalog 治理是预防性投入:catalog 存储在节点本地,对象越多越大,数十 GB 的 catalog 会拖垮启动与节点替换,需要业务侧控制表/投影数量、及时清理历史对象。
3.3 Kerberos 票据维护¶
- Eon 启动会校验
KerberosKeytabFile,keytab 路径或内容错误 → 卡 Inviting cluster;删除配置项无效(启动自动修复)。任何 keytab 变更后要立即做一次启动验证,确认能正常访问 Hadoop(案例 2.6 的核心教训)。 - HDFS 侧需为数据库 system principal 授予公共存储目录的读写权限(官方文档原文要求 "grant it read and write access to the location in HDFS where you will place your communal storage")。
3.4 HDFS 侧健康检查习惯¶
Eon 对 HDFS 的依赖远大于 Enterprise 模式——所有数据都在 HDFS 上,所以「HDFS 先健康,Eon 才健康」。结合 vault 案例与 HDFS 系列文章,建议固化如下检查习惯:
| 检查项 | 做法与要点 | 来源 |
|---|---|---|
| 文件系统完整性 | hdfs fsck / -showprogress 全库扫描;默认方式易报 SocketTimeoutException(Read timed out),加 -showprogress 输出进度后不再超时 |
fsck 案例 |
| 容量与异常增长 | hadoop fs -du -s -h /<数据库目录> 与 projection_storage 统计对比;异常差值提示清理失效或文件泄露 |
空间不释放案例 |
| NN 主备状态 | 出现 StandbyException 时先 hdfs haadmin -getServiceState 确认主备,再验证文件块完整性 |
Standby 案例 |
| DN 堆内存与吞吐 | 写慢(60 秒 lease 超时)时优先检查 DN 堆内存、网络带宽、磁盘状态 | FileAlreadyExists 案例 |
| max open files | 修改后必须重启 Hadoop 进程,用 /proc/<pid>/limits 验证生效 |
Invalid hostname 案例 |
| 小集群副本配置 | 3 个 DN + 副本数 3 时,任一 DN 故障写入即失败;设置 dfs.client.block.write.replace-datanode-on-failure.policy=NEVER 避免无谓的重试 |
datanode pipeline 案例 |
| HDFS 快照 | 清理空间前先确认无快照,否则文件「删不掉」 | 空间不释放案例 |
其中两项与 HDFS 系列文章直接呼应:fsck 与块修复的机制见 HDFS 读写流程与副本放置策略;StandbyException 背后涉及的主备切换与 QJM 原理见 HDFS 高可用(QJM、ZKFC、Federation);「3 个 DN + 副本 3」的脆弱性,正是 纠删码 vs 三副本存储策略 讨论的存储策略权衡。小集群案例的配置如下(hdfs-site.xml):
<property>
<name>dfs.client.block.write.replace-datanode-on-failure.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
<value>NEVER</value>
</property>
为什么这样配:默认策略下,写失败时客户端会尝试寻找另一个数据节点替换坏节点,这在 DN 数量充足时是好的自愈行为;但节点数等于副本数时没有「另一个节点」可用,客户端会一直尝试直到整体失败。设为 NEVER 后写失败直接报错,行为可控。注意这属于 HDFS 客户端侧配置,需要同步到所有客户端。
本节要点:运维节奏三件事——主子集群操作先 DEMOTE(铁律);复活/替换备好 bootstrap_params.conf 与 Kerberos 参数、catalog 大了先评估 TSCatalogInvite;HDFS 健康检查固化成习惯(fsck -showprogress、du 对比、NN 主备、DN 堆、ulimit、快照)。
4 最佳实践清单¶
- 多主子集群下,停某个主子集群前先 DEMOTE:直接 stop 会让整个数据库 READONLY;单主子集群无法 DEMOTE(官方要求至少保留一个 primary),停它 = 整库停机、按停机窗口安排。为什么:主子集群承载主分片订阅,是数据库的法定人数。→ Eon双主子集群的注意事项
- 复活数据库(revive_db)前备好 bootstrap_params.conf(Kerberos 参数):为什么:复活时缺少 Kerberos 认证参数会直接报公共存储权限错误(日常重启不需要该文件)。→ Eon数据库复活时报公共存储文件权限错误
- keytab 变更后立即做启动验证:为什么:Eon 启动会校验 KerberosKeytabFile,错误票据导致卡 Inviting cluster,且删除配置项会被自动修复,绕不过去。→ Eon数据库因为票据不对导致的启动失败
- FileAlreadyExistsException 先查 HDFS 写吞吐:为什么:根因是 HDFS 60 秒 lease 超时;对策是调大 DN/NN 堆内存,临时降低 MaxUploaderWorkerThreadsPerDataTarget 止血。→ Eon同步文件到hdfs报FileAlreadyExistsException错误
- 空间不释放按固定顺序清理:为什么:先查 HDFS 快照,再 TombstoneProcessingBatchSize/S3DeleteBatchSize 调参 → make_ahm_now → sync_catalog → clean_communal_storage → flush_reaper_queue,顺序不能乱;HDFS 满了要先手动删文件。→ Eon公共存储文件不删除问题
- StandbyException 别只盯主备切换:为什么:先 hadoop fs -get 验证文件块完整性,损坏块要重跑账期或从 HDFS 修复。→ 查询表报Operation category READ is not supported in state standby错误
- max open files 改完必须重启 Hadoop 进程:为什么:进程级限制在重启后才更新,用 /proc/pid/limits 验证,否则表现为 UnknownHostException。→ Eon数据库执行insert报 Invalid hostname
- fsck 全库扫描加 -showprogress:为什么:默认方式耗时长易超时,加进度输出可避免 SocketTimeoutException。→ Error while executing hdfs fsck command
- 小 HDFS 集群(节点数 = 副本数)设置 replace-datanode-on-failure.policy=NEVER:为什么:没有可替换的备用节点时,默认策略只会让写入反复失败。→ Eon报错Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try
- 控制 catalog 大小:为什么:数十 GB/节点的 catalog 会拖垮启动与节点替换(案例停服 15 小时),需定期清理对象并规划业务改造。→ Eon 数据库替换节点过后节点启动卡在等待邀请步骤且重启数据库失败
- 计划 revive/复制的停机前手动执行
SELECT sync_catalog();:为什么:catalog 默认每 5 分钟同步一次到公共存储,停机可能丢最后几分钟的元数据变更,而 catalog 正是 revive 复活的依据(官方文档「Synchronizing metadata」章节推荐)。 - 大事务加载失败时检查 UseDepotForWrites:为什么:UseDepotForWrites=1(默认)时,单事务加载量超过子集群全部 depot 之和会直接失败;官方解法是设为 0,让数据直写公共存储(官方文档「Depot management」章节)。
附录:新手常见疑问(FAQ)¶
Q1:Eon 和 Enterprise 一眼怎么区分? 看数据权威副本在哪:Enterprise 的权威数据分布在各节点本地磁盘;Eon 的全部权威数据在公共存储(本文即 HDFS),节点本地只剩 depot 缓存。运维上的直观差异:Eon 加节点 = 加算力,不需要搬数据。
Q2:depot 丢了会怎样?要恢复吗? 数据一条不丢——仓库(公共存储)才是唯一真相,depot 只是货架。depot 损坏的代价是性能下降(查询要多跑仓库),节点重新订阅分片后 depot 会重新填充,无需人工恢复。
Q3:为什么建库必须用 webhdfs:// 而不是 hdfs://? 官方文档明确「You cannot use the hdfs scheme」——Vertica 通过 WebHDFS(HTTP 协议)访问公共存储,与客户端直连 DataNode 的 hdfs:// 协议不同。HA 或 Kerberos 环境还需要在 bootstrap_params.conf 里带上 HadoopConfDir 与 Kerberos 系列参数(见 3.2)。
Q4:报错里怎么快速判断是 HDFS 还是 Vertica 的问题?
看关键词:带 WebHDFS exception、UnknownHostException、StandbyException、lease 字样的,几乎都是 HDFS 侧问题在数据库的投影,按第 2 节开头的导航表对号入座。反过来,报错只涉及 Vertica 内部组件、且公共存储读写正常时,才往数据库自身排查。
Q5:数据库突然 READONLY 了怎么办? 先查两件事:是不是停了(或掉了)主子集群——主子集群承载主分片订阅,是数据库的「法定人数」;是不是有节点宕机导致分片订阅丢失(Eon 逻辑相邻节点宕机会自动 READONLY)。对应处理:恢复/升回主子集群(见 2.5),或让节点重新订阅分片。
Q6:Enterprise 想迁到 Eon 有捷径吗?
有:Vertica 提供 MIGRATE_ENTERPRISE_TO_EON 函数完成目录转换与数据迁移(10.0 及以上版本支持),迁移后从公共存储 revive 即可,详见 怎样将企业模式的 Vertica 数据库迁移到 EON。
本文技术细节来源:知识库故障案例(见各节「来源」引用)与官方文档 60.ofdocs/vertica_docv26.2/chapters/09-eon-mode.md、21-apache-hadoop-integration.md。HDFS 读取机制补充参考 Vertica 读取 HDFS 文件的原理分析。