hadoop之steaming介绍 hadoop有个工具叫做steaming,能够支持python、shell、C++、PHP等其他任何支持标准输入stdin及标准输出stdout的语言,其运行原理可以通过和标准java的map-reduce程序对比来说明: 使用原生java语言实现Map-reduce程序 hadoop准备好数据
hadoop之steaming介绍
hadoop有个工具叫做steaming,能够支持python、shell、C++、PHP等其他任何支持标准输入stdin及标准输出stdout的语言,其运行原理可以通过和标准java的map-reduce程序对比来说明:
使用原生java语言实现Map-reduce程序
- hadoop准备好数据后,将数据传送给java的map程序
- java的map程序将数据处理后,输出O1
- hadoop将O1打散、排序,然后传给不同的reduce机器
- 每个reduce机器将传来的数据传给reduce程序
- reduce程序将数据处理,输出最终数据O2
借助hadoop streaming使用python语言实现Map-reduce程序
- hadoop准备好数据后,将数据传送给java的map程序
- java的map程序将数据处理成“键/值”对,并传送给python的map程序
- python的map程序将数据处理后,将结果传回给java的map程序
- java的map程序将数据输出为O1
- hadoop将O1打散、排序,然后传给不同的reduce机器
- 每个reduce机器将传来的数据处理成“键/值”对,并传送给python的reduce程序
- python的reduce程序将数据处理后,将结果返回给java的reduce程序
- java的reduce程序将数据处理,输出最终数据O2
上面红色表示map的对比,蓝色表示reduce的对比,可以看出streaming程序多了一步中间处理,这样说来steaming程序的效率和性能应该低于java版的程序,然而python的开发效率、运行性能有时候会大于java,这就是streaming的优势所在。
hadoop之实现集合join的需求
hadoop是用来做数据分析的,大都是对集合进行操作,因此该过程中将集合join起来使得一个集合能得到另一个集合对应的信息的需求非常常见。
比如以下这个需求,有两份数据:学生信息(学号,姓名)和学生成绩(学号、课程、成绩),特点是有个共同的主键“学号”,现在需要将两者结合起来得到数据(学号,姓名,课程,成绩),计算公式:
(学号,姓名) join (学号,课程,成绩)= (学号,姓名,课程,成绩)
数据事例1-学生信息:
学号sno | 姓名name |
01 | name1 |
02 | name2 |
03 | name3 |
04 | name4 |
数据事例2:-学生成绩:
学号sno | 课程号courseno | 成绩grade |
01 | 01 | 80 |
01 | 02 | 90 |
02 | 01 | 82 |
02 | 02 | 95 |
期待的最终输出:
学号sno | 姓名name | 课程courseno | 成绩grade |
01 | name1 | 01 | 80 |
01 | name1 | 02 | 90 |
02 | name2 | 01 | 82 |
02 | name2 | 02 | 95 |
实现join的注意点和易踩坑总结
如果你想写一个完善健壮的map reduce程序,我建议你首先弄清楚输入数据的格式、输出数据的格式,然后自己手动构建输入数据并手动计算出输出数据,这个过程中你会发现一些写程序中需要特别处理的地方:
- 实现join的key是哪个,是1个字段还是2个字段,本例中key是sno,1个字段
- 每个集合中key是否可以重复,本例中数据1不可重复,数据2的key可以重复
- 每个集合中key的对应值是否可以不存在,本例中有学生会没成绩,所以数据2的key可以为空
第1条会影响到hadoop启动脚本中key.fields和partition的配置,第2条会影响到map-reduce程序中具体的代码实现方式,第3条同样影响代码编写方式。
hadoop实现join操作的思路
具体思路是给每个数据源加上一个数字标记label,这样hadoop对其排序后同一个字段的数据排在一起并且按照label排好序了,于是直接将相邻相同key的数据合并在一起输出就得到了结果。
1、 map阶段:给表1和表2加标记,其实就是多输出一个字段,比如表一加标记为0,表2加标记为2;
2、 partion阶段:根据学号key为第一主键,标记label为第二主键进行排序和分区
3、 reduce阶段:由于已经按照第一主键、第二主键排好了序,将相邻相同key数据合并输出
hadoop使用python实现join的map和reduce代码
mapper.py的代码:
# -*- coding: utf-8 -*- #Mapper.py #来自疯狂的蚂蚁www.crazyant.net import os import sys #mapper脚本 def mapper(): #获取当前正在处理的文件的名字,这里我们有两个输入文件 #所以要加以区分 filepath = os.environ["map_input_file"] filename = os.path.split(filepath)[-1] for line in sys.stdin: if line.strip()=="": continue fields = line[:-1].split("\t") sno = fields[0] #以下判断filename的目的是不同的文件有不同的字段,并且需加上不同的标记 if filename == 'data_info': name = fields[1] #下面的数字'0'就是为数据源1加上的统一标记 print '\t'.join((sno,'0',name)) elif filename == 'data_grade': courseno = fields[1] grade = fields[2] #下面的数字'1'就是为数据源1加上的统一标记 print '\t'.join((sno,'1',courseno,grade)) if __name__=='__main__': mapper()
reducer的代码:
# -*- coding: utf-8 -*- #reducer.py #来自疯狂的蚂蚁www.crazyant.net import sys def reducer(): #为了记录和上一个记录的区别,用lastsno记录上个sno lastsno = "" for line in sys.stdin: if line.strip()=="": continue fields = line[:-1].split("\t") sno = fields[0] ''' 处理思路: 遇见当前key与上一条key不同并且label=0,就记录下来name值, 当前key与上一条key相同并且label==1,则将本条数据的courseno、 grade联通上一条记录的name一起输出成最终结果 ''' if sno != lastsno: name="" #这里没有判断label==1的情况, #因为sno!=lastno,并且label=1表示该条key没有数据源1的数据 if fields[1]=="0": name=fields[2] elif sno==lastno: #这里没有判断label==0的情况, #因为sno==lastno并且label==0表示该条key没有数据源2的数据 if fields[2]=="1": courseno=fields[2] grade=fields[3] if name: print '\t'.join((lastsno,name,courseno,grade)) lastsno = sno if __name__=='__main__': reducer()
使用shell脚本启动hadoop程序的方法:
#先删除输出目录 ~/hadoop-client/hadoop/bin/hadoop fs -rmr /hdfs/jointest/output #来自疯狂的蚂蚁www.crazyant.net #注意,下面配置中的环境值每个人机器不一样 ~/hadoop-client/hadoop/bin/hadoop streaming \ -D mapred.map.tasks=10 \ -D mapred.reduce.tasks=5 \ -D mapred.job.map.capacity=10 \ -D mapred.job.reduce.capacity=5 \ -D mapred.job.name="join--sno_name-sno_courseno_grade" \ -D num.key.fields.for.partition=1 \ -D stream.num.map.output.key.fields=2 \ -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \ -input "/hdfs/jointest/input/*" \ -output "/hdfs/jointest/output" \ -mapper "python26/bin/python26.sh mapper.py" \ -reducer "python26/bin/python26.sh reducer.py" \ -file "mapper.py" \ -file "reducer.py" \ -cacheArchive "/share/python26.tar.gz#python26" #看看运行成功没,若输出0则表示成功了 echo $?
可以自己手工构造输入输出数据进行测试,本程序是验证过的。
更多需要注意的地方
hadoop的join操作可以分为很多类型,各种类型脚本的编写有所不同,其分类是按照key字段数目、value字段数目、key是否可重复来划分的,以下是一个个人总结的对照表,表示会影响的地方:
影响类型 | 影响的范围 |
key字段数目 | 1、启动脚本中num.key.fields.for.partition的配置2、启动脚本中stream.num.map.output.key.fields的配置 |
3、map和reduce脚本中key的获取
4、map和reduce脚本中每一条数据和上一条数据比较的方法key是否可重复如果数据源1可重复,标记为M;数据源2可重复标记为N,那么join可以分为:1*1、M*1、M*N类型
1*1类型:reduce中先记录第一个value,然后在下一条直接合并输出;
M*1类型:将类型1作为标记小的输出,然后每次遇见label=1就记录value,每遇见一次label=2就输出一次最终结果;
M*N类型:遇见类型1,就用数组记录value值,遇见label=2就将将记录的数组值全部连同该行value输出。value字段数目影响每次label=1时记录的数据个数,需要将value都记录下来
原文链接 转载须注明!
原文地址:Hadoop之使用python实现数据集合间join操作, 感谢原作者分享。

