热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

应用开发之linq和ef_应用开发

与蒂姆联系蒂姆是我们最受欢迎和最多产的作家之一。在developerWorks上浏览Tim的所有文章。查看Tim的个人资料,并与他,其他作者以及Myde

本系列的前两篇文章重点介绍了针对单节点和多节点集群的Hadoop的安装和配置。 这篇最后的文章探讨了Hadoop中的编程-特别是Ruby语言中的map和reduce应用程序的开发。 我之所以选择Ruby,是因为它首先是您应该了解的一种很棒的面向对象的脚本语言,其次,您将在“ 相关主题”部分中找到大量参考资料,以获取有关 Java™和Python语言的教程。 通过对MapReduce编程的探索,我还将向您介绍流应用程序编程接口(API)。 该API提供了使用Java语言以外的其他语言开发应用程序的方法。

首先,从功能的角度出发,简要介绍一下映射和缩减,然后更深入地研究Hadoop编程模型及其构架,分配,管理工作的架构和元素。

地图的起源与归约

那么,启发MapReduce编程范例的功能要素是什么? 1958年,约翰·麦卡锡(John McCarthy)发明了一种名为Lisp的语言,该语言既实现了数值计算又实现了符号计算,但是以递归的形式实现,而这种形式对于当今使用的大多数语言都是陌生的。 (实际上,在Wikipedia上Lisp有着令人着迷的历史,其中包括有用的教程,非常值得阅读。)Lisp最早在IBM®704上实现,这是第一台大规模生产的计算机,它还支持另一个古老的收藏:FORTRAN。

map函数起源于像Lisp这样的功能语言,但现在在许多其他语言中很常见,它是函数在一系列元素上的应用。 这是什么意思? 清单1提供了与Scheme Shell(SCSH)的解释后的会话,它是Lisp的派生词。 第一行定义了一个名为square的函数,该函数接受一个参数并发出其平方根。 下一行说明了map函数的用法。 如图所示,使用map ,您可以提供函数以及该函数所应用到的元素列表。 结果是一个包含平方元素的新列表。

清单1. SCSH中的map函数的演示

