你的数据根本不够大,别老扯什么Hadoop了


本文原名“Don’t use Hadoop when your data isn’t that big ”,出自有着多年从业经验的数据科学家Chris Stucchio,纽约大学柯朗研究所博士后,搞过高频交易平台,当过创业公司的CTO,更习惯称自己为统计学者。对了,他现在自己创业,提供数据分析、推荐优化咨询服务,他的邮件是:stucchio@gmail.com 。


     有人问我,“你在大数据和Hadoop方面有多少经验?”我告诉他们,我一直在使用Hadoop,但是很少处理几TB以上数据的任务 。我基本上只是一个大数据新手——知道概念,写过代码,但是没有大规模经验。

      他们又问我,“你能使用Hadoop做简单的group by(分组)和sum(统计)吗?”我说当然可以,但我会说需要看具体的文件格式。

他们给我一个U盘,里面存储600MB数据(他们所有的数据,而不是样本数据)。不知道为什么,我用pandas.read_csvPandas是一种Python数据分析库)解决方案,而不是Hadoop完成了这个任务后,他们显得很不满意。

      Hadoop实际上是有很多局限性的。Hadoop可以运行一个通用的计算,下面我用伪码进行说明:

Scala风格的伪码:

collection.flatMap( (k,v) => F(k,v) ).groupBy( _._1 ).map( _.reduce( (k,v) => G(k,v) ) )

使用SQL风格的伪码表示

SELECT G(...) FROM table GROUP BY F(...)

      或者想我多年解释一样:

目标:统计计算图书馆书籍的数量  
Map:你统计奇数书架上书的数量,我统计偶数书架上书的数量。(做统计的人越多,统计出结果越快,就是机器越多,效率越高)  
Reduce:把我们每个人单独统计的结果数据加在一起。

        我们所做的只有两个:F(k,v)和G(k,v),除非要在中间步骤中做性能优化,其他一切都是固定的。

    在Hadoop里,所有计算都必须按照一个map、一个group by、一个aggregate或者这种计算序列来写。这和穿上紧身衣一样,多憋得慌啊。许多计算用其他模型其实更适合。穿上紧身衣(使用hadoop)的唯一原因就是,可以扩展到极大的数据集。可大多数情况,你的数据集很可能根本远远够不上那个数量级。

    可是呢,因为Hadoop和大数据是热词,世界有一半的人都想穿上紧身衣,即使他们实际不需要Hadoop。

一、如果我的数据量是几百兆,Excel可能没法加载它
        对于Excel来说的“很大的数据”并非大数据,其实还有其它极好的工具可以使用——我喜欢的是基于Numpy库之上Pandas。它可以将几百MB数据以高效的向量化格式加载到内存,在我购买已3年的笔记本上,一眨眼的功夫,Numpy就能完成1亿次浮点计算。Matlab和R也是极好的工具。

      Pandas构建于Numpy库之上,可以以矢量格式的方式有效地把数百兆的数据载入到内存中。在我购买已3年的笔记本上,它可以用Numpy在一眨眼的功夫把1亿的浮点数乘在一起。Matlab和R也是极好的工具。
       因此,对于几百兆的数据量,典型的做法是写一个简单的Python脚本逐行读取,处理,然后写到了一个文件就行了

二、可我的数据是10GB呢?
       我买了台新笔记本,它有16GB的内存(花$141.98)和256GB的SSD(额外200美元)。,如果在Pandas里加载一个10GB的csv文件,实际在内存里并没有那么大(内存不是占有10G)——可以将 “17284932583” 这样的数值串存为4位或者8位整数,“284572452.2435723”存为8位双精度。

    最坏的情况下你还可以不同时将所有数据都一次加载到内存里。

三、可我的数据是100GB、500GB或1TB呢?

     一个2T的硬盘才94.99美元,4T是169.99。买一块,加到桌面PC或者服务器上,然后装上PostgreSQL来解决它

