写点什么

我们常常意识不到问题的存在,直到有人解决了这些问题

2019 年 2 月 25 日

我们常常意识不到问题的存在,直到有人解决了这些问题

Hadoop MapReduce 虽然已经可以满足大数据的应用场景,但是其执行速度和编程复杂度并不让人们满意。于是 UC Berkeley 的 AMP Lab 推出的 Spark 应运而生,Spark 拥有更快的执行速度和更友好的编程接口,在推出后短短两年就迅速抢占 MapReduce 的市场份额,成为主流的大数据计算框架。


读到这里请你先停一下,请给这段看似“没毛病”的引子找找问题。


不知道你意识到没有,我在这段开头说的,“Hadoop MapReduce 虽然已经可以满足大数据的应用场景,但是其执行速度和编程复杂度并不让人们满意”,这句话其实是错误的。这样说好像可以让你更加清晰地看到事物发展的因果关系,同时也可以暗示别人自己有洞察事物发展规律的能力。然而,这种靠事后分析的因果规律常常是错误的,往往把结果当作了原因。


事实上,在 Spark 出现之前,我们并没有对 MapReduce 的执行速度不满,我们觉得大数据嘛、分布式计算嘛,这样的速度也还可以啦。至于编程复杂度也是一样,一方面 Hive、Mahout 这些工具将常用的 MapReduce 编程封装起来了;另一方面,MapReduce 已经将分布式编程极大地简化了,当时人们并没有太多不满。


真实的情况是,人们在 Spark 出现之后,才开始对 MapReduce 不满。原来大数据计算速度可以快这么多,编程也可以更简单。而且 Spark 支持 Yarn 和 HDFS,公司迁移到 Spark 上的成本很小,于是很快,越来越多的公司用 Spark 代替 MapReduce。也就是说,因为有了 Spark,才对 MapReduce 不满;而不是对 MapReduce 不满,所以诞生了 Spark。真实的因果关系是相反的。


这里有一条关于问题的定律分享给你:我们常常意识不到问题的存在,直到有人解决了这些问题。


当你去询问人们有什么问题需要解决,有什么需求需要被满足的时候,他们往往自己也不知道自己想要什么,常常言不由衷。但是如果你真正解决了他们的问题,他们就会恍然大悟:啊,这才是我真正想要的,以前那些统统都是“垃圾”,我早就想要这样的东西(功能)了。


所以顶尖的产品大师(问题解决专家),并不会拿着个小本本四处去做需求调研,问人们想要什么。而是在旁边默默观察人们是如何使用产品(解决问题)的,然后思考更好的产品体验(解决问题的办法)是什么。最后当他拿出新的产品设计(解决方案)的时候,人们就会视他为知己:你最懂我的需求(我最懂你的设计)。


乔布斯是这样的大师,Spark 的作者马铁也是这样的专家。


说了那么多,我们回到 Spark。Spark 和 MapReduce 相比,有更快的执行速度。下图是 Spark 和 MapReduce 进行逻辑回归机器学习的性能比较,Spark 比 MapReduce 快 100 多倍。



除了速度更快,Spark 和 MapReduce 相比,还有更简单易用的编程模型。使用 Scala 语言在 Spark 上编写 WordCount 程序,主要代码只需要三行。


val textFile = sc.textFile("hdfs://...")val counts = textFile.flatMap(line => line.split(" "))                 .map(word => (word, 1))                 .reduceByKey(_ + _)counts.saveAsTextFile("hdfs://...")
复制代码


不熟悉 Scala 语言没关系,我来解释一下上面的代码。


第 1 行代码:根据 HDFS 路径生成一个输入数据 RDD。


第 2 行代码:在输入数据 RDD 上执行 3 个操作,得到一个新的 RDD。


  • 将输入数据的每一行文本用空格拆分成单词。

  • 将每个单词进行转换,word => (word, 1),生成<Key, Value>的结构。

  • 相同的 Key 进行统计,统计方式是对 Value 求和,(_ + _)。


第 3 行代码:将这个 RDD 保存到 HDFS。


RDD 是 Spark 的核心概念,是弹性数据集(Resilient Distributed Datasets)的缩写。RDD 既是 Spark 面向开发者的编程模型,又是 Spark 自身架构的核心元素。


我们先来看看作为 Spark 编程模型的 RDD。我们知道,大数据计算就是在大规模的数据集上进行一系列的数据计算处理。MapReduce 针对输入数据,将计算过程分为两个阶段,一个 Map 阶段,一个 Reduce 阶段,可以理解成是面向过程的大数据计算。我们在用 MapReduce 编程的时候,思考的是,如何将计算逻辑用 Map 和 Reduce 两个阶段实现,map 和 reduce 函数的输入和输出是什么,这也是我们在学习 MapReduce 编程的时候一再强调的。