> (define square (lambda (x) (* x x)))
> (map square '(1 3 5 7))
'(1 9 25 49)
>

减少也适用于列表,但通常将列表减少为标量值。 清单2中提供的示例说明了另一个SCSH函数,用于将列表简化为标量-在这种情况下,将值列表以(1 +(2 +(3 +(4 +(5)))))的形式求和。 请注意,这是经典的函数式编程,它依赖于迭代的递归。

清单2.减少SCSH的演示

> (define (list-sum lis) (if (null? lis) 0 (+ (car lis) (list-sum (cdr lis)))))
> (list-sum '(1 2 3 4 5))
15
>

有趣的是,在命令式语言中,递归与迭代一样有效,因为递归在后台被翻译成迭代。

Hadoop的编程模型

Google引入了MapReduce的想法,将其作为用于处理或生成大量数据的编程模型。 在规范模型中, map函数处理键值对,从而产生一组中间的键值对。 然后, reduce函数处理这些中间键/值对,合并关联键的值(请参见图1)。 输入数据以这样一种方式进行分区,即可以将其分布在一组机器中以进行并行处理。 以相同的方式,并行处理生成的中间数据,使该方法非常适合处理大量数据。

图1. MapReduce处理的简化视图
MapReduce处理的简化视图

为了快速上手,请从map的角度看一下图1的体系结构,并减少字数(因为在本文中您将开发map并减少应用程序)。 提供输入数据后(进入Hadoop文件系统[HDFS]),首先将其分区,然后(通过作业跟踪器)分配给地图工作人员。 尽管图2中的示例显示了一个简短的句子被分区的情况,但是通常由于以下原因,要分区的工作量在128MB大小范围内:花费很少的时间进行设置,因此有更多的工作要做以最小化这开销。 地图工作人员(在规范示例中)将工作分解为单个向量,这些向量包含标记词和初始值(在本例中为1)。 映射任务完成时(由任务跟踪程序在Hadoop中定义),将工作提供给reduce worker。 reduce worker将密钥还原为唯一的集合,该值表示找到的密钥数量。

图2.简单的MapReduce示例
简单的MapReduce示例

请注意,此过程可以在同一台计算机上或不同计算机上进行,或者使用不同的数据分区依次或并行进行,结果仍然相同。

尽管规范视图(用于使用字数统计生成搜索索引)是查看Hadoop的一种方法,但事实证明,这种计算模型可以通用地应用于许多计算问题,您将看到。

Hadoop的灵活性

从图2所示的简单示例中,请注意,两个主要元素是mapreduce流程。 尽管对于这些过程的工作方式有传统的看法,但mapreduce以这种方式运行并不需要体系结构。 这是Hadoop的真正功能-灵活地实施mapreduce以解决特定应用程序方式运行的流程。 字数示例非常有用,并且适用于许多问题,但是其他模型仍然适用于此通用框架。 所需要做的就是开发地图并减少应用程序,使流程对Hadoop可见。

在其他应用程序中,Hadoop甚至被用于实现诸如神经网络,支持向量机和k- means聚类之类的算法的机器学习应用程序( 有关更多信息,请参见参考资料一节)。

数据流

尽管Hadoop是基于Java的框架,但可以使用Java语言以外的其他语言编写地图并简化应用程序。 流使这成为可能。 Hadoop中的streaming实用程序实现了一种数据流胶水。 使用streaming实用程序,您可以定义自己的映射并减少可执行文件(每个文件都从标准输入[stdin]中获取输入,并通过标准输出[stdout]提供输出),并且streaming实用程序适当地读写数据,从而以需要(请参见清单3)。

清单3.使用Hadoop流实用程序

hadoop jar $HADOOP_HOME/hadoop-streaming.jar \-input inputData-output outputData-mapper map_exec-reducer reduce_exec

清单3展示了如何在Hadoop中使用streaming实用程序,而图3以图形方式显示了如何定义流。 请注意,这是流使用的一个简单示例。 有许多选项可用于调整数据的解析方式,调整图像的调用方式,为分区器或合并器指定替换图像以及其他配置调整( 有关更多信息,请参阅“ 参考资料”部分)。

图3.图形流示例
图形流示例

Ruby示例

掌握了streaming实用程序的基本知识之后,您就可以编写一个简单的Ruby映射并简化应用程序,并了解如何在Hadoop框架内使用这些流程。 此处的示例与规范的MapReduce应用程序一起使用,但是稍后您将看到其他应用程序(以及如何在map和reduce形式中实现它们)。

从映射器开始。 该脚本从stdin获取文本输入,对其进行标记化,然后向stdout发出一组键/值对。 像大多数面向对象的脚本语言一样,此任务几乎太简单了。 清单4中显示了mapper脚本(带有一些注释和空格,使它更大一些)。 该程序使用迭代器从stdin中读取一行,并使用另一个迭代器将该行拆分为单独的标记。 然后将每个标记(单词)以1的关联值(由制表符分隔)发送到stdout。

清单4. Ruby映射脚本(map.rb)

#!/usr/bin/env ruby# Our input comes from STDIN
STDIN.each_line do |line|# Iterate over the line, splitting the words from the line and emitting# as the word with a count of 1.line.split.each do |word|puts "#{word}\t1"endend

接下来,查看reduce应用程序。 这个稍微复杂一点,但是使用Ruby哈希(关联数组)来简化约简操作(参见清单5)。 该脚本再次处理来自stdin的输入数据(由streaming实用程序传递),并将行拆分为一个单词和一个值。 然后检查哈希值中的单词; 如果找到,则将计数添加到元素。 否则,您将在单词的哈希中创建一个新条目,然后加载计数(在映射程序中应为1 )。 处理完所有输入后,您只需遍历哈希并将键值对发送到stdout。

清单5. Ruby reduce脚本(reduce.rb)

#!/usr/bin/env ruby# Create an empty word hash
wordhash = {}# Our input comes from STDIN, operating on each line
STDIN.each_line do |line|# Each line will represent a word and countword, count = line.strip.split# If we have the word in the hash, add the count to it, otherwise# create a new one.if wordhash.has_key?(word)wordhash[word] += count.to_ielsewordhash[word] = count.to_iendend# Iterate through and emit the word counters
wordhash.each {|record, count| puts "#{record}\t#{count}"}

完成map和reduce脚本后,从命令行对其进行测试。 请记住使用chmod +x将这些文件更改为可执行文件。 首先生成一个输入文件,如清单6所示。

清单6.生成输入文件

# echo "Hadoop is an implementation of the map reduce framework for " \"distributed processing of large data sets." > input
#

使用此输入,您现在可以测试您的mapper脚本,如清单7所示。回想一下,该脚本只是将输入标记化为键值对,其中每个值将为1 (非唯一输入)。

清单7.测试映射器脚本

# cat input | ruby map.rb
Hadoop 1
is 1
an 1
implementation 1
of 1
the 1
map 1
reduce 1
framework 1
for 1
distributed 1
processing 1
of 1
large 1
data 1
sets. 1
#

到目前为止,一切都很好。 现在,以原始流形式(Linux®管道)将整个应用程序组合在一起。 在清单8中,您将输入传递给地图脚本,对输出进行排序(可选步骤),然后将所得的中间数据传递给reducer脚本。

清单8.使用Linux管道的简单MapReduce

# cat input | ruby map.rb | sort | ruby reduce.rb
large 1
of 2
framework 1
distributed 1
data 1
an 1
the 1
reduce 1
map 1
sets. 1
Hadoop 1
implementation 1
for 1
processing 1
is 1
#

Ruby与Hadoop

在外壳环境中按预期方式运行地图和归约脚本后,将其与Hadoop一起进行测试。 我将跳过Hadoop设置任务(请参阅本系列的第1 部分或第2部分 ,以启动并运行Hadoop)。

第一步是在HDFS中为您的输入数据创建一个输入目录,然后提供一个示例文件,您将在该文件上测试脚本。 清单9演示了此步骤(有关这些步骤的更多信息,请参见第1部分或第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
#

接下来,使用streaming实用程序,使用自定义脚本调用Hadoop,指定输入数据和输出位置(请参见清单10)。 请注意,在此示例中, -file选项只是告诉Hadoop将Ruby脚本打包为作业提交的一部分。

清单10.将Hadoop流与自定义Ruby MapReduce脚本一起使用

# 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)。

清单11.探索Hadoop输出

# 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行的脚本中,您已经实现了mapreduce元素,并演示了它们在Hadoop框架内的执行。 这是一个简单的示例,但它说明了Hadoop背后的强大功能,以及为什么它成为使用自定义或专有算法处理大型数据集的如此流行的框架。

Hadoop的其他应用程序

Hadoop可以用于许多应用程序中,而不仅仅是简单地计算大型数据集的字数。 所需要做的就是以Hadoop基础架构可以使用的矢量形式表示数据。 尽管规范示例使用向量表示作为键和值,但是如何定义值(例如,多个值的集合)没有任何限制。 这种灵活性可以为Hadoop提供更丰富的应用程序的新机会。

正好适合MapReduce字数模型的一个有趣的应用程序是制表Web服务器访问的频率(在开创性的Google论文中讨论)。 对于此应用程序,URL用作键(从Web服务器访问日志中提取)。 reduce过程的结果是基于Web服务器日志的给定Web站点每个URL的访问总数。

在机器学习应用程序中,Hadoop已被用作扩展遗传算法以处理大量GA个体的方法(潜在解决方案)。 map过程执行传统的遗传算法,从本地池中寻求最佳个体解决方案。 然后,reduce应用程序将成为地图阶段中各个解决方案的竞赛。 这允许各个节点确定其最佳解决方案,然后允许这些解决方案在分布式的优胜劣汰展示中在还原阶段竞争。

创建了另一个有趣的应用程序来识别垃圾邮件的僵尸网络。 此过程的第一步是对电子邮件进行分类,以减少它们(基于一组指纹)为来自给定组织。 根据此过滤后的数据,为以某种方式连接的电子邮件(例如,引用电子邮件正文中的相同链接)构建了一个图形。 然后,将这些相关的电子邮件减少到主机(静态或动态IP地址)以识别相关的僵尸网络。

在通过地图和简化图元查看世界的应用程序之外,Hadoop可用作在计算机集群之间分配工作的一种方式。 映射和简化不一定强制特定类型的应用程序。 取而代之的是,可以将Hadoop视为将数据和算法分配到主机以进行更快的并行处理的一种方式。

Hadoop应用程序生态系统

尽管Hadoop提供了一个灵活的框架,但其他应用程序也可以将其接口转换为其他应用程序。 一个有趣的示例称为Hive,它是一种具有自己的查询语言(称为Hive QL )的数据仓库基础结构。 Hive使Hadoop对具有结构化查询语言(SQL)背景的人更加熟悉,但是它也支持传统的MapReduce基础结构来进行数据处理。

HBase是驻留在HDFS之上的另一个有趣的应用程序。 这是一个类似于Google BigTable的高性能数据库系统。 HBase代替了传统的文件处理,使数据库表成为MapReduce处理的输入和输出形式。

最后, Pig是Hadoop上用于分析大型数据集的平台。 Pig提供了一种高级语言,可以进行编译以映射和减少应用程序。

更进一步

Hadoop 系列的最后一篇文章探讨了针对Hadoop框架的地图开发和减少Ruby中的应用程序。 希望从本文中,您可以看到Hadoop的真正功能。 尽管Hadoop限制您使用特定的编程模型,但是该模型非常灵活,可以应用于大量应用程序。


翻译自: https://www.ibm.com/developerworks/java/library/l-hadoop-3/index.html




推荐阅读
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 本文将带你快速了解 SpringMVC 框架的基本使用方法,通过实现一个简单的 Controller 并在浏览器中访问,展示 SpringMVC 的强大与简便。 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • 阿里巴巴终面技术挑战:如何利用 UDP 实现 TCP 功能?
    在阿里巴巴的技术面试中,技术总监曾提出一道关于如何利用 UDP 实现 TCP 功能的问题。当时回答得不够理想,因此事后进行了详细总结。通过与总监的进一步交流,了解到这是一道常见的阿里面试题。面试官的主要目的是考察应聘者对 UDP 和 TCP 在原理上的差异的理解,以及如何通过 UDP 实现类似 TCP 的可靠传输机制。 ... [详细]
  • 能够感知你情绪状态的智能机器人即将问世 | 科技前沿观察
    本周科技前沿报道了多项重要进展,包括美国多所高校在机器人技术和自动驾驶领域的最新研究成果,以及硅谷大型企业在智能硬件和深度学习技术上的突破性进展。特别值得一提的是,一款能够感知用户情绪状态的智能机器人即将问世,为未来的人机交互带来了全新的可能性。 ... [详细]
  • 在数据库设计中,谨慎使用外键至关重要。本文探讨了九个关键原因,包括数据完整性的维护、性能优化、系统复杂性的管理、数据迁移的灵活性以及对外部系统的依赖性控制。通过深入分析这些因素,可以帮助开发人员和架构师做出更明智的设计决策,确保数据库系统的高效与稳定。 ... [详细]
  • 利用Python与Android进行高效移动应用开发
    通过结合Python和Android,可以实现高效的移动应用开发。首先,需要安装Scripting Layer for Android (SL4A),这是一个开源项目,旨在为Android系统提供脚本语言支持。SL4A不仅简化了开发流程,还允许开发者使用Python等高级语言编写脚本,从而提高开发效率和代码可维护性。此外,SL4A还支持多种其他脚本语言,进一步扩展了其应用范围。通过这种方式,开发者可以快速构建功能丰富的移动应用,同时保持较高的灵活性和可扩展性。 ... [详细]
  • 从2019年AI顶级会议最佳论文,探索深度学习的理论根基与前沿进展 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
  • OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战
    OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战 ... [详细]
  • 本文推荐了六款高效的Java Web应用开发工具,并详细介绍了它们的实用功能。其中,分布式敏捷开发系统架构“zheng”项目,基于Spring、Spring MVC和MyBatis技术栈,提供了完整的分布式敏捷开发解决方案,支持快速构建高性能的企业级应用。此外,该工具还集成了多种中间件和服务,进一步提升了开发效率和系统的可维护性。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • Python作为当今IT领域中最受欢迎且高效的语言之一,其框架能够显著加速Web应用程序的开发过程。本文推荐并对比了十大顶级Python Web开发框架,其中CubicWeb以其卓越的代码重用性和模块化设计脱颖而出,为开发者提供了强大的支持。 ... [详细]
  • 从 Java 过渡到 Ruby,不仅是一次编程语言的转换,更是一段技术进阶的旅程。本文将深入探讨两种语言在语法、生态系统和开发模式上的差异,帮助开发者顺利实现转型,并在新的环境中高效地编写高质量代码。 ... [详细]
author-avatar
爵士KI
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有