眼下在媒体上有非常大的关于Apache Spark框架的声音,渐渐的它成为了大数据领域的下一个大的东西。

证明这件事的最简单的方式就是看google的趋势图:

上图展示的过去两年Hadoop和Spark的趋势。Spark在终端用户之间变得越来越受欢迎,并且这些用户常常在网上找Spark相关资料。这给了Spark起了非常大的宣传作用。同一时候环绕着它的也有误区和思维错误,并且非常多人还把这些误区作为银弹。觉得它能够解决他们的问题并提供比Hadoop好100倍的性能。

这篇文章将为希望在自己系统接入Spark的技术员们解说大家对它的一些主要误区。我要说的是这些误区主要是源于市场上一些专家的谣传和过度简单化。

Spark的文档也非常清楚了反驳了这些专家的观点。可是须要我们去大量阅读。

因此。以下我所提到的误区主要包含以下几个方面:

  1. Spark是一项基于内存的技术
  2. Spark的运行速度比Hadoop快10到100倍
  3. Spark在市场上引入了一种全新的数据处理方式

排在第一位的也是最重要的误区是Spark是一项“基于内存”的技术。

不是的,从来没有不论什么一个Spark开发人员官方的声明过这样的特性。这是基于对Spark计算过程的误解。

可是这里让我们回到開始的问题。究竟什么样的技术才干称之为内存技术?我觉得是能够同意我们将数据存储在内存中并有效处理这些数据的技术。而我们在Spark中看到了什么?它并没有选项能够让我们将数据存放在内存中;尽管Spark有可插拔式的连接器能够连接到非常多持久化存储系统HDFS、Tachyon、HBase、Cassandra等等,可是就是没有自带将数据存储到内存或者硬盘上的代码。

而它所能做的仅仅是缓存数据而不是持久化数据。缓存数据是非常easy会被通过连接器连接的数据源删除或者更新的。

其次,有些人针对我们以上的观点抱怨说。Spark是在内存中处理数据的啊。当然是在内存中处理,由于你没有选择来使用其它方式来处理数据;全部在OS API上的操作都仅仅是同意我们将数据从块设备上载入到内存中或将内存中的数据卸载至块设备上。

我们不能直接使用HDD而不将HDD上的数据载入到内存中,所以现代操作系统上的全部数据处理都是在内存中进行的。

其实,Spark对于内存缓存同意我们使用LRU(近期最少使用)回收算法。您可能仍然觉得它是基于内存的技术。至少我们在处理数据时它是在内存中的。

可是让我们再看看RDBMS(关系型数据库系统)市场。这里举两个样例:Oracle和PostgreSQL。

你觉得它们是怎么处理数据的?它们使用共享内存段来作为表page内存池,并且全部的数据读写都是有这个内存池服务的,并且这个内存池也是使用LRU规则来释放并非脏数据的表page内存(并且假设有太多脏的page时会出发检查点来处理)。所以总的来说,现代数据库也利用基于内存的LRU算法来满足它们的需求。那么为什么我们不说Oracle和PostgreSQL为基于内存的数据库呢?还有就是关于Linux
IO,你知道全部传递给操作系统的IO操作的缓存也相同是基于LRU的缓存吗?

甚至,你知道Spark在内存中处理全部transformation吗?你可能感到非常失望,Spark的核心“shuffle”会将数据写入磁盘中,假设我们在我们的Spark SQL语句中使用了group by语句或者我们刚刚讲RDD转换为PairRDD而且通过键来调用聚合操作。那么我们正在强制Spark将数据依据key的哈希值分发到各个数据节点。Shuffle处理包括两个阶段,就是通常所说的“map”和“reduce”:“map”阶段只计算key的哈希值(或者是自己定义的其它切割函数)并将结果输出N个单独的文件到本地磁盘上,当中N就是“reudce”端的分区数。“Reduce”端拉取“map”端的计算结果并将其合并新的分区,因此假设我们的RDD有M个分区,则我们将它转换为一对RDD时会在集群中生成M*N个文件。这些文件包括RDD中的全部数据;有一些优化手段能够降低生成的文件数量;此外另一些工作来预排序这些文件而且在“reduce”端“合并”这些文件,但这并不能改变假设我们想要处理数据就得将数据放入HDD的事实。

所以,Spark并非一项基于内存的技术。这是一项能够让我们有效的利用基于内存的LRU方法在内存存满时将数据卸载至硬盘中;并且它没有内置持久化功能(内存、硬盘都没有)。它会在shuffle过程中将全部数据放到本地文件系统中。