而 Spark 则直接针对数据进行编程,将大规模数据集合抽象成一个 RDD 对象,然后在这个 RDD 上进行各种计算处理,得到一个新的 RDD,继续计算处理,直到得到最后的结果数据。所以 Spark 可以理解成是面向对象的大数据计算。我们在进行 Spark 编程的时候,思考的是一个 RDD 对象需要经过什么样的操作,转换成另一个 RDD 对象,思考的重心和落脚点都在 RDD 上。


所以在上面 WordCount 的代码示例里,第 2 行代码实际上进行了 3 次 RDD 转换,每次转换都得到一个新的 RDD,因为新的 RDD 可以继续调用 RDD 的转换函数,所以连续写成一行代码。事实上,可以分成 3 行。


val rdd1 = textFile.flatMap(line => line.split(" "))val rdd2 = rdd1.map(word => (word, 1))val rdd3 = rdd2.reduceByKey(_ + _)
复制代码


RDD 上定义的函数分两种,一种是转换(transformation)函数,这种函数的返回值还是 RDD;另一种是执行(action)函数,这种函数不再返回 RDD。


RDD 定义了很多转换操作函数,比如有计算 map(func)、过滤 filter(func)、合并数据集 union(otherDataset)、根据 Key 聚合 reduceByKey(func, [numPartitions])、连接数据集 join(otherDataset, [numPartitions])、分组 groupByKey([numPartitions])等十几个函数。


我们再来看看作为 Spark 架构核心元素的 RDD。跟 MapReduce 一样,Spark 也是对大数据进行分片计算,Spark 分布式计算的数据分片、任务调度都是以 RDD 为单位展开的,每个 RDD 分片都会分配到一个执行进程去处理。


RDD 上的转换操作又分成两种,一种转换操作产生的 RDD 不会出现新的分片,比如 map、filter 等,也就是说一个 RDD 数据分片,经过 map 或者 filter 转换操作后,结果还在当前分片。就像你用 map 函数对每个数据加 1,得到的还是这样一组数据,只是值不同。实际上,Spark 并不是按照代码写的操作顺序去生成 RDD,比如“rdd2 = rdd1.map(func)”这样的代码并不会在物理上生成一个新的 RDD。物理上,Spark 只有在产生新的 RDD 分片时候,才会真的生成一个 RDD,Spark 的这种特性也被称作惰性计算


另一种转换操作产生的 RDD 则会产生新的分片,比如 reduceByKey,来自不同分片的相同 Key 必须聚合在一起进行操作,这样就会产生新的 RDD 分片。实际执行过程中,是否会产生新的 RDD 分片,并不是根据转换函数名就能判断出来的,具体我们下一期再讨论。


总之,你需要记住,Spark 应用程序代码中的 RDD 和 Spark 执行过程中生成的物理 RDD 不是一一对应的,RDD 在 Spark 里面是一个非常灵活的概念,同时又非常重要,需要认真理解。


当然 Spark 也有自己的生态体系,以 Spark 为基础,有支持 SQL 语句的 Spark SQL,有支持流计算的 Spark Streaming,有支持机器学习的 MLlib,还有支持图计算的 GraphX。利用这些产品,Spark 技术栈支撑起大数据分析、大数据机器学习等各种大数据应用场景。



我前面提到,顶尖的产品设计大师和问题解决专家,不会去询问人们想要什么,而是分析和观察人们的做事方式,从而思考到更好的产品设计和问题解决方案。


但是这种技巧需要深邃的观察力和洞察力,如果没有深度的思考,做出的东西就会沦为异想天开和自以为是。要知道大众提出的需求虽然也无法触及问题的核心,但是好歹是有共识的,大家都能接受,按这种需求做出的东西虽然平庸,但是不至于令人厌恶。


而缺乏洞见的自以为是则会违反常识,让其他人本能产生排斥感,进而产生对立情绪。这种情绪之下,设计没有了进一步改进的基础,最后往往成为悲剧。这两年在所谓互联网思维的鼓吹下,一些缺乏专业技能的人,天马行空创造需求,受到质疑后公开批评用户,也是让人倍感惊诧。


我们在自己的工作中,作为一个不是顶尖大师的产品经理或工程师,如何做到既不自以为是,又能逐渐摆脱平庸,进而慢慢向大师的方向靠近呢?


有个技巧可以在工作中慢慢练习:不要直接提出你的问题和方案,不要直接说“你的需求是什么?”“我这里有个方案你看一下”。


