云原生容器编排工作流自动化任务调度后端【免费下载链接】argo-workflowsWorkflow Engine for Kubernetes项目地址https://gitcode.com/gh_mirrors/ar/argo-workflows点击查看免费下载本篇技术指南围绕 Argo Workflows v4.0.0 引入的分页性能优化Issue #13948展开讲解在归档工作流Archived Workflows分页查询场景下如何用 是否存在更多项HasMore探测代替昂贵的全表COUNT扫描从而显著提升大规模数据集的列表接口响应速度。读者将掌握该优化的设计动机、服务端与数据层的完整实现路径、采样计数兜底策略以及RemainingItemCount/continue字段在分页语义中的实际行为。背景归档工作流分页为何会成为性能瓶颈Argo Workflows 可以将已结束的 Workflow 持久化到数据库MySQL 或 PostgreSQL的argo_archived_workflows表中之后通过argo archive list或 UI 界面分页浏览。当归档数据达到数十万甚至上百万条时一次分页请求往往需要回答两个问题当前页要返回哪些数据通过LIMITOFFSET完成当前页之后还有没有更多数据传统实现通过SELECT COUNT(*)统计满足过滤条件的总行数再与offset limit比较。问题恰恰出在第二个问题上COUNT(*)需要遍历或扫描索引覆盖的所有满足过滤条件的行数据集越大这条统计查询越昂贵而在绝大多数翻页场景下调用方并不需要精确的剩余总数只需要知道还有没有下一页。官方在.features/released/v4.0.0/pagination-when-counting-workflows.md中明确记录了这次改动不再执行昂贵的全表扫描而是改用 LIMIT 查询去探测 offsetlimit 之外是否还存在记录。这一改动的落地横跨两层数据访问层新增HasMoreWorkflows接口与实现见 workflow_archive.go服务端 API 层仅在调用方显式要求剩余数量时才执行COUNT其余情况走轻量探测见 workflow_server.go。方案核心用Limit(1).Offset(offsetlimit)探测是否还有更多优化的关键思路非常朴素判断下一页是否存在只需尝试取一条记录而不是统计全部记录。在 workflow_archive.go 的HasMoreWorkflows实现中查询结构如下selector : s.SQL(). Select(uid). From(archiveTableName). Where(r.clusterManagedNamespaceAndInstanceID()) // ... 依次追加 namespace / namePrefix / startedat / creationtimestamp / finishedat / name 过滤条件 // 若存在标签过滤条件则通过 BuildArchivedWorkflowSelector 联表构建 selector selector.Limit(1).Offset(options.Offset options.Limit) var result []struct{ UID string } if err : selector.All(result); err ! nil { return err } hasMore len(result) 0这段代码的三个要点只选uid一列探测是否存在时无需拉取整行或解析 JSON 化的 workflow 字段最小化 IOLimit(1)Offset(offset limit)直接跳过当前页已经覆盖的行尝试取下一页的第一条以结果集是否为空判断hasMorelen(result) 0即表示还有下一页返回的布尔值只需 0/1 两种状态。需要指出的是该探测对过滤器的覆盖是完整的命名空间相等/不等、名称前缀、startedat起止区间、creationtimestamp、finishedat以及通过BuildArchivedWorkflowSelector引入的标签Label过滤条件都与列表查询保持一致因此探测结果与真实翻页结果不会出现语义偏差。WorkflowArchive接口的文档注释也明确说明HasMoreWorkflows是比统计全量用于分页快得多的方式。当归档未启用时null_workflow_archive.go 提供了空实现直接返回false保证无归档场景下行为一致且零开销。服务端调用链只有需要精确剩余数时才做 COUNTHasMoreWorkflows并非无条件替代CountWorkflows而是由调用方按需选择。在 workflow_server.go 的ListWorkflows处理流程中if options.ShowRemainingItemCount { archivedCount, err s.wfArchive.CountWorkflows(ctx, options) // ... totalCount liveWfCount archivedCount } else { totalCount liveWfCount // 仅作为起始值后续覆盖 }随后在填充响应元数据时if options.ShowRemainingItemCount { remainCount max(totalCount-int64(options.Offset)-int64(len(wfs)), 0) meta.RemainingItemCount remainCount } else { hasMore, err : s.wfArchive.HasMoreWorkflows(ctx, options) if hasMore { remainCount 1 } else { remainCount 0 } } if remainCount 0 { meta.Continue fmt.Sprintf(%v, options.Offsetlen(wfs)) }这里体现了完整的分页语义设计ShowRemainingItemCounttrue精确模式调用CountWorkflows计算确切剩余数meta.RemainingItemCount携带精确值供需要显示还剩 N 条的 UI 场景使用ShowRemainingItemCountfalse探测模式默认调用HasMoreWorkflowsRemainingItemCount只会是 0 或 1仅表达有无下一页两种模式只要判定还有更多数据都会设置meta.Continue offset len(wfs)客户端将其作为下一请求的continue参数继续翻页。该开关通过server/utils/list_options.go中的ListOptions.ShowRemainingItemCount字段透传见 list_options.go并提供了WithShowRemainingItemCount链式构造方法。也就是说这是 API 层既有的能力开关本次优化让它在默认关闭路径上获得了数量级的性能提升。兜底策略countWorkflowsOptimized的采样估算当调用方确实需要精确剩余数ShowRemainingItemCounttrue时CountWorkflows也做了阶梯式优化。看 workflow_archive.go常规路径若options.Limit 0或options.Offset 0即首页或未分页请求仍执行完整的COUNT(*)因为此时精确值不可避免优化路径当Limit 0 Offset 0时进入countWorkflowsOptimizedOffset 1000数据集规模有限直接执行精确COUNT避免估算误差Offset 1000对结果集执行Limit(1000)采样计数若采样结果sampleTotal 1000说明已到数据末尾直接返回采样值否则按result offset sampleTotal limit估算总数即认为数据量远超当前页此时精确值对分页 UI 已无实际意义估算足以支撑还剩很多的展示。这种设计把昂贵但精确的 COUNT 限制在小 offset 和首页场景把大规模翻页场景的开销约束在常数级别属于与HasMoreWorkflows配套的同一轮优化对应 CHANGELOG 中记录的feat(server): optimize pagination when counting workflows in archive. Fixes:#13948见 CHANGELOG.md。数据链路与兼容性整体调用链可以归纳为HTTP/gRPC ListWorkflows └─ workflowServer.ListWorkflows (server/workflow/workflow_server.go) ├─ ShowRemainingItemCounttrue → CountWorkflows → countWorkflowsOptimized采样估算 └─ ShowRemainingItemCountfalse → HasMoreWorkflows → Limit(1).Offset(offsetlimit) 探测 └─ 结果写入 meta.RemainingItemCount0/1与 meta.Continue几个值得注意的工程细节live 与 archive 的衔接列表同时包含集群内活跃 Workflow 与归档 WorkflowarchivedOffset options.Offset - liveWfCount用于把全局 offset 换算到归档表上的局部 offsetHasMoreWorkflows接收的同样是换算后的options保证探测位置正确见 workflow_server.go数据库兼容HasMoreWorkflows的实现不依赖 MySQL / PostgreSQL 方言特性两种数据库均可执行实现中仅Select(uid)避免了 Postgres 对workflowJSON 列 detoast 的开销该列在 ListWorkflows 中通过 CTE 优化见 workflow_archive.go测试覆盖服务端测试通过 mock 的HasMoreWorkflows验证了探测路径的剩余数计算见 workflow_server_test.go数据层 MySQL 集成测试则验证了归档列表与过滤器的实际行为见 workflow_archive_mysql_test.go行为兼容探测模式不修改RemainingItemCount的字段语义——它仍是一个非负整数只是精度从精确剩余数退化为是否非零客户端无需感知差异。适用场景与限制适用归档量庞大、UI/CLI 只需要下一页/上一页翻页能力的场景收益最为明显这也是本次优化的默认路径。限制若业务依赖RemainingItemCount展示精确剩余条目数需要显式开启ShowRemainingItemCount此时仍会走 COUNT 路径大 offset 下为采样估算值而非精确值countWorkflowsOptimized在Offset 1000时返回的是估算值不能用于需要精确总数的统计报表场景分页本身仍基于OFFSET实现深翻页超大 offset时HasMoreWorkflows的探测语句仍需跳过大量行数据库侧成本随 offset 增长该优化解决的是COUNT 全表扫描这一项开销而非 OFFSET 分页模型的固有问题。综上Argo Workflows 通过按需 COUNT LIMIT 探测 采样兜底三层策略将归档工作流分页中占比最高的统计开销降到了常数级是处理大规模归档数据时值得借鉴的性能设计模式。赞分享云原生容器编排工作流自动化任务调度后端【免费下载链接】argo-workflowsWorkflow Engine for Kubernetes项目地址https://gitcode.com/gh_mirrors/ar/argo-workflows点击查看免费下载相关推荐web-vmstats未来展望路线图、新功能规划与社区发展方向web vmstats未来展望路线图、新功能规划与社区发展方向 web vmstats是一款能够在浏览器中以美观方式展示Linux系统实时性能数据的工具通过运维Argo Rollouts与工作流引擎集成Argo Workflows协同Argo Rollouts与工作流引擎集成Argo Workflows协同 引言渐进式交付的自动化演进 在现代云原生应用部署中渐进式交付Progress云原生灰度发布DevOps后端PostgREST 分页与计数全指南Range 请求头、limit/offset 参数与 Prefer: count 三种计数策略PostgREST 分页与计数全指南Range 请求头、limit/offset 参数与 Prefer: count 三种计数策略 PostgREST 将 P后端API网关上一篇终极指南5分钟将小米智能设备接入HomeAssistant的完整教程下一篇Wangle框架教程构建高性能C异步服务的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
