欢迎光临
免费的PDF电子书下载网站

Spark大数据商业实战三部曲:内核解密|商业案例|性能调优 PDF下载

编辑推荐

基于*的Spark2.2.X版本,分为内核解密篇,商业案例篇,性能调优篇,共31章,学习过程中有任何疑问,可加入QQ群,有专业人员答疑解惑。 ;

内容简介

《Spark大数据商业实战三部曲:内核解密|商业案例|性能调优》基于Spark 2.2.X,以Spark商业案例实战和Spark在生产环境下几乎所有类型的性能调优为核心,以Spark内核解密为基石,分为上篇、中篇、下篇,对企业生产环境下的Spark商业案例与性能调优抽丝剥茧地进行剖析。上篇基于Spark源码,从一个动手实战案例入手,循序渐进地全面解析了Spark 2.2新特性及Spark内核源码;中篇选取Spark开发中*有代表的经典学习案例,深入浅出地介绍,在案例中综合应用Spark的大数据技术;下篇性能调优内容基本完全覆盖了Spark在生产环境下的所有调优技术。

作者简介

暂无

Spark大数据商业实战三部曲:内核解密|商业案例|性能调优 PDF下载

目录


目 ; ; ; 录

上篇 ; 内核解密

第1章 ; 电光石火间体验Spark 2.2开发实战... 2

1.1 ; 通过RDD实战电影点评系统入门及源码阅读... 2

1.1.1  ; Spark核心概念图解... 2

1.1.2  ; 通过RDD实战电影点评系统案例... 4

1.2 ; 通过DataFrame和DataSet实战电影点评系统... 7

1.2.1  ; 通过DataFrame实战电影点评系统案例... 7

1.2.2  ; 通过DataSet实战电影点评系统案例... 10

1.3 ; Spark 2.2源码阅读环境搭建及源码阅读体验... 11

第2章 ; Spark 2.2技术及原理... 14

2.1 ; Spark 2.2综述... 14

2.1.1  ; 连续应用程序... 14

2.1.2  ; 新的API 15

2.2 ; Spark 2.2 Core. 16

2.2.1  ; 第二代Tungsten引擎... 16

2.2.2  ; SparkSession. 16

2.2.3  ; 累加器API 17

2.3 ; Spark 2.2 SQL. 19

2.3.1  ; Spark SQL. 20

2.3.2  ; DataFrame和Dataset API 20

2.3.3  ; Timed Window.. 21

2.4 ; Spark 2.2 Streaming. 21

2.4.1  ; Structured Streaming. 21

2.4.2  ; 增量输出模式... 23

2.5 ; Spark 2.2 MLlib. 27

2.5.1  ; 基于DataFrame的Machine Learning API 28

2.5.2  ; R的分布式算法... 28

2.6 ; Spark 2.2 GraphX.. 29

第3章 ; Spark的灵魂:RDD和DataSet 30

3.1 ; 为什么说RDD和DataSet是Spark的灵魂... 30

3.1.1  ; RDD的定义及五大特性剖析... 30

3.1.2  ; DataSet的定义及内部机制剖析... 34

3.2 ; RDD弹性特性七个方面解析... 36

3.3 ; RDD依赖关系... 43

3.3.1  ; 窄依赖解析... 43

3.3.2  ; 宽依赖解析... 45

3.4 ; 解析Spark中的DAG逻辑视图... 46

3.4.1  ; DAG生成的机制... 46

3.4.2  ; DAG逻辑视图解析... 47

3.5 ; RDD内部的计算机制... 49

3.5.1  ; Task解析... 49

3.5.2  ; 计算过程深度解析... 49

3.6 ; Spark RDD容错原理及其四大核心要点解析... 57

3.6.1  ; Spark RDD容错原理... 57

3.6.2  ; RDD容错的四大核心要点... 57

3.7 ; Spark RDD中Runtime流程解析... 59

3.7.1  ; Runtime架构图... 59

3.7.2  ; 生命周期... 60

3.8 ; 通过WordCount实战解析Spark RDD内部机制... 70

3.8.1  ; Spark WordCount动手实践... 70

3.8.2  ; 解析RDD生成的内部机制... 72

3.9 ; 基于DataSet的代码到底是如何一步步转化成为RDD的... 78

第4章 ; Spark Driver启动内幕剖析... 81