直向曲中求,对于复杂的问题,越是直截了当越是得不到答案。迂回曲折地提出问题,一起思考问题背后的规律,才能逐渐发现问题的本质。通过这种方式,既能达成共识,不会有违常识,又可能产生洞见,使产品和方案呈现闪光点。


  • 你觉得前一个版本最有意思(最有价值)的功能是什么?

  • 你觉得我们这个版本应该优先关注哪个方面?

  • 你觉得为什么有些用户在下单以后没有支付?


作者介绍


李智慧,极客时间《从0开始学大数据》专栏讲师,同程艺龙交通首席架构师、Apache Spark 源代码贡献者,长期从事大数据、大型网站架构的研发工作,曾担任阿里巴巴技术专家、Intel 亚太研发中心架构师、宅米和 WiFi 万能钥匙 CTO,有超过 6 年的线下咨询、培训经验,著有畅销书《大型网站技术架构:核心原理与案例分析》。


2019 年 2 月 25 日 15:325224

评论 1 条评论

发布
用户头像
这篇文章太牛逼了
2019 年 12 月 05 日 23:50
回复
没有更多了
发现更多内容

企业应用AI之路怎么走?飞桨实践有真知

百度大脑

AI 飞桨

构建高可用的MySQL

林一

MySQ MySQL 高可用 Maxscale

面试官:如何给字符串设计索引?

JavaFish

MySQL 索引 字符串 索引优化

小白必看的,JS中循环语句大集合

华为云开发者社区

JavaScript js 循环语句 while循环 for循环

☕️【Java技术之旅】带你一起探究String类不可变的特性

李浩宇/Alex

string 原理 字符串 6月日更 6 月日更

TcaplusDB君 · 行业新闻汇编(6月9日)

TcaplusDB

nosql tencentdb TcaplusDB NoSQL数据库

react源码解析9.diff算法

全栈潇晨

react源码

阿里大神亲码“Java面试笔记”,不讲一句废话,全是精华

菜菜山

Java 程序员 架构 面试

质量分析工具-监控大厅大揭秘

anyRTC开发者

音视频 WebRTC sdk

想做DBA,多租户管理你一定要知道这些

华为云开发者社区

多租户 GaussDB(DWS) 资源池 存储空间 资源隔离

TcaplusDB | 行业新闻汇编(6月1日)

数据人er

数据库 游戏 tencentdb TcaplusDB

如何科学制定和管理项目计划?

万事ONES

项目管理 ONES 项目经理

[TcaplusDB知识库]TcaplusDB限制条件

TcaplusDB

数据库 nosql tencentdb TcaplusDB

☕️【Java 技术之旅】带你一起攻克String类创建的难点分析

李浩宇/Alex

Java string pool string 6月日更 6 月日更

如何针对美工与设计师的Maya工具进行版本控制

龙智—DevOps解决方案

24道几乎必问的JVM面试题,我只会7道,你能答出几道?

北游学Java

Java 面试 JVM

阿里云官方出品:全面总结阿里云云原生架构方法论与实践经验

尹文敏

云计算 阿里云 云原生 云原生架构 云原生应用

理解Linux之文件I/O——知其然,知其所以然

奔着腾讯去

文件管理 Linux内核 文件I/O I/O模型

百度灵医智惠明星案例获人民日报点赞:智慧医疗让看病更便捷

百度大脑

人工智能 智慧医疗

面试官:一台服务器能建立的TCP链接真的只有65535个吗?

程序员小毕

Java Linux 程序员 面试 TCP

基于传感器的人体生命体征监控技术

不脱发的程序猿

物联网 传感器 智能医疗 人体生命体征监控技术

「Adobe国际认证」PS软件通过"内容识别填充"从照片中移去对象

Adobe国际认证

硬核!最全“Java25面试宝典+Java29核心知识集”,一箭双雕杠秋招!

不秃顶的Java程序员

Java 程序员

准备3个月,面试10分钟,Java中高级岗面试为何越来越难?

Java架构师迁哥

六一儿童节 | TcaplusDB祝大小朋友节日快乐

数据人er

数据库 nosql tencentdb TcaplusDB

带你剖析鸿蒙轻内核任务栈的源代码

华为云开发者社区

鸿蒙 任务栈 任务调度 任务上下文

宜兴牵手百度智能云共建人工智能应用中心,推动数字经济创新发展

百度大脑

人工智能

程序员需要了解数据库知识么?

escray

极客时间 学习笔记 朱赟的技术管理课 六月日更

福利时刻 十年黑客大佬的Web安全渗透技术分享

学神来啦

Linux 黑客 安全 运维自动化

毕昇JDK:为啥是ARM上超好用的JDK

华为云开发者社区

Java 华为 jdk Openjdk 毕昇 JDK

博云作为专业独立PaaS厂商,入选中国PaaS市场研究报告

BoCloud博云

PaaS

我们常常意识不到问题的存在,直到有人解决了这些问题-InfoQ