camunda large data - modric2jeff/archive GitHub Wiki
下面把遇到“百万级历史数据导致接口/查询慢、External Task 执行慢”的问题拆成:原因 → 优先级排序的优化清单(可立即做 / 中期 / 长期)→ 具体配置/SQL 示例 → 诊断要点和升级说明。结论中我也列出 Camunda 7 的新版本相关信息。
主要瓶颈通常是历史表(ACT_HI_)暴涨导致查询/索引扫描变慢、作业/外部任务获取的数据库争用与回退(backoff)策略、以及数据库维护/索引不佳;优先处理 history cleanup / TTL / 索引 / job-executor & external-task 配置 / 分区或归档 能最快见效。([Camunda 7 文档]1)
- 历史表(ACT_HI_*)行数到百万/千万时,历史查询、JOIN、DELETE、扫描都会变慢(索引和统计信息失效也会放大问题)。([Camunda 7 文档]2)
- 如果没有配置或没有运行 History Cleanup / TTL,历史会持续堆积。Camunda 用
REMOVAL_TIME_列做高效删除。([Camunda 7 文档]1) - Job executor / external-task 的获取逻辑有 backoff/long-polling 行为,错误配置会导致高并发时大量争用或延迟。([Camunda 7 文档]3)
- 大量历史数据还会导致数据库 I/O、锁争用、连接池耗尽与索引 bloat(尤其在大量删除后若不做 vacuum/reindex)。(通用 RDBMS 原则)
-
启用并配置 History Cleanup / TTL(强烈推荐)
- 在 BPMN 中为流程定义加上
camunda:historyTimeToLive="P30D"(示例:30 天)或通过 API/管理界面设置。然后启用 history-cleanup job(cron)。这能把旧历史标记并定期删除,立竿见影降低历史表大小。([Camunda 7 文档]1)
- 在 BPMN 中为流程定义加上
-
检查慢查询日志 & 建立必要索引
- 把数据库的 slow query 打开,找出频繁的 SQL(例如针对 ACT_HI_PROCINST、ACT_HI_ACTINST 的查询)。根据慢查询建立索引(示例:
CREATE INDEX PROC_DEF_ID_END_TIME ON ACT_HI_PROCINST (PROC_DEF_ID_, END_TIME_);)可大幅降低特定查询时间。务必和 DBA 用 EXPLAIN 验证。([Camunda 8 文档]4)
- 把数据库的 slow query 打开,找出频繁的 SQL(例如针对 ACT_HI_PROCINST、ACT_HI_ACTINST 的查询)。根据慢查询建立索引(示例:
-
数据库维护(VACUUM/ANALYZE / rebuild indexes / update statistics)
- 如果刚做过大批量删除,先执行 DB 的整理(Postgres 的 VACUUM FULL / REINDEX 或等效操作),恢复查询性能。
-
调整 External Task 客户端长轮询与回退
- 在外部 worker/client 设置
asyncResponseTimeout(例如120000ms),把 backoff 设置适当(或 0)并设置合理的maxTasks与lockDuration(lockDuration 设置为预计最长处理时间)。这能减少无谓的频繁查询并提高吞吐。([Camunda Forum]5)
- 在外部 worker/client 设置
-
调整 Job Executor 配置(根据负载做微调)
- 关键配置:
maxJobsPerAcquisition、maxWait(默认 60s,可降到 e.g. 1000 ms 以减少延迟)、线程池大小等。注意集群场景下不要把maxJobsPerAcquisition设置过高以免某节点“抢占”全部作业。([Camunda 7 文档]3)
- 关键配置:
-
降低历史等级(historyLevel)或为某些流程使用较低的 TTL
- 如果业务允许,把
HISTORY_FULL→HISTORY_ACTIVITY或针对不重要流程设短 TTL,可明显降低历史数据量与索引负担。([Camunda Forum]6)
- 如果业务允许,把
-
优化事务边界 / 异步化
- 将长耗时任务改为 async-before/async-after 或 External Task,从而缩短单事务做的工作量,减少锁持有时间。
-
按查询场景建立物化/索引表
- 对于经常按某变量/客户 id 查询流程状态的场景,可以维护一个轻量“索引”表(通过 listener 更新),用于快速查找,而不是直接扫描 HI 表或复杂 join。([Stack Overflow]7)
-
分区或归档历史数据(Postgres 分区 or ETL 到数据仓库)
-
把 Reporting/查询导向只读副本
- 把长时间的历史查询(报表/Optimize)指向 DB 的只读副本,避免对主库争用。
-
考虑把 runtime 与历史分离(谨慎)
- 理论上把 runtime 与历史分离到不同数据库能把主库轻量化,但 Camunda 的一些功能(Cockpit、工具)依赖两部分数据;分离并不简单,需要评估兼容性与工具影响。([Camunda Forum]9)
- 在 BPMN 文件里为一个 process 定义 TTL(ISO 8601 期间):
<process id="myProcess" name="..." isExecutable="true" xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
camunda:historyTimeToLive="P30D">
...
</process>(P30D = 30 天)。([Camunda 7 文档]10)
-
External Task client(示例参数、Spring Boot client 配置):
-
asyncResponseTimeout = 120000(长轮询 2 分钟) -
maxTasks = 根据 worker 并行度设定(例如 10/20) -
lockDuration = 预计处理最长时间(ms)这些在官方 External Task client docs / starter 中有说明,长轮询能减少空轮询导致的 DB 压力。([Camunda 7 文档]11)
-
-
Job executor(可以在 engine 配置/部署描述文件或 Spring Boot 配置调整):
-
maxJobsPerAcquisition(默认较小,按负载增减) -
maxWait(单位 ms,默认 60000,可减小以降低作业延迟,但会增 DB 访问频率) -
jdbcBatchProcessing(视 DB 类型决定是否开启/关闭)([Camunda 7 文档]3)
-
-
索引示例(根据你查询热点字段):
CREATE INDEX PROC_DEF_ID_END_TIME ON ACT_HI_PROCINST (PROC_DEF_ID_, END_TIME_);
-- or index on REMOVAL_TIME_ if you query by removal_time
CREATE INDEX HI_PROCINST_REMOVAL_TIME ON ACT_HI_PROCINST (REMOVAL_TIME_);(先用 EXPLAIN 确认再建索引,避免无用索引占空间)。([Camunda 8 文档]4)
- Camunda 在 7.x 的后续版本里既有 bug fix 也会有一些性能/DB 相关改进(比如 history-cleanup 的改良、外部 task / REST 的改进、job executor 的配置项等)。Camunda 在 2025 年也有 7.24(alpha / LTS)相关发布、并有 7.24 LTS 的计划 (2025-10-14) —— 升级可能带来 bug 修复与小幅性能优化,但不是“针对任意大表立刻可用”的魔法开关;升级前应做性能回归测试。([Camunda 7 文档]12)
- 打开数据库 slow-query,抓最慢的 10 条 SQL,EXPLAIN 分析(找出是否是 seq scan / index scan / bad plan)。
- 检查 ACT_HI_* 表行数、索引大小与 bloat(和 DBA 合作跑 VACUUM/ANALYZE)。
- 确认
REMOVAL_TIME_是否存在、TTL 是否正确、history-cleanup job 是否在运行。([Camunda 7 文档]1) - 查看 external-task fetchAndLock 模式与 client 配置(asyncResponseTimeout/backoff/maxTasks/lockDuration)。([Camunda Forum]5)
- 观察 job-executor 日志,是否在大量 backoff 或报错,以及作业获取间隔(maxWait)。([Camunda]13)
- 大规模删除历史后一定要做索引重建 / 更新统计信息,否则查询仍可能很慢。([Flowable]14)
- 分区/更改表结构前请做备份并在非生产环境充分测试(分区对外键、备份策略和应用查询有影响)。([Stack Overflow]15)
- 更改 history level(减少记录)会丢失审计/历史信息,需评估合规影响。([Camunda Forum]6)
如果你把下面几项信息贴上来,我可以基于你的环境给出更具体的动作清单和 SQL:
- 使用的数据库(Postgres/MySQL/Oracle)和版本;
-
SELECT COUNT(*)的关键表(ACT_HI_PROCINST、ACT_HI_ACTINST、ACT_RU_EXECUTION 等)的行数; - 一条代表性的慢 SQL(或者 slow query 的 top1),以及 EXPLAIN 输出的计划(如果可以)。
或者我可以按上面优先级帮你生成:TTL 配置脚本、推荐索引 SQL、external-task client 配置样例和一份给 DBA 的检查清单。
需要我先从帮你分析一条慢 SQL + 给出索引建议开始吗?(把慢查询语句和你用的 DB 类型贴来我就可以分析)