4.1 ; Spark Driver Program剖析... 81

4.1.1  ; Spark Driver Program.. 81

4.1.2  ; SparkContext深度剖析... 81

4.1.3  ; SparkContext源码解析... 82

4.2 ; DAGScheduler解析... 96

4.2.1  ; DAG的定义... 96

4.2.2  ; DAG的实例化... 97

4.2.3  ; DAGScheduler划分Stage的原理... 98

4.2.4  ; DAGScheduler划分Stage的具体算法... 99

4.2.5  ; Stage内部Task获取最佳位置的算法... 113

4.3 ; TaskScheduler解析... 116

4.3.1  ; TaskScheduler原理剖析... 116

4.3.2  ; TaskScheduler源码解析... 117

4.4 ; SchedulerBackend解析... 132

4.4.1  ; SchedulerBackend原理剖析... 132

4.4.2  ; SchedulerBackend源码解析... 132

4.4.3  ; Spark程序的注册机制... 133

4.4.4  ; Spark程序对计算资源Executor的管理... 134

4.5 ; 打通Spark系统运行内幕机制循环流程... 135

4.6 ; 本章总结... 145

第5章 ; Spark集群启动原理和源码详解... 146

5.1 ; Master启动原理和源码详解... 146

5.1.1  ; Master启动的原理详解... 146

5.1.2  ; Master启动的源码详解... 147

5.1.3  ; Master HA双机切换... 157

5.1.4  ; Master的注册机制和状态管理解密... 163

5.2 ; Worker启动原理和源码详解... 170

5.2.1  ; Worker启动的原理流程... 170

5.2.2  ; Worker启动的源码详解... 174

5.3 ; ExecutorBackend启动原理和源码详解... 178

5.3.1  ; ExecutorBackend接口与Executor的关系... 178

5.3.2  ; ExecutorBackend的不同实现... 179

5.3.3  ; ExecutorBackend中的通信... 181

5.3.4  ; ExecutorBackend的异常处理... 183

5.4 ; Executor中任务的执行... 184

5.4.1  ; Executor中任务的加载... 184

5.4.2  ; Executor中的任务线程池... 185

5.4.3  ; 任务执行失败处理... 186

5.4.4  ; 揭秘TaskRunner 188

5.5 ; Executor执行结果的处理方式... 189

5.6 ; 本章总结... 197

第6章 ; Spark Application提交给集群的原理和源码详解... 198

6.1 ; Spark Application到底是如何提交给集群的... 198

6.1.1  A pplication提交参数配置详解... 198

6.1.2  A pplication提交给集群原理详解... 199

6.1.3  A pplication提交给集群源码详解... 201

6.2  Spark Application是如何向集群申请资源的... 211

6.2.1  A pplication申请资源的两种类型详解... 211

6.2.2  A pplication申请资源的源码详解... 213

6.3  从Application提交的角度重新审视Driver 219

6.3.1   Driver到底是什么时候产生的... 220

6.3.2   Driver和Master交互原理解析... 238

6.3.3   Driver和Master交互源码详解... 244

6.4  从Application提交的角度重新审视Executor 249

6.4.1   Executor到底是什么时候启动的... 249

6.4.2   Executor如何把结果交给Application. 254

6.5  Spark 1.6 RPC内幕解密:运行机制、源码详解、Netty与Akka等... 254

6.6  本章总结... 267

第7章  Shuffle原理和源码详解... 268

7.1  概述... 268

7.2  Shuffle的框架... 269

7.2.1   Shuffle的框架演进... 269

7.2.2   Shuffle的框架内核... 270

7.2.3   Shuffle框架的源码解析... 272

7.2.4   Shuffle数据读写的源码解析... 275

7.3  Hash Based Shuffle. 281

7.3.1   概述... 281

7.3.2   Hash Based Shuffle内核... 282

7.3.3   Hash Based Shuffle数据读写的源码解析... 285

7.4  Sorted Based Shuffle. 290

7.4.1   概述... 292

7.4.2   Sorted Based Shuffle内核... 293

7.4.3   Sorted Based Shuffle数据读写的源码解析... 294

7.5  Tungsten Sorted Based Shuffle. 302

7.5.1   概述... 302

7.5.2   Tungsten Sorted Based Shuffle内核... 302

7.5.3   Tungsten Sorted Based Shuffle数据读写的源码解析... 303

