分布式调度系统次重点
# 01.项目模块说明
# 1、配置管理层(Web-Server)
# 1)配置管理
- 团队管理,项目管理(流水线最终归属一个项目里)
- 通知管理(飞书通知、邮件通知、通知模版定义)
- Webhook管理(回调URL,Header、Body)
- 仓库配置(仓库地址,认证token)
- 制品库配置(制品地址、认证秘钥)
- 资源配置(K8S、测试车、台架、实机、虚机)
- 应用配置(打通与Apollo配置中心数据拉取覆盖,区分dev、prod环境,用户部署时将参数设置到原子环境变量中,或者k8s secret中)
- 扩展属性配置(支持用户自定义实例页面属性显示)
# 2)流水线管理
- 流水线配置
- 配置 实例变量
- 触发规则(GitLab触发、Webhook触发、定时触发、人工触发)
- 重试规则(重试条件
变量=某一个值或者正则时
,重试间隔,最多多少次) - 并发规则(流水线最多能够启动多少实例),终止最早实例 或 禁止新实例触发
- 通知规则(实例成功,实例失败,变量符合指定值或正则)
- 回调规则(header、body数据根据规则替换成环境变量数据)
- 管理权限(可编辑人、可触发人、运营权限)
# 3)原子配置
- 原子配置
- 源原子(指定要拉取的Gitlab仓库地址,分支名,Tag)
- 自定义原子(支持Python、Shell、Java等多种环境)
- 远程原子
- 启动原子(URL、Method、Header、Body)
- 终止原子(URL、Method、Header、Body)
- 原子终止回调(支持变量替换)
- 子流程原子
- 原子触发子流程实例创建(将父流水线参数携带到子流程中)
- 重试策略(创建新实例,重试旧实例)
- 支持任意节点重试(调度服务逐级启动父实例,原子逐级启动子实例)
- Docker构建原子
- 关联源原子、镜像仓库、镜像名称、镜像Tag
- Dockerfile、Dockerfile路径(Kaniko构建完成自动推送Harbor)
- 部署原子
- 关联“应用参数”+环境“dev/prod”等(原子部署时会引用 替换标记)
- 指定 “集群资源”,命名空间、部署名称
- 或者指定gitops路径参数执行部署
- 流控原子(指定哪些原子不执行直接跳过)
- 人工原子(重要步骤用来人工审批节点,对接内部工单系统)
# 4)DAG编排和触发
- DAG任务编排
- 实例包含多个阶段,阶段包含多个原子,原子根据依赖关系编排并行串行
- 编排好的任务最终生成 DAG(有向无环图)
- 触发流水线
- 提供用户接口,用于触发调度实例(GitLab触发、Webhook触发、定时触发、人工触发)
- 在实例创建后,通过 MySQL 事务将实例ID推送至 RabbitMQ 的
实例ID队列
中
# 5)效能大盘
流水线效能大盘
- 开始时间、结束时间、调度等待耗时、业务执行耗时、业务等待耗时、业务执行时间
效能统计(统计大盘、实时大盘、组大盘)
- 实例数量、原子数量、耗时
- CPU、GPU、内存 使用量 使用率
- 车辆、台架 资源使情况
资源Quota
- 1.流水线实例, 2.原子实例, 3.CPU requests, 4.CPU limits, 5.MEM requests, 6.MEM limits, 7.GPU', 台架数量,测试车数量
# 2、调度引擎层
# 1)派发引擎服务
- 在实例创建后,通过 MySQL 事务将实例ID推送至 RabbitMQ 的
实例ID队列
中 派发引擎服务
根据实例ID和优先级配置+DAG配置
,将待执行原子批量推送至 RabbitMQ 的原子ID队列
(根据优先级分别有自己的队列)
# 2)预处理服务
预处理服务
根据实例ID、原子ID,获取原子详细配置和要执行的命令参数
- 调度集群信息 or 车辆类型 or 台架类型(根据Agent Tag标记识别)
- 根据上面参数生成包括创建K8S Job的YAML文件等最终执行结构体,并推送到
原子封装队列
# 3)调度服务
- 去中心化设计(大型项目)
1、每个调度服务实例启动后注册到 ETCD,维护服务列表和健康状态
2、所有调度服务实例并行监听 RabbitMQ 队列,尝试抢占消费任务
3、成功消费任务后,调度服务获取 Redis 锁(任务ID为 key)防止重复消费
4、如果锁获取成功,调度服务执行任务;如果锁获取失败,丢弃该任务
5、任务执行完成后,调度服务发送 RabbitMQ `ack`,并更新任务状态到 Redis
6、如果任务执行失败,RabbitMQ 重新将任务放回队列,等待其他实例消费
7、如果多次执行失败,任务会写入到redis中,由监控告警人工介入处理
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3、任务执行层(GRPC服务层)
# 1)GRPC Server(任务引擎服务)
- 任务下发
gRPC服务端
接收来自调度服务的任务,根据内存中 gRPC客户端 上报的Tag标记,将任务发送给匹配的客户端
- 去中心化调度&故障转移
- 如果检查发现自己没有可用的指定Tag客户端,或者客户端异常无法正常执行
任务引擎服务
会担当调度服务
的功能,从etct中获取其他可用的gRPC服务端派发- 每次被重新调度TTL值加1,当超过预设TTL值时会上报TTL超时状态到RabbitMQ
- 客户端连接管理
- 客户端启动后会根据公网域名和路由策略分配到指定gRPC服务端,并建立gRPC长连接
- 服务端根据客户端ID把连接写入到内存中,并同步到Redis中(服务端、客户端、Tag标记对应关系)
- 客户端会与服务端保持心跳机制,服务端更新客户端信息到ETCD中,ETCD中有过期策略,心跳3次失败就会自动过期
- 日志收集
- 客户端使用gRPC长连接把执行日志上报给服务端,服务端根据
实例ID/原子ID
存储日志到挂载盘 - 原子结束后把原子日志文件上报到OSS存储服务中,并将存储URL替换MySQL中的挂载盘路径
- 运行时日志通过挂载盘直接读取给客户端,超大日志只读取指定长度日志,同时提供存储地址,用户可自行下载
- 客户端使用gRPC长连接把执行日志上报给服务端,服务端根据
- 原子状态同步
- 客户端将原子成功 & 失败 等状态同步到服务端,服务端将状态写入RabbitMQ中,并同步到Kafka中,方便用户订阅
# 2)GRPC Client(执行器Agent)
- 接收任务
- 客户端接收并解析来自 Server 的原子任务,并根据任务类型执行任务
- K8S任务:K8S Job任务,使用上面封装好的K8S Job结构体直接启动执行
- 脚本任务:直接在本机执行(台架和测试车等都是脚本任务)
- 将执行任务POD Name或者台架信息上报到服务端,服务端更新绑定信息到MySQL和Redis缓存中
- 客户端接收并解析来自 Server 的原子任务,并根据任务类型执行任务
- 上报日志
- K8S任务日志:直接根据POD NAME从K8S接口中拉取数据流发送给服务端
- 脚本执行日志:通过gRPC长连接实时同步到服务端,并同步写入到本地(失败重传)
- 执行状态上报
- 客户端根据执行成功失败情况将原子执行状态上报到服务端
- 建立连接
- gRPC客户端启动后会尝试与服务端建立连接,如果失败会一直重试直到建联成功
- 客户端根据直接执行能力上报Tag标记(测试车、P1台架、P2台架、K8S等)
- 建联成功后会有一个goroutine一直与服务端保持心跳服务
- 公网认证服务
- 如果是车端Agent或者外网台架,客户端通过Openssl生成公钥私钥对
- 通过认证Token认证,调用http外网域名接口上报到云端,云端审批后即可完成认证
- 完成认证后客户端使用私钥对URL参数加密,云端解密,成功后即可完成gRPC连接
# 4、服务保障层
# 1)原子状态同步服务
- 原子状态同步,负责同步任务执行的状态
- 消费 RabbitMQ 的状态队列,将任务的执行状态更新至 MySQL 数据库中,确保任务状态的实时监控
- GRPC Server将原子执行状态上报到 RabbitMQ 的状态队列
- priorityAtomSync JOB 消费状态队列,并将状态更新到MySQL
- 原子状态同步充分考虑了幂等性问题
- 原子状态上报时携带当时上报时间的毫秒级时间撮,保证久状态不会覆盖更新新状态
# 2)原子执行器
- 原子执行器由执行器和代码片段两部分组成,代码片段可以是官方的,也支持用户自定义
- 通过挂载盘或 wget 动态下载的方式,执行指定路径下的 GO 二进制文件或脚本
- 执行脚本时,会根据环境变量传递的实例和原子ID,获取并注入任务参数,实现原子任务之间的数据共享
- 执行完成后,将产物变量信息上报至平台,原子Agent封装了执行器中的逻辑,可以直接执行
- 官方代码片段主要包括
- 源原子(指定要拉取的Gitlab仓库地址,分支名,Tag)
- 远程原子(定义启动,终止的调用URL,类似与Postman,串联业务)
- 子流程原子(用来触发其他子流程,实时同步执行百分比)
- Docker构建原子(利用Kaniko构建镜像并推送到Harbor)
- 部署原子(使用K8S配置将服务部署到K8S中)
- 流控原子(指定哪些原子不执行直接跳过)
- 人工原子(重要步骤用来人工审批节点,对接内部工单系统)
- 命令行执行,自定义原子(支持Python、Shell、Java等多种环境)
- 比如用户可以git clone下载一个python脚本,执行python脚本
- 也可以直接执行Shell脚本等
# 3)监控服务
告警服务
实例超时启动告警
原子超时启动告警
资源使用率超过预定阀值告警
原子执行时长超过遇到值报警
报警数据展示、报警收敛、报警升级
重新调度服务(主要用来做兜底)
- 日志再收集:
- 定时任务检查原子执行结束但没有日志的原子
- K8S Job类型:重新从K8S中拉取数据流,上传到OSS,更新日志链接
- 脚本类型:告警,并等待测试车、台架等在线后重新上传(会在本地留存日志数据)
- 原子重新调度
- 检查最近2小时内失败原子配置,如果设置了重试策略,根据重试策略重新调度
- 日志再收集:
# 4)效能看板
流水线效能大盘
- 开始时间、结束时间、调度等待耗时、业务执行耗时、业务等待耗时、业务执行时间
效能统计(统计大盘、实时大盘、组大盘)
- 实例数量、原子数量、耗时
- CPU、GPU、内存 使用量 使用率
- 车辆、台架 资源使情况
资源Quota
- 1.流水线实例, 2.原子实例, 3.CPU requests, 4.CPU limits, 5.MEM requests, 6.MEM limits, 7.GPU', 台架数量,测试车数量
任务执行监控
任务状态追踪:实时跟踪各个实例的执行状态,包括正在执行、已完成、失败、等待中等状态每个任务的执行进度可以在看板上清晰展示
任务详情展示:对于每个实例和原子任务,提供详细的执行日志和步骤信息,帮助用户快速定位和解决问题
性能指标监控
- 系统负载:展示调度系统的当前负载情况,包括消息队列的长度、服务器的CPU和内存使用率等关键资源的使用情况
- 执行延迟:分析和展示任务从触发到完成的延迟时间,帮助用户识别和解决潜在的性能瓶颈
- 吞吐量:展示单位时间内系统处理的任务数量,帮助用户评估系统的处理能力
资源利用情况
- Kubernetes 资源监控:对于采用 Kubernetes 作为执行环境的任务,效能看板提供对 Kubernetes 资源使用情况的监控,包括 Pod 数量、节点资源使用率等
- gRPC 连接状态:展示 gRPC Server 与 Client 之间的连接情况,追踪长连接的健康状态和响应时间
# 02.部门职能
# 1、生产链路
主要职责
- 自动驾驶数据的
采集
、处理
、标注
、存储
等工作 - 为
模型训练和算法优化
提供高质量的基础数据
- 自动驾驶数据的
数据采集与清洗:
- 利用车载传感器(如
摄像头、激光雷达
等)采集大量的道路行驶数据 - 并进行数据清洗和筛选,去除无效或噪声数据。
- 利用车载传感器(如
数据标注:
- 将采集的数据进行人工或半自动的标注,如对图片或视频中的行人、车辆、交通信号等进行标记,以支持机器学习模型的训练
- 例如,手动标注行人过马路、红绿灯状态等,确保数据的准确性
数据存储与管理:
- 维护大规模的数据存储系统,确保数据的有效存储、备份和高效读取,如在分布式存储系统中管理PB级的数据。
具体应用场景:
- 车队通过传感器每天采集上百TB的行驶数据,数据采集链路团队负责从车辆传感器到云端的整个数据流的处理,包括数据上传、清洗和存储。
# 2、路测链路
主要负责: 自动驾驶车辆的道路测试,验证自动驾驶系统在实际道路环境中的表现,确保算法在不同场景下的可靠性与安全性。
具体职责和业务举例:
- 路测计划制定: 根据不同的测试需求,设计测试路线和场景,覆盖城市道路、高速公路、停车场等多种复杂场景,确保自动驾驶系统的全面测试。
- 路测数据采集: 在路测过程中,实时采集车辆传感器数据、行驶轨迹、障碍物信息等,用于分析算法在实际环境中的表现。例如,测试自动驾驶车辆在拥挤城市路况中的避障能力。
- 结果分析与反馈: 对路测数据进行分析,如车辆的加速、刹车、转向、变道等行为是否符合预期。如果发现问题,将数据反馈至研发部门进行算法优化。
具体应用场景:
- 在自动驾驶车辆行驶过程中,路测链路团队安排车辆在不同天气条件下的复杂路况进行测试,并通过数据分析检查车辆的表现,保证自动驾驶系统的稳定性。
# 3、地图业务
主要负责: 高精度地图的构建和维护,为自动驾驶车辆提供精确的道路信息,辅助车辆进行路径规划和导航。
具体职责和业务举例:
- 高精地图制作: 利用激光雷达和其他传感器采集的道路信息,生成高精度的3D地图。这些地图包含详细的车道线、路标、交通信号等信息,精度通常达到厘米级。
- 实时地图更新: 确保地图数据的实时更新,反映道路上的最新变化(如施工、路障、新增交通设施等),以便自动驾驶系统能够及时调整路径规划。
- 地图融合: 将实时传感器数据与预先制作的高精地图进行融合,为车辆提供更准确的定位和环境感知支持。例如,车辆可以通过高精地图提前知道即将到来的弯道或交通灯位置。
具体应用场景:
- 地图业务部门构建的高精地图帮助车辆准确识别道路标线、交通信号等细节,使车辆能够在城市中的复杂交叉路口正确导航和通行。
# 4、PnC (Planning and Control,规划与控制)
主要负责: 自动驾驶系统中的决策、路径规划和车辆控制,确保车辆安全高效地从起点行驶到目的地。
具体职责和业务举例:
- 路径规划: 基于实时感知信息和高精地图,规划最优行驶路线,避免障碍物和其他交通参与者。例如,在拥堵的城市路段中,系统可以规划绕开拥堵路段的路线。
- 行为决策: 在自动驾驶过程中,做出如变道、减速、停车等行为决策。例如,当车辆遇到前方有行人过马路时,系统会通过感知和决策模块发出减速并停车的指令。
- 车辆控制: 根据规划的路径和行为决策,实时控制车辆的加速、转向和刹车,确保车辆平稳行驶。例如,在高速公路行驶时,车辆控制模块确保车辆在车道内保持稳定的车速和方向。
具体应用场景:
- PnC团队负责设计算法来处理复杂的交通场景,如当车辆遇到前方车辆突然减速时,系统能够实时规划变道动作,并控制车辆平稳变道,避免碰撞风险。
# 5、大规模仿真
主要负责: 构建大规模的虚拟环境,通过仿真测试自动驾驶系统的性能,评估系统在各种极端条件下的行为,减少实际路测的成本和风险。
具体职责和业务举例:
- 仿真场景构建: 创建不同的虚拟驾驶场景,包括城市道路、乡村道路、高速公路、恶劣天气等,模拟真实的驾驶环境。例如,模拟大雾天气下的高速公路行驶,测试自动驾驶系统的感知和决策能力。
- 仿真测试与迭代: 通过仿真平台批量测试自动驾驶系统的行为,评估车辆在不同路况下的决策准确性和行驶稳定性。仿真测试可以进行数百万次,并根据测试结果对算法进行优化。
- 异常情况处理: 在仿真过程中,模拟突发状况(如突然出现的障碍物、交通事故等),测试系统的应急反应能力。例如,测试车辆在紧急情况下的刹车反应是否足够快,能否有效避免碰撞。
具体应用场景:
- 仿真团队可以在虚拟环境中模拟真实世界中的千种驾驶场景,如车辆在冰雪路面行驶时的刹车测试,确保算法的鲁棒性,避免将未成熟的技术直接投入路测。