使用 Hadoop 的 Ruby
在 shell 环境中您的 map 和 reduce 脚本按预期工作,通过 Hadoop 将它们放入测试中。我将会跳过 Hadoop 安装任务(参考本系列的 用 Hadoop 进行分布式数据处理,第 1 部分:入门 或 用 Hadoop 进行分布式数据处理,第 2 部分:进阶 以便建立 Hadoop 并使其运行)。
第一步将要在 HDFS 内为您的输入信息创建输入字典,然后提供一个将测试您脚本的简单文件。清单 9 说明了此步骤(有关这些步骤的更多信息,请参考本系列的 用 Hadoop 进行分布式数据处理,第 1 部分:入门 或 用 Hadoop 进行分布式数据处理,第 2 部分:进阶)。
清单 9. 为 MapReduce 过程创建输入数据
| # hadoop fs -mkdir input # hadoop dfs -put /usr/src/linux-source-2.6.27/Documentation/memory-barriers.txt input # hadoop fs -ls input Found 1 items -rw-r--r-- 1 root supergroup 78031 2010-06-04 17:36 /user/root/input/memory-barriers.txt # |
下一步,使用 流 实用工具,通过自定义脚本来调用 Hadoop,简化输出的输入数据和位置(请参考清单 10)。在此示例中请注意 -file 选项会简单地告诉 Hadoop 来打包您的 Ruby 脚本作为部分作业提交。
清单 10. 通过 Ruby MapReduce 脚本使用 Hadoop 流
# hadoop jar /usr/lib/hadoop-0.20/ contrib/streaming/hadoop-0.20.2+228-streaming.jar \ -file /home/mtj/ruby/map.rb -mapper /home/mtj/ruby/map.rb \ -file /home/mtj/ruby/reduce.rb -reducer /home/mtj/ruby/reduce.rb \ -input input/* -output output packageJobJar: [/home/mtj/ruby/map.rb, /home/mtj/ruby/reduce.rb, /var/lib/hadoop-0.20/... 10/06/04 17:42:38 INFO mapred.FileInputFormat: Total input paths to process : 1 10/06/04 17:42:39 INFO streaming.StreamJob: getLocalDirs(): [/var/lib/hadoop-0.20/... 10/06/04 17:42:39 INFO streaming.StreamJob: Running job: job_201006041053_0001 10/06/04 17:42:39 INFO streaming.StreamJob: To kill this job, run: 10/06/04 17:42:39 INFO streaming.StreamJob: /usr/lib/hadoop-0.20/bin/hadoop job ... 10/06/04 17:42:39 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/... 10/06/04 17:42:40 INFO streaming.StreamJob: map 0% reduce 0% 10/06/04 17:43:17 INFO streaming.StreamJob: map 100% reduce 0% 10/06/04 17:43:26 INFO streaming.StreamJob: map 100% reduce 100% 10/06/04 17:43:29 INFO streaming.StreamJob: Job complete: job_201006041053_0001 10/06/04 17:43:29 INFO streaming.StreamJob: Output: output # |
最后,通过 hadoop 实用工具使用 cat 文件系统操作来探索输出(请参考清单 11)。
Listing 11. Exploring the Hadoop output # hadoop fs -ls /user/root/output Found 2 items drwxr-xr-x - root supergroup 0 2010-06-04 17:42 /user/root/output/_logs -rw-r--r-- 1 root supergroup 23014 2010-06-04 17:43 /user/root/output/part-00000 # hadoop fs -cat /user/root/output/part-00000 | head -12 +--->| 4 immediate 2 Alpha) 1 enable 1 _mandatory_ 1 Systems 1 DMA. 2 AMD64 1 {*C,*D}, 2 certainly 2 back 2 this 23 # |
在不到 30 行的脚本中,您已经在 Hadoop 框架内实现了 map 和 reduce 元素并演示了它们的执行。虽然是一个简单的示例,但是通过自定义的和专有的算法说明了 Hadoop 背后真实的力量以及为什么 Hadoop 正在成为一种用于处理大型数据集的流行框架。
Hadoop 的其他应用程序
Hadoop 可用于许多应用程序上,其已超越了为大型数据集简单计算字数的工作。所有这一切的需要就是用矢量格式表达 Hadoop 基础设施可以使用的数据。虽然规范的示例使用矢量表达作为键和值,但是并没有限制您如何来定义值(例如一些值的汇总)。在更加丰富的应用程序集中此灵活性可以为 Hadoop 创造新的机会。
一个一直适合 MapReduce 字数统计模型的有趣的应用程序正在把 Web 服务器访问的频率制表(在开创性 Google 文章中讨论)。对于此应用程序来说,URL 作为键来服务(从 Web 服务器访问日志摄取)。reduce 过程的结果是基于 Web 服务器日志的给定 Web 站点的每次 URL 访问的总数。
在计算机学习用户程序中,Hadoop 已经作为处理大量 GA 个体的规模遗传算法的一种方法(潜在解决方案)。map 过程执行传统的遗传算法,从本地池中搜索最佳单个解决方案。然后 reduce 应用程序成为来自 map 阶段的单个解决方案的集成。这会允许单个节点识别最佳解决方案,然后允许这些解决方案在最适于生存的分布式显示的 reduce 阶段中相互竞争。
另外一个有趣的应用程序被创建用于识别僵尸网络的垃圾邮件。此过程的第一步将会为减少垃圾邮件为目的而对电子邮件按来自给定组织而进行分类(基于一组指纹)。根据过滤的这些数据,对以特定方式(例如参考电子邮件正文中的相同链接)连接的邮件生成一个图表。然后这些相关电子邮件会减少至主机(静态或动态 IP 地址)以识别有问题的僵尸网络。
在应用程序之外通过 map 和 reduce 基元来查看世界,Hadoop 作为在计算机集群之间分配工作的方式非常有用。 Map 和 reduce 并非必须强制某种特定类型的应用程序。相反地,Hadoop 可以被视为一种可以同时将数据和算法分配到主机以获得更快速的并行处理速度的方法。
Hadoop 应用程序生态系统
虽然 Hadoop 提供了一个灵活的架构,但也可以使用其他应用程序转换与其他应用程序的界面。一个有趣的示例称为 Hive,它是一个具有自己特定查询语言(称为 Hive QL)的数据仓库基础结构。Hive 使得 Hadoop 更加熟悉结构化查询语言 (SQL) 背景,同时还支持传统的 MapReduce 基础结构来进行数据处理。
HBase 是另外一种位于 HDFS 顶部的有趣的应用程序。它是一个类似于 Google BigTable 的高性能数据库系统。代替传统的文件处理,HBase 使数据库将 MapReduce 处理的输入和输出格式列表。
最后,Pig 是 Hadoop 中用于分析大型数据集的平台。Pig 提供可编译 map 和 reduce 应用程序的高级语言。
进一步的学习
这是 Hadoop 系列 的最后一篇文章,探索了在适用于 Hadoop 框架的 Ruby 中开发 map 和 reduce 应用程序。希望从这篇文章您可以看到 Hadoop 的真正力量。虽然 Hadoop 将您限制在一个特定的编程模型中,但是这种模型是灵活的且可被应用到大量的应用程序上。
前两篇文章:
用 Hadoop 进行分布式数据处理(入门)
用 Hadoop 进行分布式数据处理(进阶)