7.6  Shuffle与Storage 模块间的交互... 309

7.6.1   Shuffle注册的交互... 310

7.6.2   Shuffle写数据的交互... 314

7.6.3   Shuffle读数据的交互... 315

7.6.4   BlockManager架构原理、运行流程图和源码解密... 315

7.6.5   BlockManager解密进阶:BlockManager初始化和注册解密、BlockManager- Master工作解密、BlockTransferService解密、本地数据读写解密、远程数据读写解密... 324

7.7  本章总结... 341

第8章  Job工作原理和源码详解... 342

8.1  Job到底在什么时候产生... 342

8.1.1   触发Job的原理和源码解析... 342

8.1.2   触发Job的算子案例... 344

8.2  Stage划分内幕... 345

8.2.1   Stage划分原理详解... 345

8.2.2   Stage划分源码详解... 346

8.3  Task全生命周期详解... 346

8.3.1   Task的生命过程详解... 347

8.3.2  Task在Driver和Executor中交互的全生命周期原理和源码详解... 348

8.4  ShuffleMapTask和ResultTask处理结果是如何被Driver管理的... 364

8.4.1   ShuffleMapTask执行结果和Driver的交互原理及源码详解... 364

8.4.2  ResultTask执行结果与Driver的交互原理及源码详解... 370

第9章  Spark中Cache和checkpoint原理和源码详解... 372

9.1  Spark中Cache原理和源码详解... 372

9.1.1   Spark中Cache原理详解... 372

9.1.2   Spark中Cache源码详解... 372

9.2  Spark中checkpoint原理和源码详解... 381

9.2.1   Spark中checkpoint原理详解... 381

9.2.2   Spark中checkpoint源码详解... 381

第10章  Spark中Broadcast和Accumulator原理和源码详解... 391

10.1  Spark中Broadcast原理和源码详解... 391

10.1.1   Spark中Broadcast原理详解... 391

10.1.2   Spark中Broadcast源码详解... 393

10.2  Spark中Accumulator原理和源码详解... 396

10.2.1   Spark中Accumulator原理详解... 396

10.2.2   Spark中Accumulator源码详解... 396

第11章  Spark与大数据其他经典组件整合原理与实战... 399

11.1  Spark组件综合应用... 399

11.2  Spark与Alluxio整合原理与实战... 400

11.2.1   Spark与Alluxio整合原理... 400

11.2.2   Spark与Alluxio整合实战... 401

11.3  Spark与Job Server整合原理与实战... 403

11.3.1   Spark与Job Server整合原理... 403

11.3.2   Spark与Job Server整合实战... 404

11.4  Spark与Redis整合原理与实战... 406

11.4.1   Spark与Redis整合原理... 406

11.4.2   Spark与Redis整合实战... 407

中篇  商业案例

第12章  Spark商业案例之大数据电影点评系统应用案例... 412

12.1  通过RDD实现分析电影的用户行为信息... 412

12.1.1   搭建IDEA开发环境... 412

12.1.2   大数据电影点评系统中电影数据说明... 425

12.1.3   电影点评系统用户行为分析统计实战... 428

12.2  通过RDD实现电影流行度分析... 431

12.3  通过RDD分析各种类型的最喜爱电影TopN及性能优化技巧... 433

12.4  通过RDD分析电影点评系统仿QQ和微信等用户群分析及广播
背后机制解密... 436

12.5  通过RDD分析电影点评系统实现Java和Scala版本的二次排序系统... 439

12.5.1   二次排序自定义Key值类实现(Java)... 440

12.5.2   电影点评系统二次排序功能实现(Java)... 442

12.5.3   二次排序自定义Key值类实现(Scala)... 445

12.5.4   电影点评系统二次排序功能实现(Scala)... 446

12.6  通过Spark SQL中的SQL语句实现电影点评系统用户行为分析... 447

12.7  通过Spark SQL下的两种不同方式实现口碑最佳电影分析... 451

12.8  通过Spark SQL下的两种不同方式实现最流行电影分析... 456

12.9  通过DataFrame分析最受男性和女性喜爱电影TopN.. 457

12.10  纯粹通过DataFrame分析电影点评系统仿QQ和微信、淘宝等用户群... 460

12.11  纯粹通过DataSet对电影点评系统进行流行度和不同年龄阶段兴趣分析等... 462

