Presto 设计与实现(十三):查询状态机
为了对 SQL 查询的关键步骤进行标记,Presto 定义了 SQL 查询状态,使用枚举 QueryState 表示,同时使用类 QueryStateMachine 管理 SQL 查询当前状态、SQL 消耗资源和查询状态间合法的切换,每个 SQL 查询只有一个 QueryStateMachine 实例。
下面是 QueryState 状态图:
说明:
WAITING_FOR_PREREQUISITES:任务初始状态, 客户端通过 Presto Client 调用 QueuedStatementResource HTTP 服务的 SQL 查询接口,QueuedStatementResource 接受客户端查询请求,创建 Query 查询对象存储在本地缓存 ConcurrentHashMap 中;
QUEUED:队列状态, DispatchManager 在分发查询前,会对 Query 进行权限相关的校验,校验通过会将 Query 转换为 DispatchQuery 对象;
WAITING_FOR_RESOURCES:等待资源状态,ClusterSizeMonitor 会校验是否有充足的工作节点,校验规则比较当前可用工作节点数量是否大于等于配置的最小工作节点数量,如果充足会立刻执行;否则会等待一段时间默认 5 分钟,超时任务失败。
DISPATCHING:分发状态, SqlQueryExecutionFactory 根据 DispatchQuery 创建 SqlQueryExecution 对象,SqlQueryManager 在 SqlQueryExecution 执行前注册事件监听任务状态变更,调用 SqlQueryExecution.start 方法执行任务;
**PLANNING:逻辑计划生成中状态, **SqlQueryExecution.start 方法内部会进行词法分析、语法分析、生成语法树、生成逻辑计划、逻辑计划优化和生成物理计划,最后通过 LegacySqlQueryScheduler 将物理计划转换为多个 Stage 每个 Stage 对应多个 RemoteTask;
STARTING:等待运行状态, LegacySqlQueryScheduler 执行周期方法 schedule 前,正在生成 Stage 和 Task 或已经全部生成之间的等待状态;
RUNNING:任务运行状态, LegacySqlQueryScheduler 执行周期方法发现 queryStateMachine 的任务状态为 STARTING,并且已经生成了 RemoteTask,会通过 queryStateMachine 将任务状态从 STARTING 切换到 RUNNING;
FINISHING:完成中状态, 当前会话如果声明了事务,会调用 transactionManager.asyncCommit 方法远程提交事务,如果提交失败,状态会从 FINISHING 切换到 FAILED,如果提交成功或者未声明任何事务,会进行后续的关闭监控和释放资源等操作;
FINISHED:完成状态, 完成资源释放后状态会从 FINISHING 切换到 FINISHED,查询最重执行完毕
FAILED:任务失败,任何一个环节出错都可能导致失败,例如 SQL 语句解析错误、任务取消、没有足够工作节点和任务超时等。
版权声明: 本文为 InfoQ 作者【冰心的小屋】的原创文章。
原文链接:【http://xie.infoq.cn/article/668a71b00bfe5a949c2a888f1】。文章转载请联系作者。
评论