定义一单位有用工作
对于内部 CSV 导出,请求会创建导出记录;工作进程读取有界数据集、写入输出对象并将记录标记为完成。定义最大有用范围、时间限制和取消行为。使用隔离的队列、测试数据库和无法通知真实客户的目标。
将计算时间与数据库和存储等待区分开。单个作业时长数字会掩盖这些区别。在内存中构建整个文件与流式处理有界批次的可扩展性不同。保持队列消息足够小,以描述工作,而不嵌入客户数据或凭据。
通过设计使重复投递安全
使用持久导出标识符将尝试关联到一个逻辑结果。在持久状态中强制唯一性以及原子的所有权/完成转换。先检查导出是否存在,然后在单独的无保护步骤中插入,会让并发尝试发生竞态。发布对象并确认队列消息也构成一个失败边界。
# Illustrative contract, not queue implementation
job_type: export-account-report
logical_result: EXPORT_RECORD_ID
input_scope: AUTHORIZED_ACCOUNT_AND_DATE_RANGE
attempt_limit: REVIEWED_FINITE_LIMIT
completion: ONE_PUBLISHED_RESULT_FOR_THIS_EXPORT
retry: CLASSIFIED_TRANSIENT_FAILURES_ONLY
failed_result: INSPECTABLE_WITHOUT_CUSTOMER_SECRETSCelery 将延迟确认与幂等任务关联,并记录了在子进程终止后仍会发生确认的情况。队列选项并不会创造恰好一次执行。请审查系统的重新投递语义,并设计应用结果以容忍重试。
技术参考: Celery 任务行为.
在增加进程之前设定预算
对于一个假设的工作进程,每个活动导出使用 300 MiB,四个同时导出在运行时开销之前就已意味着约 1,200 MiB。这些是规划输入,不是基准。再加上数据库连接、查询内存、临时磁盘和输出带宽;进程数只是其中一个限制。
用一个活动导出和真实积压进行演练。在重复相同 API 流量的情况下增加到两个。比较完成的有用导出、最旧作业年龄、延迟、失败和主机压力。如果吞吐量几乎不提高而数据库等待增加,请停止增加并发。额外的 CPU 可能无法消除该瓶颈。
阻止失败造成更多负载
在重试之前对错误分类。临时存储中断可能是暂时性的;未授权账户或不支持的导出格式需要终止性错误或人工干预。使用有限尝试预算以及支持的退避和抖动延迟重试。保持失败作业可检查,并移除敏感字段。
为外部调用设置超时并设定整体任务预算。放弃一次尝试并不能证明其远程副作用没有发生。一次超时的发布可能已经写入了输出。应通过导出 ID 进行对账,而不是盲目再发布一个结果。
将工作进程纳入部署和恢复
按照旧工作节点文档化的关闭行为停止其上的新工作。让进行中的工作完成,或在已知截止时间下安全中断。测试在输出已写入但完成尚未记录之后发生崩溃的情况;替换尝试应找到一致的结果,而不是将其重复。
在重叠的发布版本之间保持消息格式兼容。新的 API 可能入队一个旧工作节点无法读取的负载。对契约进行版本管理,或对发布进行排序,以便在新消息出现之前已有受支持的消费者。将这些数据库写入方纳入 模式兼容性审查.
选择下一个要更改的约束
留下并发设置、重试策略、任务契约和经过测量的停止规则。如果昂贵的导出拖慢了小任务,考虑在提高全局限制之前使用具有独立预算的独立队列。如果在任何现实的导出负载下 API 延迟都受到影响,分离工作节点可能比扩大一个共享主机更有用。
在变更后重复相同的工作负载并保留对比。 API 与工作者场景 说明了 App 2 和额外内存如何进入选择。这些流程并不意味着托管队列、无限任务或自动扩展。
官方参考
本文档已针对本文进行审核。示例是规划练习,不是已在 PrivacyNodes 服务器上测试过的命令。请查阅你所安装版本的文档。