下一个误区是“Spark运行速度比Hadoop快10到100倍”。

这里我们引用一篇早先发表的文章:http://laser.inf.ethz.ch/2013/material/joseph/LASER-Joseph-6.pdf。这篇文章声称Spark的目标是支持迭代的任务,典型的机器学习。可是假设我们參考Apache站点上Spark的主页时就会再次发现一个让我们眼前一亮的样例:

此外,上图中这个样例是关于机器学习算法“logistic回归分析”的。那么什么是机器学习中最基本的部分呢?那就是在同一个数据集上的多次的重复迭代。而这里正是Spark的内存中缓存LRU算法的真正亮点;当我们重复的连续多次扫描同一组数据时,我们仅仅须要在第一次使用这些数据的时候才去读取它。其后都是从内存中读取这些数据。这样的做法真的非常好;但不幸的是,他们用比較奇怪的方式来执行这些脚本:尽管在Hadoop上执行这些脚本但却没有使用HDFS的缓存功能(http://hadoop.apache.org/docs/r2.3.0/hadoop-project-dist/hadoop-hdfs/CentralizedCacheManagement.html)

当然他们没有义务一定要这样去做,可是我觉得就是这个不同会导致性能下降3到4倍(更高效的实现方式是不将中间数据放入HDD,这样任务启动更快)。

压力測试在企业领域的悠久历史教会了我一件事:从来不要相信压力測试。对于不论什么两个有竞争关系的系统我们都能找到一系列样例来证明系统A比系统B快,相同也能找到非常多文章来证明系统B比系统A快。

我们所能相信的(当然也要保持怀疑态度)的是独立的第三方压測工具,如TCP-H。由于它们是独立的,所以会覆盖尽可能多的场景来展示真实的性能情况。

总的来说。Spark比Hadoop快主要是由于:

  1. 任务启动更快。Spark使用线程,而MR则又一次启动了新的JVM。
  2. Shuffle阶段更快。Spark在shuffle期间只将数据放入HDD一次;而MR做了两次。
  3. 工作流更快。传统的MR工作流是一系列MR job,每一个job在迭代时都会讲数据存入HDFS。而Spark支持DGA和管道操作。这样就能够让我们运行复杂的工作流而不用将中间数据持久化(除非要进行shuffle)。

  4. 缓存。对于这点持怀疑态度,由于眼下HDFS也能够使用缓存,但总的来说Spark缓存还是很好的,尤其是它的SparkSQL部分会将数据缓存在面向列的表单中。

以上全部这些使得Spark性能比Hadoop要好,对执行时间比較短的任务来说能达到Hadoop的100倍。但在真实的生产环境中不会超过2.5到3倍。

最后的一个被非常少提及的误区是:“Spark在市场上引入了一种全新的数据处理方法”。其实,Spar没有引入不论什么新的改革。尽管他们在实现高效的LRU缓存和pipeline上的想法非常好。但他们并非前无古人的。假设我们打开思维去思考这个问题,我们可能会发现所实现的差点儿和早先MPP数据库中所引入的概念全然一样:查询的管道式运行、没有中间数据会持久化、对表的页数据进行LRU缓存。如你所见,Spark的核心和其之前的技术并没有不同。当然。有一个非常大的进步就是Spark用开源的方式实现了这些,而且通过互联网社区免费提供给了用户。而对于企业来说能够在不减少性能的前提下不用再去支付企业级的MPP技术费用。

最后,我建议大家不要相信我们从媒体上所听到的不论什么事情。相信相关方面的技术专家。他们一般是我们最好的提问者。

1. 本文由程序猿学架构翻译

2.原文地址:http://0x0fff.com/spark-misconceptions/

2. 转载请务必注明本文出自:程序猿学架构(微信号:archleaner)

3. 很多其它文章请扫码:

Spark迷思的更多相关文章

  1. [No00002E]关于大数据,你不知道的6个迷思

    还是那个观点:计算机,编程语言,互联网,大数据等等都只是工具! 导语:看过美剧<纸牌屋>没?知道这部"白宫甄嬛传"为什么会火吗?靠的是大!数!据! 过去两年,在 Net ...

  2. paip.提升效率--僵尸代码的迷思

    paip.提升效率--僵尸代码的迷思 僵尸代码是指你的代码库里被注释掉的那部分代码, 很少去使用它,就像僵尸一样, 看雷kill-the-zombies-in-your-code ========== ...

  3. 前端迷思与React.js

    前端迷思与React.js 前端技术这几年蓬勃发展, 这是当时某几个项目需要做前端技术选型时, 相关资料整理, 部分评论引用自社区. 开始吧: 目前, Web 开发技术框架选型为两种的占 80% .这 ...

  4. Python 装饰器执行顺序迷思

    Table of Contents 1. 探究多个装饰器执行顺序 1.1. 疑问 1.2. 函数和函数调用的区别 1.3. 装饰器函数在被装饰函数定义好后立即执行 1.4. 疑问的解释 2. 参考资料 ...

  5. 深夜Python - 第1夜 - for 迷 in 迷思

    深夜Python - 第1夜 - for 迷 in 迷思 在一个月黑风高的夜晚,我悄悄打开编辑器,进入程序的世界.刚刚学会Python的我,由于一段时间的过度装B,被委托优化一段程序,我信心十足地接下 ...

  6. 承上启下继往开来,Python3上下文管理器(ContextManagers)与With关键字的迷思

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_217 在开发过程中,我们会经常面临的一个常见问题是如何正确管理外部资源,比如数据库.锁或者网络连接.稍不留意,程序将永久保留这些资 ...

  7. android 进程/线程管理(二)----关于线程的迷思

    一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...

  8. JS异步阻塞的迷思

    还是百度前端技术学院的“任务十九”可视化排序算法的题,在写出快速排序算法之后,要求用动画的形式把这个排序过程呈现出来.排序过程在CPU里不过是瞬间的事,但要转换成“缓慢的”动画效果给人类看,就不得不把 ...

  9. 关于App的一些迷思以及一些动画效果开源库的推荐

    http://www.open-open.com/lib/view/open1427856817396.html

随机推荐

  1. java学习之借书系统

    实现的图书借阅系统要处理用户输入的非法参数,并引导用户正确使用 测试结果: 主要目的就是练习异常处理中的Exception类的使用 使用的相关语法 try{ //可能产生异常的代码块 }catch(E ...

  2. ARP欺骗防御工具arpon

    ARP欺骗防御工具arpon   ARP欺骗是局域网最为常见的中人间攻击实施方式.Kali Linux提供一款专用防御工具arpon.该工具提供三种防御方式,如静态ARP防御SARPI.动态ARP防御 ...

  3. SQL Server密码爆破工具SQLdict

    SQL Server密码爆破工具SQLdict SQL Server是Windows系统常用的数据库服务器.它广泛采用用户名和密码方式,进行身份认证.Kali Linux提供一款专用的数据库密码爆破工 ...

  4. [Java]如何把当前时间插入到数据库

    [Java]如何把当前时间插入到数据库 1.在orderDao.java中 /** 设置订单*/ public void setOrder(Order order){ Date time = new ...

  5. SLAM(一)----学习资料整理

    转自:http://www.cnblogs.com/wenhust/ 书籍: 1.必读经典 Thrun S, Burgard W, Fox D. <Probabilistic robotics& ...

  6. Nginx报Primary script unknown的错误解决

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 改成红色部分变量 root   /usr/local/nginx/h ...

  7. [原创]浅谈H5页面性能测试

    [原创]浅谈H5页面性能测试 H5页面我想各位都不陌生,随着移动互联网兴起,不管是App,还是H5都火起来了,最突出的2个表现是ios/android/前端等工程师薪水大涨,尤其是资深前端工程师40W ...

  8. sqlserver 2012 IDE中 Windows身份验证连接服务器报错 ,Login failed for user 'xxx\Administrator'. 原因: 找不到与提供的名称匹配的登录名。

    问题描述: 本地装了两个实例,一个是SQLEXPRESS,可以正常操作.但是另一个开发常用的实例MSSQLSERVER却连Windows身份验证都报错,报的错误也是很奇葩,怎么会找不到Administ ...

  9. ASP.Net中关于WebAPI与Ajax进行跨域数据交互时Cookies数据的传递

    本文主要介绍了ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据传递的相关知识.具有很好的参考价值.下面跟着小编一起来看下吧 前言 最近公司项目进行架构调整,由原来的三层架构改 ...

  10. go标准库DOC与 raft

    http://studygolang.com/static/pkgdoc/index.html https://github.com/avelino/awesome-go#database