首页 文章 精选 留言 我的

精选列表

搜索[产业分析],共10000篇文章
优秀的个人博客,低调大师

sync.mutex 源代码分析

sync.Mutex是Go标准库中常用的一个排外锁。当一个 goroutine 获得了这个锁的拥有权后, 其它请求锁的 goroutine 就会阻塞在 Lock 方法的调用上,直到锁被释放。sync.Mutex的实现也是经过多次的演化,功能逐步加强,增加了公平的处理和饥饿机制。 初版的 Mutex首先我们来看看Russ Cox在2008提交的第一版的Mutex实现。 1type Mutex struct { 2 key int32; 3 sema int32; 4} 5 6func xadd(val *int32, delta int32) (new int32) { 7 for { 8 v := *val; 9 if cas(val, v, v+delta) { 10

优秀的个人博客,低调大师

Spark作业调度阶段分析[转]

Spark作为分布式的大数据处理框架必然或涉及到大量的作业调度,如果能够理解Spark中的调度对我们编写或优化Spark程序都是有很大帮助的; 在Spark中存在转换操作(Transformation Operation)与行动操作(Action Operation)两种;而转换操作只是会从一个RDD中生成另一个RDD且是lazy的,Spark中只有行动操作(Action Operation)才会触发作业的提交,从而引发作业调度;在一个计算任务中可能会多次调用 转换操作这些操作生成的RDD可能存在着依赖关系,而由于转换都是lazy所以当行动操作(Action Operation )触发时才会有真正的RDD生成,这一系列的RDD中就存在着依赖关系形成一个DAG(Directed Acyclc Graph),在Spark中DAGScheuler是基于DAG的顶层调度模块; 相关名词 Application:使用Spark编写的应用程序,通常需要提交一个或多个作业; Job:在触发RDD Action操作时产生的计算作业 Task:一个分区数据集中最小处理单元也就是真正执行作业的地方 TaskSet:由多个Task所组成没有Shuffle依赖关系的任务集 Stage:一个任务集对应的调度阶段 ,每个Job会被拆分成诺干个Stage RDD Action作业提交流程 这里根据Spark源码跟踪触发Action操作时触发的Job提交流程,Count()是RDD中的一个Action操作所以调用Count时会触发Job提交; 在RDD源码count()调用SparkContext的runJob,在runJob方法中根据partitions(分区)大小创建Arrays存放返回结果; RDD.scala /** *ReturnthenumberofelementsintheRDD. */ defcount():Long=sc.runJob(this,Utils.getIteratorSize_).sum SparkContext.scala defrunJob[T,U:ClassTag]( rdd:RDD[T], func:(TaskContext,Iterator[T])=>U, partitions:Seq[Int], resultHandler:(Int,U)=>Unit):Unit={ valcallSite=getCallSite valcleanedFunc=clean(func) logInfo("Startingjob:"+callSite.shortForm) if(conf.getBoolean("spark.logLineage",false)){ logInfo("RDD'srecursivedependencies:\n"+rdd.toDebugString) } dagScheduler.runJob(rdd,cleanedFunc,partitions,callSite,resultHandler,localProperties.get) } 在SparkContext中将调用DAGScheduler的runJob方法提交作业,DAGScheduler主要任务是计算作业与任务依赖关系,处理调用逻辑;DAGScheduler提供了submitJob与runJob方法用于 提交作业,runJob方法会一直等待作业完成,submitJob则返回JobWaiter对象可以用于判断作业执行结果; 在runJob方法中将调用submitJob,在submitJob中把提交操作放入到事件循环队列(DAGSchedulerEventProcessLoop)中; defsubmitJob[T,U]( rdd:RDD[T], func:(TaskContext,Iterator[T])=>U, partitions:Seq[Int], callSite:CallSite, resultHandler:(Int,U)=>Unit, properties:Properties):JobWaiter[U]={ ...... eventProcessLoop.post(JobSubmitted( jobId,rdd,func2,partitions.toArray,callSite,waiter, SerializationUtils.clone(properties))) ...... } 在事件循环队列中将调用eventprocessLoop的onReceive方法; Stage拆分 提交作业时DAGScheduler会从RDD依赖链尾部开始,遍历整个依赖链划分调度阶段;划分阶段以ShuffleDependency为依据,当没有ShuffleDependency时整个Job 只会有一个Stage;在事件循环队列中将会调用DAGScheduler的handleJobSubmitted方法,此方法会拆分Stage、提交Stage; private[scheduler]defhandleJobSubmitted(jobId:Int, finalRDD:RDD[_], func:(TaskContext,Iterator[_])=>_, partitions:Array[Int], callSite:CallSite, listener:JobListener, properties:Properties){ varfinalStage:ResultStage=null ...... finalStage=newResultStage(finalRDD,func,partitions,jobId,callSite) ...... valjob=newActiveJob(jobId,finalStage,callSite,listener,properties) ...... valjobSubmissionTime=clock.getTimeMillis() jobIdToActiveJob(jobId)=job activeJobs+=job finalStage.setActiveJob(job) valstageIds=jobIdToStageIds(jobId).toArray valstageInfos=stageIds.flatMap(id=>stageIdToStage.get(id).map(_.latestInfo)) listenerBus.post( SparkListenerJobStart(job.jobId,jobSubmissionTime,stageInfos,properties)) submitStage(finalStage) submitWaitingStages() } 调度阶段提交 在提交Stage时会先调用getMissingParentStages获取父阶段Stage,迭代该阶段所依赖的父调度阶段如果存在则先提交该父阶段的Stage 当不存在父Stage或父Stage执行完成时会对当前Stage进行提交; privatedefsubmitStage(stage:Stage){ valjobId=activeJobForStage(stage) if(jobId.isDefined){ if(!waitingStages(stage)&&!runningStages(stage)&&!failedStages(stage)){ valmissing=getMissingParentStages(stage).sortBy(_.id) if(missing.isEmpty){ submitMissingTasks(stage,jobId.get) }else{ for(parent<-missing){ submitStage(parent) } waitingStages+=stage } } } ...... } 参考资料:http://spark.apache.org/docs/latest/ 本文链接:http://www.solinx.co/archives/579#comment-47

优秀的个人博客,低调大师

Drill storage plugin实现原理分析

Drill Storage Plugin介绍 Drill是一个交互式SQL查询引擎,官方默认支持的数据源有hive、hbase、kafka、kudu、mongo、opentsdb、jdbc等,其中jdbc storage plugin可以覆盖所有支持jdbc协议的数据源,如:mysql、oracle等关系型数据库。所有数据源的接入都是通过drill的storage plugin实现的,理论上Drill通过storage plugin机制可以支持对任何数据源进行异构查询。 Drill作为一个SQL查询引擎,它跟传统数据库有着很多相似之处,主要包括SQL Parser、SQL Validator、Query Optimizer、Data Flow Operators等几部分。如下图所示,SQL Parser阶段会把SQL语句解析为SQL查

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册