大数据Spark 面经
1: Spark 整体架构
Spark 是新一代的大数据处理引擎,支持批处理和流处理,也还支持各种机器学习和图计算,它就是一个Master-worker 架构,所以整个的架构就如下所示:
2: Spark 任务提交命令
一般我们使用shell 命令提交,命令如下:
./bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--driver-cores 2 \
--driver-memory 1g \
--executor-cores 4 \
--num-executors 10 \
--executor-memory 8g \
--class PackageName.ClassName XXXX.jar \
--name "Spark Job Name" \
driver 和executor 就是对应的spark的 driver 和executor 的配置,然后再指定个部署模式master 就可以了。
3: spark提交任务的流程
如上所示,我们在提交spark 任务的时候,有个参数可供选择模式,就是deploy-mode 的参数,它的值有client 和cluster 之分;client 说白了就是driver 在客户端,任务的分配和调度都在客户端,这种只适合用于测试;毕竟一旦流量大了的话客户端是顶不住的啊;而cluster 模式是spark对应的driver 和executor 都是在yarn集群上,相对来说稳定,我们这里只着重说yarn-cluster 的提交流程
3.1: 首先如上面的第二点所示,我们先提交启动命令
3.2: 然后客户端这边先运行提交的jar包里面的main方法
3.3: 接着和RM 通信,告诉RM 启动ApplicationMaster,./bin/ApplicatioMaster
3.4: RM 随机选择一台NM 准备启动AM
3.5: 在AM 里面启动driver,然后让driver 进行SparkContext 的初始化以及进行任务的切分
3.6:AM 再向RM 申请资源
3.7: 申请资源后AM 就启动ExecutionBackend,
3.8: ExecutionBackend 启动 Executors
3.9:Driver 把任务分配给Executors
cluster 流程图如下所示:
client 流程图如下所示:
4: Spark 中的RDD
4.1: RDD 概念
还是老样子,先理解一个东西之前我们看看它的学名是什么,Resilient Distribute DataSet ,就是弹性分布式数据集;说白了,它的本质还是数据的集合,MR 和Flink的输入是一条条数据,这Spark 说我乖点了,输入我就先把它们整成一个个数据集;哈哈哈,符合预先聚合的思想。说白了,RDD 就是三个层次的抽象,Dataset, partition, 以及record;对应到生活中的例子,就是班级,组以及单个同学;
4.2:RDD 的特点是啥?从学名可以窥见一二,弹性,分布式
我们先说弹性,说白了就是灵活,可以容错,它是怎么容错的呢?就是RDD之间互相有依赖关系,如果某个RDD的分区没有了,可以从原始数据和依赖关系得来,不用让其他分区重算;
那么分布式呢,就是一个RDD的分区数据可以分发到不同的节点上进行计算;靠近数据的计算嘛;
一个RDD的分区数可以自定义;如果没有自定义,则和hdfs的block数一样,或者和cpu的核数成比例关系,一核心大概可以处理2-4个分区。
4.3: RDD 之间的血缘关系
血缘血缘,套到数据集这边就知道是上下游RDD的关系了,这里的血缘指的就是子RDD和父RDD 之间是分区之间一对一还是多对一;说白了如果一个父RDD的一个分区的数据给到了子RDD的多个分区,这明摆着宽广嘛,就是宽依赖;否则就是摘依赖,一对一的关系;如下所示
4.4: RDD 之间的stage 划分
这里就有个问题了,为什么要进行stage的划分呢? 大家可以想想,这个spark的RDD 也是基于内存的计算,如果一个任务一直这样计算下去,比如算到90%的时候,机器突然宕机了,任务全部失败了,是不是又得重新计算,所以我们就要进行个中间数据的备份嘛,比如算完了一个stage的数据,先把它存储到外部系统,这样就不怕任务突然中断了;
所以大家是不是结合上面的宽窄依赖就想到了,如果出现了宽依赖我们就截断,划分一个stage;毕竟可以先保存一份数据嘛,可能一个子RDD有多个父RDD,每个父RDD就自己先把数据保存起来,做个备份嘛;
所以我们stage 划分就是根据宽窄依赖去划分的,碰到宽依赖就划分一个stage,stage 里面的算子和数据自成一个天地。
4.5: spark的编程思想之RDD
所以兄弟们可以看到,说白了,我们进行spark的编程的时候,就是基于RDD的,然后和算子一起,把RDD当作点,这些算子当成边,不就构建成了我们的这个有向无环图(DAG) 嘛;没有相互依赖的RDD 进行一个并行计算,有相互依赖的窄依赖的类型也可以进行并行计算,当碰到宽依赖的时候,就要进行数据打散了,不就是shuffle嘛,最后算好的数据落盘就行了。
5: Spark中groupByKey,reduceByKey,, combineByKey, aggregrateByKey的区别
怎么说呢,其实这些算子都是针对数据做聚合的操作,groupByKey 和reduceByKey 没有定义初始值的结构,groupByKey 默认用的hash 分区,而reduceByKey 可以自定义分区,也会提前进行combine;这两个算子分区内的逻辑和分区间的逻辑都是一致的;
而aggregrateByKey 和 combineByKey 和 则在reduceByKey的基础上做了些变化,aggregrateByKey 是自定义分区内和分区间的逻辑;而combineByKey 是在上述的基础上也增加一个初始值自定义。
6: spark中的hashShuffle,sortShuffle, 以及优化后的这两个变种
6.1: 普通的hashShuffle ,说白了就是在shuffle的过程中使用hash对key 进行分组,假如上游有100个类似的mapTask,下游有100个reduce task,每个mapTask 会针对下游生成100个文件,总共就是10000个小文件了,这个对于集群来说负担就太大了,如下所示:
6.2: 优化后的HashShuffle
上述的普通版产生的小文件个数太多了,所以我们需要优化下,优化的重点思路就是复用,既然每个上游的task都要生成这么多文件,可不可以一个Executor 里面的缓冲区复用呢?答案是可以的,spark 官方就根据cpu core 的数量 * 下一个stage的task个数来确定缓冲区数量以及文件个数,相对来说少了挺多的,原先要10000个,现在可能只要5*100个就可以了。哈哈哈,不过这个优化机制要通过spark.shuffle.consolidateFiles=true 开启;
6.3: sortShuffle
sortShuffle 是什么呢?说白了就是在shuffle 之前先进行排序,然后也会有溢写到磁盘,可能会生成多个文件,但是最终每个task会对所有的文件进行合并,最终只生成一个文件和文件对应的索引,让下游的task 根据索引文件去找数据,拉取数据。如下所示:
这个对应的文件更少了,对下游的压力也更小了。
6.4: byPassSortShuffle
这个和上面的sortShuffle 如出一辙,唯一的区别就是在写文件的时候不会进行排序,省去了这部分的开销;不过这个需要触发的点有两个,
6.4.1: shuffle map task 数量小于spark.shuffle.sort.bypassMergeThreshold=200参数的值。
6.4.2: 不是聚合类的 shuffle 算子
兄弟们最终是不是还想问问,现阶段该怎么启用sortShuffle,spark2.x 已经把所有的shuffle都默认成了sortShuffle了。
7: spark中的cache,persist 和checkpoint 的区别
三者都是把数据持久化的,前面两个是把数据缓存到内存,而checkpoint 是吧数据存到hdfs 或者本地文件;前者不会截断血缘关系,后者会截断,毕竟hdfs副本可以容错;cache 实际上就是调用的persist
8: RDD , DataFrame, 以及DataSet 的区别
8.1: RDD 就是我们刚刚说的弹性分布式数据集嘛,是面向对象的,是需要序列化和反序列化的,在网络IO中性能消耗大,是不支持Spark Sql的;但是它是编译类型安全的;
8.2: DataFrame 怎么说呢?就是相当于一个表,类似于python 和R,它只知道表头,只知道下面的Name,age,Height;不知道具体每个字段对应的数据类型,它就相当于表里的v如下所示:
所以它是编译时类型不安全的;不过它有个优点,它的存储是放在java的堆外内存,不用进行GC了,也不用进行序列化和反序列化带来的开销了
8.3: 这就是天生为sql 创建的数据集了,它就相当于sql里面的表,既知道表的字段头,也知道每个表的字段的数据类型;而且它还支持序列化的时候轻量的序列化,它结合了DF 和 RDD的优点,编译时也是类型安全的,并且带来了一个全新的概念,Encode,它可以保证按需序列化数据了。
9: SparkShuffle 的优化:
上一步我们讲了spark上游MapTask生成小文件的优化,那么接下来我们也可以看看sparkReduce的这个Reduce 端的优化。
9.1: 既然要优化reducer端,首先能不能让每次buffer存储的数据量多点,就节省了reduce 拉取的个数,这个值通过spark.shuffle.file.buffer 来控制,一般32k,可以是64k;
9.2: 既然要拉取的数据量少点,是不是可以提高每批次拉取的数据量呢?那就是spark.reducer.maxSizeInFlight 的值控制的,一般是48M,可以到96M;
10. sparkStreaming 和kafka的连接方式
说白了,这个问题就是问的sparkStreaming 如何从kafka 拉取数据的,
10.1:Receiver 方式,这个是Spark 1.5 之前的版本,说白了就是Executor 里面有个receiver的组件,它负责和kafka创建连接,并且使用kafka的高阶api 去和kafka 通信,从kafka 消费过来的数据基本上是先放在内存中,然后供spark的executor 去做其他处理,所以数据量激增的时候有可能导致内存炸掉; 毕竟数据放在内存中很有可能丢失,是吧?所以它做了一个checkPoint,会对每个批次的数据做个备份,学名叫做WAL(Write ahead log) 机制,就是会把数据备份到分布式文件系统比如hdfs上面;
10.2:Direct 方式,直接每次轮询kafka的partition的数据,有几个partition 这边也就轮询几次,使用kafka的低阶的api,自己保存每个partition的offset,自己维护,保证了可以和kafka的同步;可以做到数据精确消费一次;
生产环境一般都用DIrect 方式,毕竟不用checkpoint,不用降低数据处理速率,而且可以精准消费一次;不存在重复消费的可能。
说白了,就是Receiver 是被动的,可能会被kafka的数据给干爆;Direct 是主动的,自己掌握offset ,去主动消费
11:sparkStreaming 窗口函数的原理
因为sparkStreaming 本质上是微批数据当作实时数据(如下所示)
val ssc = new StreamingContext(sc,Seconds(5))//5表示5秒中对数据进行切分形成一个RDD
``
所以窗口数据也是微批的合集,窗口一定要是微批的整数倍,这样才能算是可以统计出来的有效窗口
12: spark 常见算子解释
12.1: mapToPair, 说白了就是把原来的数据转换成关系对的形式,不管之前的数据怎么样,转换之后的数据就是pair对的形式,比如 tuple<String,Long>
12.2: transform, tranformToPair, 都是基于sparkStreaming 的流式数据结构上的算子,transform可能就是返回一个流式的数据Dstream, 里面的数据单位是Object; 而tranformToPair 返回的是带有pair 对的流是数据。
12.3: spark 编程,最关键的是你要知道你的输入是什么,你要输出什么,是tuple呢,还是String呢,还是其他数据呢,RDD里面装载的基础数据结构要知道;
12.3:
自定义排序类就是要实现Ordered 以及 Serialziable 接口,定义好大于,小于,compreTo的逻辑;
自定义的accumulator 说白了就是一个累加器,继承实现AccumulatorParam的方法,最关键的是要知道这个累加器的逻辑是什么,对哪个值累加,在addAccumulator 中实现这个累加的逻辑;
自定义的聚合函数,也就是udaf的function , 是要继承UserDefinedAggregateFunction的类,最重要的是要做三件事,初始化传进来的值,在update方法里面对每个分区的值做业务判断处理;
在merge 方法里面对所有分区的值做个融合判断处理,最终在buffer中更新
13:spark电商项目的核心
13.1: 首先从业务方面可以分为session访问指标计算,页面转换率计算;广告相关的指标计算,订单指标的相关统计计算;产品相关的指标计算;核心点是和产品经理核对好各个指标的计算方法;
13.2: 大数据大数据,最重要的关注点就是我们要关注性能,因为好的性能和差的性能跑任务的时间可以相差到几个甚至十几个小时,所以我们在编写代码的时候就要尽可能考虑到这些点;从系统可用资源方面,代码层面,数据倾斜和组成方面进行考虑,尽量达到最大的性能;尽量考虑稳定性。
13.3: spark调优
13.3.1: 算子调优
13.3.2: shuffle 调优
13.3.3: 资源调优
13.3.4: jvm 调优,降低cache 内存的比例
14: Spark 内存管理机制
14.1: 静态内存变为动态内存,统一内存管理了,分成了Storage Memory 和Execution Memory ,分别是1:1 的关系,存储数据,存储shuffle过程中的数据
推荐阅读
-
大数据Spark 面经
-
房产中介遭遇寒冬,链家转型之路任重道远?-房产中介寒冬到来,链家急切求生? “想到了市场会变坏,但没有想到会来得这么快,逼着我们转型。”这是2017年下半年,已经处于转型当中的搜房网董事长莫天全说过的一句话,这句话反映了链家所在的房产交易市场近两年来并不好过。 2017年链家在北京和上海的二手房市场陷入低谷。链家在北京二手房成交量同比下滑51%,在上海,链家2017年月均交易量只有一万套左右。上海北京一直是支撑链家房产交易量的两个重点城市,这两个城市交易量呈现下降,很大程度上说明其它地方可能也不好过。据业内人士估算,二手房市场月成交1.5万套才是盈亏的分水岭,并且规模越大,亏损得越多。 事实上,链家所在的房产中介行业,从2016年开始,受国家不断出台的房产调控政策,比如“去库存”、“棚改”、“房产税收”等影响,行业内各个房产中介开始出现裁员收缩、关店、交易量下降等现象。这些现象虽然都是正常的市场反应,不必过慌,但对于链家而言,每少一家线下店,每少一名经纪人,可能都是不小的打击。 链家闫觅曾说:“目前如何提高运营效率是长租公寓运营商面临的一大难题,推出贝壳找房一方面能给加入者带来流量红利,一方面为参与者带来业务升级,提升房产交易效率。”如此看来,加入贝壳找房好处颇多。不过天下毕竟没有免费的午餐,链家如此让利给入局者,总得有一个说得过去理由。其实,长期以上述模式走下去的贝壳找房,能帮助链家实现真房源数据的维护。如果是出于这样的目的,那么推出贝壳找房可以看成是链家在行业压力下寻求自救的举措。 链家拥抱第三方平台,真实房源数据是终极目标? 要问链家的核心资源在哪里,那么毫无疑问,全国约7000万套真房源数据是链家的核心所在,这是链家生态系统得以运转的血液,也是链家在对外讲话当中,常常提到的事情。从链家的官网简介当中可以看出,链家已经涉及到房产交易服务、大数据处理、资产管理等业务,这些业务大多数是建立在房源数据交易的基础之上。因而如果房源数据出现了问题,那么其产生的后果可想而知。 真房源数据甄别的主体可以来源于两方面,要么亲力亲为,要么让别人去帮你完成甄别。对于主打真房源的链家而言,线下门店是链家真房源的有利保障,要知道从链家一开始提出真房源理念后,其线下门店就开始马不停蹄地扩张,所以即使当行业虚假房源信息泛滥的时候,链家也能有底气提出“真房源”理念。而随着线下门店数量的减少,在2017年8月,链家开始和拥有1800家门店、覆盖54座城市的21世纪中国不动产,就双方加盟合作事宜进行谈判,而且在今年1月份,链家重启德佑品牌,进行加盟模式的布局,可见链家对于加盟模式的重视程度。 目前链家的加盟模式可以分为轻加盟和重度加盟。对于一些平台,例如对乐乎、同创、城家、湾流等品牌公寓,链家采取的是“品质联盟”的形式,换个角度可以理解为轻加盟模式,大家签个正品协议,然后你把你的房源挂到我的平台上。而对于个人加盟甚至是中小中介平台,链家一般采用重度加盟模式,这种模式会从人员的招聘、培训、管理等环节对加入者实行全程干预。 例如链家在2017年下半年,鼓励内部员工自主加盟到链家网当中,加盟者需承担门店的一切费用。同时向链家支付10%的营业额作为加盟费,而加盟者的员工由链家培训,以确保加盟模式跟自己的直营模式在服务上做到无差异。这些事例都在一定程度上反映了链家想找最省钱的真房源确认途径。 其实,链家很清楚,重度垂直门店模式会占用大量的资金,在业务不景气的时候,易造成资金周转困难,不过链家也明白,线下门店是链家开疆扩土的前沿阵地,是真房源数据的最基础来源。因而在线下门店处于收缩的时候,以第三方平台确认真房源的打法,自然而然会成为链家现今的最佳选择。 匆忙布局,链家转型之路并不平坦
-
反传销网8月30日发布:视频区块链里的骗子,币里的韭菜,杜子建骂人了!金融大V周召说区块链!——“一小帮骗子玩一大帮小白,被割韭菜,小白还轮流被割,割的就是你!” 什么区块链,统统是骗子 作者:周召(知乎金融领域大V,毕业于上海财经大学,目前任职上海某股权投资基金合伙人) 有人问我,区块链现在这么火,到底是不是骗局? 我的回答是: 是骗局。而且我并不是说数字货币是骗局,而是说所有搞区块链的都是骗局。 -01- 区块链是一种鸡肋技术 人类社会任何技术的发明应用,本质都是为了提高社会的生产效率。而所谓区块链技术本质不过是几种早已成熟的技术的大杂烩,冗余且十分低效,除了提高了洗钱和诈骗的效率以外,对人类社会的进步毫无贡献。 真正意义上的区块链得包含三个要素:分布式系统(包括记账和存储),无法篡改的数据结构,以及共识算法,三者互为基础和因果,就像三体世界一样。看上去挺让人不明觉厉的,而经过几年的瞎折腾,稍微懂点区块链的碰了几次壁后都已经渐渐明白区块链其实并没有什么卵用,区块链技术已经名存实亡,沦为了营销工具和传销组织的画皮。 因为符合上述定义的、以比特币为代表的原教旨区块链技术,是反效率的,从经济学角度来说,不但不是一种帕累托改进,甚至还可以说是一种帕累托倒退。 原教旨区块链技术的效率十分低下,因为要遍历所有节点,只能做非常轻量级的数据应用,一旦涉及到大量的数据传输与更新,区块链就瞎了。 一方面整条链交易速度会极慢,另一方面数据库容量极速膨胀,考虑到人手一份的存储机制,区块链其实是对存储资源和能源的一种极大的浪费。 这里还没有加上为了取得所谓的共识和挖矿消耗的巨大的能源,如果说区块链技术是屎,那么这波区块链投机浪潮可谓人类历史上最大规模的搅屎运动。 区块链也验证不了任何东西。 所谓的智能合约,即不智能,也非合约。我看有人还说,如果有了智能合约,就可以跟老板签一份放区块链上,如果明年销售业绩提升30%,就加薪10%,由于区块链不能篡改,不能抵赖,所以老板必须得执行,说得有板有眼,不懂行的愣一看,好像还真是那么回事。 但仔细一想,问题就来了。首先,在区块链上如何证明你真的达到了30%业绩提升?即便真的达到老板耍赖如何执行? 也就是说,如果区块链真这么厉害,要法院和仲裁干什么。 人类社会真正的符合成本效益原则的是代理制度。之前有人说要用区块链改造注册会计师行业,我不知道他准备怎么设计,我猜想他思路大概是这样的,首先肯定搞去中心化,让所有会计师到链上来,然后一个新人要成为注册会计师就要所有会计师同意并记录在链上。 那我就请问了,我每天上班累死累活,为什么还要花时间去验证一个跟我无关的的人的专业能力?最优做法当然是组织一个委员会,让专门的人来负责,这不就是现在注册会师协会干的事儿吗?区块链的逻辑相当于什么事情都要拿出来公投,这个绝对是扯淡的。 当然这么说都有点抬举区块链了,区块链技术本身根本没有判断是非能力,如果这么高级的人工智能,靠一个无脑分布式记账就能实现的话,我们早就进入共产主义社会了。 虽然EOS等数字货币采用了超级节点,通过再中心化的方式提高效率,有点行业协会的意思,是对区块链原教旨主义的一种修正,但是依然无法突破区块链技术最本质的局限性。有人说,私有链和联盟链是区块链技术的未来,也是扯淡,因为区块链技术没有未来。如果有,说明他是包装成区块链的伪区块链技术。 区块链所涉及的所有底层技术,不管是分布式数据库技术,加密技术,还是点对点传输技术等,基本都是早已存在没什么秘密可言的技术。 比特币系统最重要的特性是封闭性和自洽性,他验证不了任何系统自身以外产生的信息的真实性。 所谓系统自身产生的信息,就是数据库数据的变动信息,有价值的基本上有且只有交易信息。所以说比特币最初不过是中本聪一种炫技的产物,来证明自己对几种技术的掌握,你看我多牛逼,设计出了一个像三体一样的系统。因此,数字货币很有可能是区块链从始至终唯一的杀手应用。 比特币和区块链概念从诞生到今天已经快10年了,很多人说区块链技术在爆发的前夜,但这个前夜好像是不是有点过长了啊朋友,跟三体里的长夜有一拼啊。都说区块链技术像是90年代初的互联网,可是90年代初的互联网在十年发展后,已经出现了一大批伟大的公司,阿里巴巴在99年都成立了,区块链怎么除了币还是币呢? 正规的数字货币未来发展的形式无外乎几种,要么就是论坛币形式,或者类似股票的权益凭证等。问题是论坛币和股票之前,本来也都电子化了,区块链来了到底改变了什么呢? 所有想把TOKEN和应用场景结合起来的人最后都很痛苦,最后他们会发现区块链技术就是脱裤子放屁,自己辛苦搞半天,干嘛不自己作为中心关心门来收钱?最后这些人都产生了价值的虚无感,最终精神崩溃,只能发币疯狂收割韭菜,一边嘴里还说着我是个好人之类的奇怪的话。 因此,之前币圈链圈还泾渭分明,互相瞧不起,但这两年链圈逐渐坐不住了,想着是不是趁着泡沫没彻底破灭之前赶快收割一波,不然可能什么都捞不着了。 前段时间和一个名校毕业的链圈朋友瞎聊天,他说他们“致力于用区块链技术解决数字版权保护问题”,我就问他一个问题,你们如何保证你链的版权所有权声明是真实的,万一盗版者抢先一步把数据放在链上怎么办。他说他们的解决方案是连入国家数字版权保护中心的数据库进行验证…… 所以说区块链技术就是个鸡肋,研究到最后都会落入效率与真实性的黑洞,很多人一头扎进链圈后才发现,真正意义上的区块链技术,其实什么都干不了。 -02- 不是蠢就是坏的区块链媒体 空气币和区块链的造富神话,让区块链自媒体也开始迎风乱扭。一群群根本不知道区块链为何物的妖魔鬼怪纷纷进驻区块链自媒体战场,开始大放厥词胡编乱造。 任何东西,但凡只要和区块,链,分,分布式,记账,加密,验证,可追溯等等这些个关键词沾到哪怕一点点,这些所谓的区块链媒体人就会像狗闻到了屎了一样疯狂地把区块链概念往上套。 这让我想起曾经一度也是热闹非凡的物联网,我曾经去看过江苏一家号称要改变世界的“物联网”企业,过去一看是生产路由器的,我黑人问号脸,对方解释说没有路由器万物怎么互联,我觉得他说得好有道理,竟无言以对。 好,下面让我们进入奇葩共赏析时间,来看看区城链媒体经常有哪些危言耸听的奇谈怪论 区块链(分布式记账)的典型应用是*?? 正如前面所说,真正意义上的区块链分布式记账,不光包括“记”这个动作,还包括分布式存储和共识机制等。而*诞生远远早于区块链这个词的出现,勉强算是“分布式编辑”吧,就被很多区块链媒体拿来强行充当区块链技术应用的典范。 其实事实恰恰相反,*恰恰是去中心化失败的典范,现在如果没有精英和专业人士的编辑和维护,*早就没法看了。 区块链会促进社会分工?? 罗振宇好像就说过类似的话,虽然罗振宇说过很多没有逻辑的话,但这句话绝对是最没逻辑思维的。很多区块链自媒体也常常用这句话来忽悠老百姓,说分工代表效率提高社会进步,而区块链“无疑”会促进分工,他们的理由仅仅是分工和分布式记账都共用一个“分”字,就强行把他们扯到一起。 实际情况恰恰相反,区块链是逆分工的,区块链精神是号召所有人积极地参与到他不擅长也不想掺合的事情里面去。 区块链不能像上帝一样许诺他的子民死后上天国,只能给他们许诺你们是六度人脉中的第一级,我可以赚后面五级人的钱,你处于金字塔的顶端。
-
如何使用Spark生成HFile文件,并利用BulkLoad功能将其大容量数据快速加载进HBase