四、Hadoop << SQL或Python脚本

       在计算的表达能力来说,Hadoop比SQL差。Hadoop里能写的计算,在SQL或者简单的Python脚本都可以更轻松地写出来。
       SQL是一个直观的查询语言,适合做业务分析,业务分析师和程序员都很常用。SQL查询非常简单,而且还非常快——只有数据库使用了正确的索引,要花几秒钟的sql查询都不太常见。

     Hadoop没有索引的概念,Hadoop只有全表扫描,而且Hadoop抽象层次太多了——我之前的项目尽在应付Java内存错误( java memory errors)、内存碎片和集群竞用了,而这些时间远多于实际的数据分析工作。

      如果你的数据并不是像SQL表那样的结构化数据(比如纯文本、JSON对象、二进制对象),通常是直接写一个小的Python脚本或者Ruby脚本逐行处理更直接。保存到多个文件,然后逐个处理即可,SQL不适用的情况下,从编程来说Hadoop也没那么糟糕,但相比Python脚本仍然没有什么优势。

    除了难以编程,Hadoop还一般总是比其他技术方案要慢。只要索引用得好,SQL查询非常快。比如要计算join,PostgreSQL只需查看索引(如果有),然后查询所需的每个键。而Hadoop呢,必须做全表扫描,然后重排整个表。排序通过多台机器之间分片可以加速,但也带来了跨多机数据流处理的开销。如果要处理二进制文件,Hadoop必须反复访问namenode。而简单的Python脚本只要反复访问文件系统即可。

五、我的数据超过了5TB

     只能使用Hadoop,而无需做过多的选择。

    你的命可真苦——只能苦逼地折腾Hadoop了,没有太多其他选择(可能还能用许多硬盘容量的高富帅机器来扛),而且其他选择往往贵得要命(脑海中浮现出IOE等等字样……)。

    用Hadoop唯一的好处是扩展。如果你的数据是一个数TB的单表,那么全表扫描是Hadoop的强项。此外的话(如果你没有这样大数据量的表),请关爱生命,尽量远离Hadoop。它带来的烦恼根本不值,用传统方法既省时又省力。

六、Hadoop是一个极好的工具

         我并不讨厌Hadoop,当我用其它工具不能很好处理数据时我会选择Hadoop。另外,我推荐使用Scalding,不要使用Hive或Pig。Scalding支持使用Scala语言来编写Hadoop任务链,隐藏了其下的MapReduce。

转自:http://blog.csdn.net/hguisu/article/details/12585383

原创文章,作者:s19930811,如若转载,请注明出处:http://www.178linux.com/2621

(0)
上一篇 2015-04-04 21:39
下一篇 2015-04-04 21:48

相关推荐

  • Linux文本处理三剑客之awk详解

    前言 awk是一款强大的报告生成器,不同于sed和grep,它的侧重点是如何把文本信息更好的展示出来,常用与统计和格式化输出。awk相当于微型的shell,有着自己一套语法结构,例如:循环结构,数组,条件判断,函数,内置变量等功能。处理对象一般纯文本文件或纯文本信息。 用法详解 基本语法 awk [options] 'progra…

    Linux干货 2015-04-29
  • select和case用法

    一、作业 1、斐波那契数列又称黄金分割数列,因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2) 写一个函数,求n阶斐波那契数列 2、汉诺塔(又称河内塔)问…

    Linux干货 2016-08-21
  • 正则表达式和grep用法,及文本查看、处理工具

    概念 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。(维基百科) 通俗…

    2017-10-21
  • 运维的危险命令,用了必死(1)

    Linux命令行佷有用、很高效,也很有趣,但有时候也很危险,尤其是在你不确定你自己在正在做什么时候。这篇文章并不打算引来你对Linux或linux 命令行的愤怒。我们只是想让你意识到在你运行某些命令时应该三思而后行。(译注:当然,以下命令通常都是在root权限下才能将愚蠢发挥到无可救药;在普通用户身份下,破坏的只是自己的一亩三分地。)

    2017-11-16
  • 通配符、正则表达式小计

    基本通配符:    *: 匹配任意长度的任意字符;    ?: 匹配任意的单个字符;    []: 匹配指定范围内的任意单个字符;    [^]: 匹配非指定范围内的任意单个字符;   简单示例:   &nbs…

    Linux干货 2017-03-16
  • 第六周

      第6周   1 复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#; cp /etc/rc.d/rc.sysinit ; sed -i 's@^[[:space:]]\+@#@g&#03…

    Linux干货 2017-02-13