命名管道是一种在操作系统中相对比较低级的进程通信方式,它是一种以文件为中介的进程通信方式。在Go语言中,通过os包提供了对命名管道的支持。在本文中,我们将介绍如何在Go中使用命名管道来实现进程间通信。一、命名管道的概念命名管道是一种特殊的文件,可以被多个进程同时访问。在Linux系统中,命名管道是一种特殊的文件类型,它们存在于文件系统的某个位置上,并且可以在

Java错误:Hadoop错误,如何处理和避免当使用Hadoop处理大数据时,常常会遇到一些Java异常错误,这些错误可能会影响任务的执行,导致数据处理失败。本文将介绍一些常见的Hadoop错误,并提供处理和避免这些错误的方法。Java.lang.OutOfMemoryErrorOutOfMemoryError是Java虚拟机内存不足的错误。当Hadoop任

在Go语言中,使用第三方库是非常方便的。许多优秀的第三方库和框架可以帮助我们快速地开发应用程序,同时也减少了我们自己编写代码的工作量。但是如何正确地使用第三方库,确保其稳定性和可靠性,是我们必须了解的一个问题。本文将从以下几个方面介绍如何使用第三方库,并结合具体例子进行讲解。一、第三方库的获取Go语言中获取第三方库有以下两种方式:1.使用goget命令首先