12.11.1   通过DataSet实现某特定电影观看者中男性和女性不同年龄的人数... 463

12.11.2   通过DataSet方式计算所有电影中平均得分最高
(口碑最好)的电影TopN.. 464

12.11.3   通过DataSet方式计算所有电影中粉丝或者观看人数最多(最流行电影)的电影TopN   465

12.11.4   纯粹通过DataSet的方式实现所有电影中最受男性、女性喜爱的
电影Top10. 466

12.11.5  纯粹通过DataSet的方式实现所有电影中QQ或者微信核心目标
用户最喜爱电影TopN分析... 467

12.11.6   纯粹通过DataSet的方式实现所有电影中淘宝核心目标用户最喜爱电影TopN分析    469

12.12  大数据电影点评系统应用案例涉及的核心知识点原理、源码及案例代码... 470

12.12.1   知识点:广播变量Broadcast内幕机制... 470

12.12.2   知识点:SQL全局临时视图及临时视图... 473

12.12.3   大数据电影点评系统应用案例完整代码... 474

12.13  本章总结... 496

前沿

前    言

大数据像当年的石油、人工智能(Artificial Intelligence)像当年的电力一样,正以前所未有的广度和深度影响所有的行业,现在及未来公司的核心壁垒是数据,核心竞争力来自基于大数据的人工智能的竞争。Spark是当今大数据领域最活跃、最热门、最高效的大数据通用计算平台,2009年诞生于美国加州大学伯克利分校AMP实验室,2010年正式开源,2013年成为Apache基金项目,2014年成为Apache基金的顶级项目。基于RDD,Spark成功构建起了一体化、多元化的大数据处理体系。

在任何规模的数据计算中,Spark在性能和扩展性上都更具优势。

(1)Hadoop之父Doug Cutting指出:Useof MapReduce engine for Big Data projects will decline, replaced by ApacheSpark(大数据项目的MapReduce引擎的使用将下降,由Apache Spark取代。)

(2)Hadoop商业发行版本的市场领导者Cloudera、HortonWorks、MapR纷纷转投Spark,并把Spark作为大数据解决方案的首选和核心计算引擎。

2014年的Sort Benchmark测试中,Spark秒杀Hadoop,在使用十分之一计算资源的情况下,相同数据的排序上,Spark比MapReduce快3倍!在没有官方PB排序对比的情况下,首次将Spark推到了1PB数据(十万亿条记录)的排序,在使用190个节点的情况下,工作负载在4小时内完成,同样远超雅虎之前使用3800台主机耗时16个小时的记录。

2015年6月,Spark最大的集群来自腾讯——8000个节点,单个Job最大分别是阿里巴巴和Databricks——1PB,震撼人心!同时,Spark的Contributor比2014年涨了3倍,达到730人;总代码行数也比2014年涨了2倍多,达到40万行。IBM于2015年6月承诺大力推进Apache Spark项目,并称该项目为:以数据为主导的,未来十年最重要的新的开源项目。这一承诺的核心是将Spark嵌入IBM业内领先的分析和商务平台,并将Spark作为一项服务,在IBMBluemix平台上提供给客户。IBM还将投入超过3500名研究和开发人员在全球10余个实验室开展与Spark相关的项目,并将为Spark开源生态系统无偿提供突破性的机器学习技术——IBM SystemML。同时,IBM还将培养超过100万名Spark数据科学家和数据工      程师。

2016年,在有“计算界奥运会”之称的国际著名SortBenchmark 全球数据排序大赛中,由南京大学计算机科学与技术系PASA大数据实验室、阿里巴巴和Databricks公司组成的参赛团队NADSort,以144美元的成本完成100TB标准数据集的排序处理,创下了每TB数据排序1.44美元成本的最新世界纪录,比2014年夺得冠军的加州大学圣地亚哥分校TritonSort团队每TB数据4.51美元的成本降低了近70%,而这次比赛依旧使用Apache Spark大数据计算平台,在大规模并行排序算法以及Spark系统底层进行了大量的优化,以尽可能提高排序计算性能并降低存储资源开销,确保最终赢得比赛。

在Full Stack理想的指引下,Spark中的Spark SQL、SparkStreaming、MLLib、GraphX、R五大子框架和库之间可以无缝地共享数据和操作,这不仅打造了Spark在当今大数据计算领域其他计算框架都无可匹敌的优势,而且使得Spark正在加速成为大数据处理中心首选通用计算平台,而Spark商业案例和性能优化必将成为接下来的重中之重!

