如何将Node.js Streaming MapReduce引入Amazon EMR

概述

\\

Node.js是一套JavaScript框架,其核心诉求在于利用非阻塞I/O以及异步式事件驱动处理模型实现服务器端应用程序的高性能运行。

\\

当客户需要处理规模庞大且复杂性较高的数据时,Node.js能够提供一套以原生方式支持JSON数据结构的运行时环境。Python及Ruby等编程语言都拥有面向JSON数据的优秀支持能力,但Node.js在处理包含列表及数组的结构时显得尤为得心应手。Node.js还提供一套高性能且具备可扩展能力的备用方案,能够以原生方式将JSON数据作为对象加以处理。目前大家已经可以获得专门针对Node.js的AWS SDK(http://aws.amazon.com/sdkfornodejs),其允许我们将Node.js应用程序与AWS服务加以紧密整合。

\\

在今天的文章中,大家将了解到如何在Amazon Elastic MapReduce(简称Amazon EMR)当中安装Node.js、如何构建一款Node.js应用程序并将其与Hadoop Streaming并发处理架构相整合、外加如何在AWS之上部署并运行我们的Node.js MapReduce应用程序。要了解更多与Amazon EMR以及Hive项目相关之细节信息,请大家点击此处查看专题教程。

\\

本文假定大家已经熟知与Hadoop、Hive以及Amazon EMR相关的专业知识。

\\

用例

\\

在本文当中,我们将使用来自Twitter的数据,这部分数据中包含由推文、转发、回复以及直发信息所构成的复杂信息体系。每个文件中都包含有单一Twitter事务数据块,我们需要将其内容写入至Amazon Simple Storage Service(简称Amazon S3)并随时加以读取。我们希望针对Hive的实际需求对数据进行转换,旨在对转发率、每秒推文数量以及每用户直发信息数量等指标进行汇总。

\\

样本输入数据

\\

我们的数据表现出一套由大量Twitter用户所构成的复杂交互图谱,其中包括推文转发与回复内容,如下图所示:

\\

f730abffb8da3d9491c4350e2bcfffa4.png

\\

为了进行数据发现,我们可以利用Hive配合JsonSerde(可参看http://aws.amazon.com/articles/2854)对数据进行调查。不过由于这套图谱非常复杂而且存在自我指涉,因此大部分Hive JsonSerde无法将这部分数据显示为表格。能够在Node.js中进行数据处理,我们能够更轻松地利用简单语法实现数据图谱导航。

\\

安装Node.js

\\

我们可以利用以下bootstrap操作将Node.js安装在Amazon EMR集群当中:

\\
\---bootstrap-actions Path=s3://github-emr-bootstrap-actions/node/install-nodejs.sh,Name=InstallNode.js
\\

(如果大家此前从未接触过bootstrap操作,请点击此处查阅Amazon EMR提供的说明文档。)

\\

编写MapReduce代码

\\

现在Node.js已经被安装在Amazon EMR集群之上,而Hadoop Streaming也得到正确配置,接下来我们需要运行自己的Node.js应用程序以完成映射与归约操作。利用Hadoop Streaming处理架构,我们能够为流任务指定所需要使用的映射与归约代码。

\\

与其它Hadoop Streaming兼容语言一样,我们必须从Amazon S3数据存储或者HDFS文件系统当中利用标准输入(即stdin)方式实现数据读取。在Node.js当中,stdin能够利用处理全局对象的方式获得可访问能力(参见http://nodejs.org/api/process.html)。这就使我们得以访问多种控制机制,进而通过管理输入与输出数据流对数据进行读取与写入,例如process.stdin与process.stdout。

\\

我们的MapReduce程度必须执行五项主要函数以实现从Hadoop Streaming以及输出结果中读取数据。

\\

配置标准输入

\\

在默认情况下,process.stdin输入通道会处于暂停状态,且不触发任何事件。在将其启用之前,我们必须首先配置所需的字符集编码。对于非多字节字符集而言,我们可以使用UTF-8。因此,我们映射或者归约方案的主体流程应该从这里开始:

\\
\process.stdin.setEncoding('utf8'); 
\\

或者,我们也可以使用UTF-16实现多字节支持。在此之后,我们必须启用stdin对事件进行恢复以及触发:

\\
\process.stdin.resume(); 
\\

处理来自STDIN的输入内容

\\

当我们的Node.js应用程序使用该stdin.data事件时,process.stdin通道会就此发出通知——stdin.data事件会在一定数量的数据可用于读取时被触发。我们的Node.js应用程序必须对这部分数据进行缓存处理以备后续使用,因为事件所提供的每一个数据块可能都仅仅属于标准输入内容中全部可用数据的一小部分。由于我们此前通过配置让Hadoop Streaming使用非分割式FileInputFormat,因此我们会在单一映射器中获取到完整的JSON数据,并能够将该文件作为整体加以处理。有鉴于此,我们可以通过以下代码将数据块缓存于data事件当中:

\\
\var line = ‘’;\// fires on every block of data read from stdin\process.stdin.on('data', function(chunk) {\    // chunk and emit on newline\    lines = chunk.split(\"\\")\     \    if (lines.length \u0026gt; 0) {\        // append the first chunk to the existing buffer\        line += lines[0]\         \        if (lines.length \u0026gt; 1) {\            // emit the current buffer\            emitter.emit(lineEvent,line);\ \            // go through the rest of the lines and emit them, buffering the last\            for (i=1;i\u0026lt;lines.length; i++) {\                if (i\u0026lt;lines.length) {\                    emitter.emit(lineEvent,lines[i]);\                } else {\                    line = lines[i];\                }\            }\        }\    }\});
\\

上述操作会将全部数据块附加至行变量处,并在每一次发现新的换行符时触发“lineReady”事件。

\\

处理完整的stdin数据

\\

在全部来自stdin的数据被读取完成后,该流程将触发stdin.end事件。我们已经将全部数据收集到行缓冲区当中,这样我们只需要利用以下代码刷新最后一行数据:

\\
\// fires when stdin is completed being read\process.stdin.on('end', function() {\    emitter.emit(lineEvent,line);\});
\\

每当新的内容行准备就绪时,我们都将利用以下代码将其排序至一个JSON对象当中:

\\
\try {\    obj = JSON.parse(line);\} catch (err) {\    process.stderr.write('Error Processing Line ' + line + '\');\    process.stderr.write(err);\    return;\}
\\

我们可以选择把复杂的JSON数据简化为普通输出结果,以供Hive JsonSerde进行加载,或者选择生成CSV或者XML数据来代替。

\\

以Hadoop兼容格式写入数据

\\

对于某些特定的MapReduce操作类型,我们需要确保其归约器能够获取到归属于特定类型的全部数据。为了实现这一目标,我们必须指定一个键值,并保证Hadoop在调用该归约器之前会首先对输出结果进行分类。在进行文本内容处理时,我们会利用由\\t标签开头的字符串来表示这个值。

\\

要执行存储或者移除方面的数据写入操作,我们需要利用process.stdout.write()向stdout实施写入。

\\

制作可执行文件

\\

Amazon EMR利用命令行语法调用的方式运行映射器与归约器,例如“./mapper.js”。因此,我们需要确保我们所构建的Node.js模块能够通过命令行实现调用。为达成这一目标,我们在映射器或者归约器文件的开头处添加一条标准“shebang”命令,这样它就能调用Node.js并运行脚本内容:

\\
\#!/usr/bin/env node 
\\

接下来,大家可以通过命令行调用的方式测试自己的映射器代码了(以下示例假定代码位于名为Mapper.js的文件当中):

\\
\./mapper.js \u0026lt; input-file-path 
\\

部署与运行

\\

在编写了自己的映射器与归约器之后,接下来我们将其传输至Amazon S3当中,而后利用Amazon EMR针对部分输入数据运行MapReduce。

\\

以下示例讲解了如何利用Amazon EMR命令行执行各个步骤(参见http://aws.amazon.com/developertools/2264),不过大家也可以在Amazon EMR控制台(参见console.aws.amazon.com/elasticmapreduce)或者Amazon EMR API(参见http://docs.aws.amazon.com/ElasticMapReduce/latest/API/Welcome.html?r=8857)中利用命令实现同样的效果。我们将展示如何以自动方式利用AWS命令行工具运行该应用程序,但大家完全可以使用AWS Web Console或者AWS Data Pipeline完成同样的工作。我们可以使用--create-cluster命令启动一套新的Amazon EMR集群,同时利用以下代码启动该集群并捃行我们的Node.js bootstrap操作:

\\
\aws emr create-cluster --ami-version 3.3.1 --enable-debugging --visible-to-all-users\ --name MyNodeJsMapReduceCluster --instance-groups  InstanceCount=2,InstanceGroupType=CORE,InstanceType=m3.xlarge \InstanceCount=1,InstanceGroupType=MASTER,InstanceType=m3.xlarge --\no-auto-terminate --enable-debugging --log-uri s3:///logs --\bootstrap-actions Path=s3://github-emr-bootstrap-\actions/node/install-nodejs.sh,Name=InstallNode.js --ec2-attributes \KeyName=\u0026lt;my key pair\u0026gt; 
\\

这样我们就创建了一套始终启用的集群,其中包含配备3.3.1 AMI、双核心节点以及一个主节点,全部采用m3.xlarge实例类型。以上代码同时为指定存储桶设定了调试与日志记录机制,并通过bootstrap操作完成了Node.js的启动时安装。除此之外,代码中还使用了Amazon EC2密钥对,从而将SSH安全机制引入该Hadoop集群。

\\

接下来,我们将添加Hadoop Streaming流程,旨在处理自己的输入数据。在以下代码中,大家需要把\u0026lt;my cluster ID\u0026gt;替换为自己的实际集群ID:

\\
\aws emr add-steps --cluster-id \u0026lt;my cluster ID\u0026gt; \--steps Name=NodeJSStreamProcess,Type=Streaming
\\

我们通过创建一套文件系统参考(利用—files参数)添加自己的映射器与归约器JavaScript文件,而后将该基础文件名通过-mapper与-reducer进行引用:

\\
\Args=--files,\"s3://\u0026lt;path to mapper\u0026gt;/mapper.js\\,s3://\u0026lt;path to \reducer\u0026gt;/reducer.js\
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值