目录
1.背景
conductor推荐用dynomite做存储,但大多数公司并不会有这样的存储层基础,反而是redis集群都有,那么如果只是用redis做集群,conductor的数据可靠吗?如果redis异常,conductor是什么表现?
基于上述问题对conductor的数据进行分析。
2.示例流程
流程图 | worker定义 |
---|---|
![]() | ![]() |
3. redis的数据:
3.1 初始状态下redis数据:
每一个worker都有一个key,POLL_DATA 是hash接口,默认情况下存储的数据为:
3.2 注册一个workflow后redis数据
新增两个key:
其中:
- conductor_zlcft.test.WORKFLOW_DEF_NAMES 保存所有注册的workflow的名字,是set结构
- conductor_zlcft.test.WORKFLOW_DEF.coreSatelliteOpen 保存的是具体的workflow的元数据,hash接口,key为版本号,value为定义的dsl json
3.3 启动一个workflow:
3.3.1 workflow相关的数据
workflow运行时数据插入redis中,其中记录了workflow执行时的元数据(definition)和启动任务时实际的入参:
每一个workflow对应的workflowId(即实例id),会按天聚合存储:
conductor_zlcft.test.WORKFLOW_DEF_TO_WORKFLOWS.coreSatelliteOpen.20221112
同时,每一个workflow还有一个总的workflowId集合:
conductor_zlcft.test.CORR_ID_TO_WORKFLOWS.coreSatelliteOpen_id
执行中的workflow信息会保存下来(当workflow执行完起workflowId会被删除)
conductor_zlcft.test.PENDING_WORKFLOWS.coreSatelliteOpen
每一个workflow实例都有一个单独的hash结构记录其任务调度情况:
3.3.2 TASK相关的数据:
每一类task的每个执行数据都会保存,其中记录了每个任务执行时对应的元数据(definition)和实际的执行参数
2.3.3.消息队列
MESSAGE队列中存储的是 执行过的workflow信息
QUEUE队列中存储的是调度中的workflow信息 ,且执行完会被删除;
每一类task都有单独的队列:
conductor_zlcft_queues.test.QUEUE.checkFundStatus.c
采用有序set,记录了入队列的顺序,task执行完会被删除
每类执行中的task会单独维护一个set结构:
conductor_zlcft.test.IN_PROGRESS_TASKS.checkFundStatus
该类任务执行结束,该key被删除
4.ES数据:
4.1数据的双写:
做任务驱动时,会有更新库中任务、流程的动作,都会写入es数据:
com.netflix.conductor.core.execution.WorkflowExecutor#decide方法中:
com.netflix.conductor.core.dal.ExecutionDAOFacade#createWorkflow
更新任务:
com.netflix.conductor.core.dal.ExecutionDAOFacade#updateTasks
注:若配置异步写es,则是在流程执行完成时一起写入,存在宕机丢失的可能性
更新流程:com.netflix.conductor.core.dal.ExecutionDAOFacade#updateWorkflow
此时写入es的数据主要用作运行时数据的检索,参考:
com.netflix.conductor.service.WorkflowService#searchWorkflows
4.2 数据的归档:
workflow实例数据可以在es中进行归档,归档的数据记录了每个流程执行过程中的入参、入参等数据;
若数据进行了归档,只要redis中的元数据还在,那么可以重试任意一个workflow实例
com.netflix.conductor.core.dal.ExecutionDAOFacade#removeWorkflowIndex
在删除workflow实例信息时,默认会进行归档操作,es的json体中新增两个字段 rawJSON、archived
其中 :rawJSON 就是workflow实例信息的字符串,包含所有信息,在restart已删除的实例时,就是取es中的这部分数据 , archived字段此时会被赋值为true
4.3.1 触发时机
该方法主要由 com.netflix.conductor.core.dal.ExecutionDAOFacade#removeWorkflow 触发,而removeWorkflow的触发时机有:
1.启动一个workflow发生异常时:com.netflix.conductor.core.execution.WorkflowExecutor#startWorkflow()
2.外部服务调用接口删除时:com.netflix.conductor.service.ExecutionService#removeWorkflow
3.流程成功执行完成(Completed)时:
com.netflix.conductor.core.execution.WorkflowExecutor#endExecution
com.netflix.conductor.core.listener.WorkflowStatusListener#onWorkflowCompletedIfEnabled
4.流程终止(TERMINATED)时:
com.netflix.conductor.core.execution.WorkflowExecutor#terminateWorkflow
com.netflix.conductor.core.listener.WorkflowStatusListener#onWorkflowTerminatedIfEnabled
4.3.2 启用归档配置:
若需要进行workflow归档,需要两步操作:
1.在conductor服务的application.properties文件新增配置: conductor.workflow-status-listener.type=archive
2.定义workflow时新增属性 workflowDefinition=true
其对应的配置类为:com.netflix.conductor.contribs.listener.archive.ArchivingWorkflowListenerConfiguration
5.结论
数据分列 | 说明 |
---|---|
元数据 | 用于定义workflow 和 task |
执行流水 | 每个创建的workflow实例执行时的过程数据,包含workflow的出入参、每个task节点的出入参 |
队列数据 | 主要用于任务的调度 |
数据类型 | 特点 |
---|---|
redis元数据 | 注册workflow时入库,永不过期 每次启动实例时、执行task时查询 |
redis实例数据(运行时数据) | 执行workflow实例时入库,永不过期 restart实例时查询 查看历史流水时查询 |
redis队列数据 | 做任务调度时入库,任务执行完立即删除 |
es元数据 | 无 |
es实例数据(运行时数据) | 执行workflow实例时入库,永不过期 restart实例时查询 查看历史流水时查询(需开启归档功能) |
es队列数据 | 无 |
1.若元数据丢失,对应的workflow不可用
对应的redis key为: conductor_zlcft.test.WORKFLOW_DEF_NAMES conductor_zlcft.test.WORKFLOW_DEF.coreSatelliteOpen
2.元数据属于最开始注册到conductor中的,不会变,开启redis持久化机制后,理论上元数据不会丢失,因此conductor接redis理论上数据持久化的不会阻塞业务使用
3.es的双写默认是用来做数据检索,另外可以用作运行数据的归档,若开启了es的数据归档功能,则只要redis中的元数据还在,那么可以重试任意一个workflow实例