本书根据
王家林
老师亲授课程及结合众多大数据项目经验编写而成,其中王家林、段智华编写了本书近90%的内容,具体编写章节如下:

第3章 Spark的灵魂:RDD和DataSet;

第4章 Spark Driver启动内幕剖析;

第5章 Spark集群启动原理和源码详解;

第6章 Spark Application提交给集群的原理和源码详解;

第7章 Shuffle原理和源码详解;

第8章 Job工作原理和源码详解;

第9章 Spark中Cache和checkpoint原理和源码详解;

第10章 Spark中Broadcast和Accumulator原理和源码详解;

第11章 Spark与大数据其他经典组件整合原理与实战;

第12章 Spark商业案例之大数据电影点评系统应用案例;

第13章 Spark 2.2实战之Dataset开发实战企业人员管理系统应用案例;

第14章 Spark商业案例之电商交互式分析系统应用案例;

第15章  Spark商业案例之NBA篮球运动员大数据分析系统应用案例;

第16章 电商广告点击大数据实时流处理系统案例;

第17章 Spark在通信运营商生产环境中的应用案例;

第18章 使用SparkGraphX实现婚恋社交网络多维度分析案例;

第23章Spark集群中Mapper端、Reducer端内存调优;

第24章 使用Broadcast实现Mapper端Shuffle聚合功能的原理和调优实战;

第25章 使用Accumulator高效地实现分布式集群全局计数器的原理和调优案例;

第27章 Spark五大子框架调优最佳实践;

第28章 Spark
2.2.0
新一代钨丝计划优化引擎;

第30章 Spark性能调优之数据倾斜调优一站式解决方案原理与实战;

第31章 Spark大数据性能调优实战专业之路。

其中,段智华根据自身多年的大数据工作经验对本书的案例等部分进行了扩展。

除上述章节外,剩余内容由夏阳、郑采翎、闫恒伟三位作者根据
王家林
老师的大数据授课内容而完成。

在阅读本书的过程中,如发现任何问题或有任何疑问,可以加入本书的阅读群(QQ:418110145)讨论,会有专人答疑。同时,该群也会提供本书所用案例源码及本书的配套学习视频。

如果读者想要了解或者学习更多大数据相关技术,可以关注DT大数据梦工厂微信公众号DT_Spark,也可以通过YY客户端登录68917580永久频道直接体验。


王家林
老师的新浪微博是http://weibo.com/ilovepains/ 欢迎大家在微博上与作者进行        互动。

由于时间仓促,书中难免存在不妥之处,请读者谅解,并提出宝贵意见。

 

王家林2017年中秋之夜于美国硅谷

 

免费在线读