<p>Windows 系统上的 OneDrive 应用程序允许您将文件存储在高达 5 GB 的云上。OneDrive 应用程序中还有另一个功能,它允许用户选择一个选项,是将文件保留在系统空间上还是在线提供,而不占用您的系统存储空间。此功能称为按需文件。在这篇文章中,我们进一步探索了此功能,并解释了有关如何在 Windows 11 电脑上的 OneDrive 中按需使用文件的各种选项。</p><h2>如何使用 On

近年来,WebSocket技术已经成为了Web开发中不可或缺的一部分。WebSocket是一种在单个TCP连接上进行全双工通信的协议,它使得客户端和服务器之间的通信更加流畅和高效。如今,很多现代的Web应用程序都使用了WebSocket技术,例如实时聊天、在线游戏以及实时数据可视化等。Go语言作为一个现代的编程语言,自然也提供了很好的支持WebSock

随着大数据时代的到来,数据处理和存储变得越来越重要,如何高效地管理和分析大量的数据也成为企业面临的挑战。Hadoop和HBase作为Apache基金会的两个项目,为大数据存储和分析提供了一种解决方案。本文将介绍如何在Beego中使用Hadoop和HBase进行大数据存储和查询。一、Hadoop和HBase简介Hadoop是一个开源的分布式存储和计算系统,它可

随着音频处理在各种应用场景中的普及,越来越多的程序员开始使用Go编写音频处理程序。Go语言作为一种现代化的编程语言,具有优秀的并发性和高效率的特点,使用它进行音频处理十分方便。本文将介绍如何在Go中使用音频处理技术,包括读取、写入、处理和分析音频数据等方面的内容。一、读取音频数据在Go中读取音频数据有多种方式。其中比较常用的是使用第三方库进行读取,比如go-

随着数据量的不断增大,传统的数据处理方式已经无法处理大数据时代带来的挑战。Hadoop是开源的分布式计算框架,它通过分布式存储和处理大量的数据,解决了单节点服务器在大数据处理中带来的性能瓶颈问题。PHP是一种脚本语言,广泛应用于Web开发,而且具有快速开发、易于维护等优点。本文将介绍如何使用PHP和Hadoop进行大数据处理。什么是HadoopHadoop是


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境