presto 查询调度流程 (Coordinator Scheduler)

news/2024/10/6 1:47:28

based on tag: 0.287

presto的 scheduler 是 SqlQueryScheduler 这个类控制的, 这个class主要是负责调度物理执行计划。调度具体的每个SqlStageExecution. 这个Stage可以当成Fragment的一个概念

他会先把所有的stage创建一个schedule计划。一共有两种schedule计划,一个是all-at-once,另一个是phased,还有一个 adaptive-phased (其实就是根据stage数量来决定到底是all-at-once还是phased).

        // AdaptivePhasedExecutionPolicy.java createExecutionScheduleif (stages.size() > getMaxStageCountForEagerScheduling(session)) {return new PhasedExecutionSchedule(stages);}else {return new AllAtOnceExecutionSchedule(stages);}

SqlQueryScheduler 的主要流程是什么呢?

  scheduler:schedules = // 每个 stages (section 可以理解为单个查询的所有SQL的fragment) 创建一个schedules while (schedules.all_finish()) {stage_wait_schedule = schedule.get_next_stages();stages.addAll(stage_wait_schedule)for stage in stages:stage.scheduler.schedule() // (这里是stage的scheduler,比如发async rpc, 分配split/计算节点)collect_block_schedule_result() // 收集block schedule resultwait_if_has_block_events() // 这里是等block result 的 future 最多等1s}

可以看到其实SQLSchedule的流程就是先获取下次要调度哪些stage,然后执行每个stage中的scheduler的schedule()方法,
那么这个 ExecutionSchedule (schedule计划) 里面是如何提供这个顺序的呢?
AllAtOnceExecutionSchedule:
给出一个调度顺序,然后把所有的stage都拿出来调度。
PhasedExecutionSchedule:
获取一个拓扑执行序,每次返回一部分来执行, 如果存在join这类的fragment,会优先调度 build side,再调度probe side。对于union这类的会一个一个执行
他的大概算法就是在plan中添加一个 build 到 probe 的 edge

对于这样的一个plan (里面每个节点代表一个fragment),会先调度 build side,然后再调度 probe side。
但是对于broadcast join 这个算法会出现环,所以他这里做了一个处理:

@VisibleForTestingstatic List<Set<PlanFragmentId>> extractPhases(Collection<PlanFragment> fragments){// Build a graph where the plan fragments are vertexes and the edges represent// a before -> after relationship.  For example, a join hash build has an edge// to the join probe.// 先构建这个 graphGraph<PlanFragmentId, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);fragments.forEach(fragment -> graph.addVertex(fragment.getId()));Visitor visitor = new Visitor(fragments, graph);for (PlanFragment fragment : fragments) {visitor.processFragment(fragment.getId());}// Computes all the strongly connected components of the directed graph.// These are the "phases" which hold the set of fragments that must be started// at the same time to avoid deadlock.// 找到所有强关系集合 如果有A->B B->A 这两个就是强关系 List<Set<PlanFragmentId>> components = new KosarajuStrongConnectivityInspector<>(graph).stronglyConnectedSets();Map<PlanFragmentId, Set<PlanFragmentId>> componentMembership = new HashMap<>();for (Set<PlanFragmentId> component : components) {for (PlanFragmentId planFragmentId : component) {componentMembership.put(planFragmentId, component);}}// build graph of components (phases)// 只有两个边不是强关系才会添加Graph<Set<PlanFragmentId>, DefaultEdge> componentGraph = new DefaultDirectedGraph<>(DefaultEdge.class);components.forEach(componentGraph::addVertex);for (DefaultEdge edge : graph.edgeSet()) {PlanFragmentId source = graph.getEdgeSource(edge);PlanFragmentId target = graph.getEdgeTarget(edge);Set<PlanFragmentId> from = componentMembership.get(source);Set<PlanFragmentId> to = componentMembership.get(target);if (!from.equals(to)) { // the topological order iterator below doesn't include vertices that have self-edges, so don't add themcomponentGraph.addEdge(from, to);}}// 所以对于broadcast来说Join的fragment和 build side的fragment会同时被调度, 因为他们是一组强关系List<Set<PlanFragmentId>> schedulePhases = ImmutableList.copyOf(new TopologicalOrderIterator<>(componentGraph));return schedulePhases;}

那么对于一个task,是否可以被调度多次呢?

    file: PhasedExecutionSchedule.javaprivate void removeCompletedStages(){for (Iterator<StageExecutionAndScheduler> stageIterator = activeSources.iterator(); stageIterator.hasNext(); ) {StageExecutionState state = stageIterator.next().getStageExecution().getState();// state 的状态有 PLANNED SCHEDULING SCHEDULED RUNNING 以及 isDone(CANCELED FINISHED 等)// 所以一个一次调度之后有可能是SCHEDUING (比如还有split没有分配),但是没调度完成,所以下次调度还要调度这些 taskif (state == SCHEDULED || state == RUNNING || state.isDone()) {stageIterator.remove();}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/43108.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

MyBatisX插件逆向工程和SQL生成使用

1.MyBatisX插件逆向工程将表映射成实体类 在IDEA中装好MyBatisX插件并连接数据库后,对咬映射成实体类的表点击鼠标右键,如下图所示:之后会弹出如下界面:然后根据如图信息进行配置,点击next。如果使用的是MyBatis-Plus3直接按照下图选项即可:至此结束逆向工程将表映射成实…

RSA算法中,为什么需要的是两个素数?

RSA算法是一种广泛使用的非对称加密技术,基于大数分解的困难性。本文将探讨为什么RSA算法需要两个素数,并以通俗易懂的例子解释其原理,同时提供专业分析和必要的数学背景。PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全、密码学、联邦学习、同态…

2024-06-11 微信小程序上传代码提示超过xx兆?==》npm run build

平常上传小程序都是直接点上传,这个会直接把dev的包给上传,自然会比较大,可以通过命令npm run build来压缩包,从而减少包的体积 然后用微信开发者工具新建一个项目,选中build包,点击上传即可

Gitee仓库+宝塔WebHook实现线上与仓库代码同步更新

本文由 ChatMoney团队出品进行以下操作时,请确保已经在gitee添加了SSH公钥(Gitee个人设置->SSH公钥)宝塔上安装WebHook​编辑​找到WebHook,点击设置,点击添加,名称自行根据项目填写,脚本填写以下代码: #!/bin/bash echo "" # 输出当前时间 date --date=0…

数据可视化是如何在智慧展厅中发挥作用的?

数据可视化是如何在智慧展厅中发挥作用的?随着科技的进步,智慧展厅成为展示信息、互动体验和传递品牌价值的前沿平台。数据可视化作为智慧展厅的重要组成部分,通过将复杂的数据转化为直观的图形、图表和互动界面,极大地提升了展厅的展示效果和观众的参与感。首先,数据可视…

Vue 打包 Error: error:0308010C:digital envelope routines::unsupported

这个错误通常与Node.js的加密模块和OpenSSL版本有关 出现这个错误是因为 node.js V17版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制,可能会对生态系统造成一些影响. js/app.8d066b51.js from Terser Error: error:0308010C:digital envelope…

Java整合FreeMarker导出Pdf文件

引入依赖 <!--Freemarker wls--><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.30</version></dependency><dependency><groupId>com.itextpdf.tool<…

PHP文件上传接口

文件上传接口 上传在项目/runtime/storage/下,返回的是相对路径.// 文件上传接口public function uploadAjax(){// 获取上传的文件$file = Request::file(file);// 验证规则$validate = Validate::rule([file => fileExt:jpg,jpeg,png,gif|fileSize:10485760, // 限制文件扩…