第3章  Spark的灵魂:RDD和DataSet  本章重点讲解Spark的RDD和DataSet。3.1节讲解RDD的定义、五大特性剖析及DataSet的定义和内部机制剖析;3.2节对RDD弹性特性七个方面进行解析;3.3节讲解RDD依赖关系,包括窄依赖、宽依赖;3.4节解析Spark中DAG逻辑视图;3.5节对RDD内部的计算机制及计算过程进行深度解析;3.6节讲解Spark RDD容错原理及其四大核心要点解析;3.7节对Spark RDD中Runtime流程进行解析;3.8节通过一个WordCount实例,解析Spark RDD内部机制;3.9节基于DataSet的代码,深入分析DataSet一步步转化成为RDD的过程。3.1  为什么说RDD和DataSet是Spark的灵魂  Spark建立在抽象的RDD上,使得它可以用一致的方式处理大数据不同的应用场景,把所有需要处理的数据转化成为RDD,然后对RDD进行一系列的算子运算,从而得到结果。RDD是一个容错的、并行的数据结构,可以将数据存储到内存和磁盘中,并能控制数据分区,且提供了丰富的API来操作数据。Spark一体化、多元化的解决方案极大地减少了开发和维护的人力成本和部署平台的物力成本,并在性能方面有极大的优势,特别适合于迭代计算,如机器学习和图计算;同时,Spark对Scala和Python交互式shell的支持也极大地方便了通过shell直接使用Spark集群来验证解决问题的方法,这对于原型开发至关重要,对数据分析人员有着无法拒绝的吸引力。3.1.1  RDD的定义及五大特性剖析  RDD是分布式内存的一个抽象概念,是一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,能横跨集群所有节点并行计算,是一种基于工作集的应用抽象。  RDD底层存储原理:其数据分布存储于多台机器上,事实上,每个RDD的数据都以Block的形式存储于多台机器上,每个Executor会启动一个BlockManagerSlave,并管理一部分Block;而Block的元数据由Driver节点上的BlockManagerMaster保存,BlockManagerSlave生成Block后向BlockManagerMaster注册该Block,BlockManagerMaster管理RDD与Block的关系,当RDD不再需要存储的时候,将向BlockManagerSlave发送指令删除相应的Block。  BlockManager管理RDD的物理分区,每个Block就是节点上对应的一个数据块,可以存储在内存或者磁盘上。而RDD中的Partition是一个逻辑数据块,对应相应的物理块Block。本质上,一个RDD在代码中相当于数据的一个元数据结构,存储着数据分区及其逻辑结构映射关系,存储着RDD之前的依赖转换关系。  BlockManager在每个节点上运行管理Block(Driver和Executors),它提供一个接口检索本地和远程的存储变量,如memory、disk、off-heap。使用BlockManager前必须先初始化。  BlockManager.scala的部分源码如下所示。1. private[spark] class BlockManager(2.    executorId: String,3.    rpcEnv: RpcEnv,4.    val master: BlockManagerMaster,5.    val serializerManager: SerializerManager,6.    val conf: SparkConf,7.    memoryManager: MemoryManager,8.    mapOutputTracker: MapOutputTracker,9.    shuffleManager: ShuffleManager,10.    val blockTransferService: BlockTransferService,11.    securityManager: SecurityManager,12.    numUsableCores: Int)13.  extends BlockDataManager with BlockEvictionHandler with Logging {    BlockManagerMaster会持有整个Application的Block的位置、Block所占用的存储空间等元数据信息,在Spark的Driver的DAGScheduler中,就是通过这些信息来确认数据运行的本地性的。Spark支持重分区,数据通过Spark默认的或者用户自定义的分区器决定数据块分布在哪些节点。RDD的物理分区是由Block-Manager管理的,每个Block就是节点上对应的一个数据块,可以存储在内存或者磁盘。而RDD中的partition是一个逻辑数据块,对应相应的物理块Block。本质上,一个RDD在代码中相当于数据的一个元数据结构(一个RDD就是一组分区),存储着数据分区及Block、Node等的映射关系,以及其他元数据信息,存储着RDD之前的依赖转换关系。分区是一个逻辑概念,Transformation前后的新旧分区在物理上可能是同一块内存存储。  Spark通过读取外部数据创建RDD,或通过其他RDD执行确定的转换Transformation操作(如map、union和groubByKey)而创建,从而构成了线性依赖关系,或者说血统关系(Lineage),在数据分片丢失时可以从依赖关系中恢复自己独立的数据分片,对其他数据分片或计算机没有影响,基本没有检查点开销,使得实现容错的开销很低,失效时只需要重新计算RDD分区,就可以在不同节点上并行执行,而不需要回滚(Roll Back)整个程序。落后任务(即运行很慢的节点)是通过任务备份,重新调用执行进行处理的。  因为RDD本身支持基于工作集的运用,所以可以使Spark的RDD持久化(persist)到内存中,在并行计算中高效重用。多个查询时,我们就可以显性地将工作集中的数据缓存到内存中,为后续查询提供复用,这极大地提升了查询的速度。在Spark中,一个RDD就是一个分布式对象集合,每个RDD可分为多个片(Partitions),而分片可以在集群环境的不同节点上计算。  RDD作为泛型的抽象的数据结构,支持两种计算操作算子:Transformation(变换)与Action(行动)。且RDD的写操作是粗粒度的,读操作既可以是粗粒度的,也可以是细粒       度的。

Spark大数据商业实战三部曲:内核解密|商业案例|性能调优 pdf下载声明

本pdf资料下载仅供个人学习和研究使用,不能用于商业用途,请在下载后24小时内删除。如果喜欢,请购买正版

pdf下载地址

版权归出版社和作者所有,下载链接已删除。如果喜欢,请购买正版!

链接地址:Spark大数据商业实战三部曲:内核解密|商业案例|性能调优