zoukankan      html  css  js  c++  java
  • spark 内核笔记

        
        执行启动命令 jar 、wordcount
        sparkSubmit:
            yarnclient ->submitApplication-> ResourceManage
            bin/java 在NodeManager 启动进程,ApplicationMaster 
            ApplicationMaster进程启动后,需要向ResourceManage注册ApplicationMaster
            
        ApplicationMaster:
            // userclass wordCount
            //主线程main创建driver线程, 等待driver线程创建sc
            //-》driver线程创建sc后 阻塞
            //-》主线程申请计算所需资源,创建完成后恢复driver
            //-》driver线程和主线程合二为一, driver线程 里的userClass.join()
             
            主线程和driver线程交互执行
            
        ApplicationMaster 向resourceManage 申请资源,返回可以运行的containers
        根据container 的位置在 对应的NodeManger 用命令方式启动container,每个container 启动一个excutor
        driver里的schedulerBacked 和 excutor 里的 Excutorbackend 互相通信,用于driver给excutor发送任务
        启动完excutor ,注册excutor
        
        创建计算对象,进行任务的划分和阶段划分,每一个任务由一个线程执行,这些线程在线程池里面
        
        
        
        
        
        一般任务数是核数的2-3倍
        一个行动算子 就是一个job
        driver 负责excutor之间的任务调度
        excutor 负责任务的执行,会存储rdd 和 广播变量
        
        
        driver 和excutor 通信是通过rpc,rpc是进程间通信协议
        netty 通信框架
            BIO:block IO
            NIO:non block IO,new IO
            netty  使用了AIO,异步非阻塞IO
        具体通信流程:
         driver的transportClinent 发送数据给 excutor 的transportSever 
            放入inbox,经过终端处理,放入outbox,然后outbox内部的transportClinent 
            连接driver 的transportSever 返回数据,inbox和outbox底层都是链表
        
        spark的任务调度:
            一个行动算子是一个job
            一个job根据shuffle 划分阶段
            task 是依据stage的最后一个rdd的分区数
            公平调度器,如果一个队列任务执行比例低,下次调度任务时,优先调度
        本地化调度:
            RDD的首选位置,计算发给哪个位置更好
            RDD存储级别:process_local,
                         node_local,
                         rack_local(机架本地化),
                         没有级别,
                         any
        
        spark shuffle:
            影响shuffle的点: 1 磁盘
                              2 缓冲区(参数配置),读取缓冲区默认48M,当task数量比较多,可能需要调小
                              3 数据量(先filter 或者reduceByKey 数据量少 ,shuffle性能高)
                              4 写文件的方式
        下游的多个task访问上游一个task产生的同一个溢写文件,可能冲突
        解决方案:溢写文件存多份,
                  溢写文件数量和下游的task数量相等,
                  每个task单独访问
        上述方案出现的问题:核数多了后,小文件过多
        优化方案:一个cpu 核的所有task共享溢写文件,
                    溢写文件数量和下游的task数量相等
        上述方案当机器数多了后,仍然小文件过多
        解决方案:一个机器的一个核存一份溢写文件
                 该溢写文件分数据文件和索引文件,
                 其中数据文件是分区排序的
                 
        
        serializedShuffle     
            解释:一个对象序列化后,放入内存,可以经过压缩,这样方便传输,也可以存放更多的对象
            1)支持重定位的序列化,为了防止内存碎片,kryo序列化支持,java序列化不支持
            2)分区数不能大于16777216
            3)不能有预聚合
            
        sortshuffle:
            reduceByKey 就是这种shuffle
            if (has预聚合){
                会有外部聚合器
                会对key排序,这样数据查找速度快
                只需要对map的value进行合并
                map的底层是k,v 连起来的数组,可以看作c++的结构体数组
                用数组的原因是key是排序好的,可以通过索引及二分查找法快速定位
                扩展:环形缓冲区溢写前是对索引进行排序,数据不动,
                      这样只需要对内存的部分数据进行排序,就可以对所有数据进行排序
                      
                溢写条件:
                    数据量是32的倍数,并且数据量大于5M,此时会申请内存
                    当预估大小大于申请后的内存,需要进行溢写
                    
                    当元素个数大于INT 的最大值,强制溢写
                最终需要对这些临时溢写文件进行归并排序(如果能忽略,可以提高性能)
                
                如果只有内存中有数据,那么只需要对内存数据排序,然后写文件
                如果有溢写文件,需要merge,将内存数据和溢写文件合并,
                    最终合并成一个索引文件和一个排序好的数据文件
            }     
            else{
                存放分区,k,v
            }     
        bypass sortshuffle:
            忽略归并排序的shuffle
            条件:1) 不能有预聚合功能 ,有预聚合的算子
                    reduceByKey,foldByKey,combineByKey,aggregateByKey
                    groupBykey没有
                  2)分区数量必须小于阈值,默认是200
        
        为什么能忽略归并排序:
            写分区数量个文件,然后直接按照分区顺序合并成一个文件,
            同时创建这个文件的索引文件
        注意溢写文件多的时候用bypass sortshuffle 才合适,因为当内存足够大时,
            有可能sortshuffle 不溢写文件,工作中需要把bypass 阈值设高一点
            默认200,可以设为500
        
                    
    spark 内存管理:
            spark的结果可以把中间的计算过程通过内存传递
            jvm 默认启动的时候是当前可用内存的1/64,最大是1/4
            堆外内存是从操作系统申请的,不受gc控制,由程序自己控制
            kafka 数据文件是0拷贝技术,索引文件是虚拟内存映射
            
            executor 内存分3部分,分别是storage(30%),
                                        execution(30%),
                                        other(40%),
                                        预留300M内存,防止内存溢出
            
                rdd,catche 保存在存储内存
                shuffle 需要使用执行内存
                元数据信息保存在other
                执行内存和存储内存有动态占用机制
  • 相关阅读:
    Gyp语法规则参考 & 工具的使用
    从源码编译Chrome(chromium)
    Oracle 高版本导出到低版本的测试验证
    CentOS7 安装Oracle11g的过程.
    Rhino 使 JavaScript 应用程序更灵动(转载)
    javascript与java的相互调用,纯java的javascript引擎rhino(转载)
    Template Method Design Pattern in Java
    Chain Of Responsibility Design Pattern Example
    设计模式之状态模式
    设计模式之装饰者模式
  • 原文地址:https://www.cnblogs.com/wanghzh/p/15053839.html
Copyright © 2011-2022 走看看