《Hadoop实战手册》一1.2 使用Hadoop shell命令导入和导出数据到HDFS

简介:

本节书摘来异步社区《Hadoop实战手册》一书中的第1章,第1.2节,作者: 【美】Jonathan R. Owens , Jon Lentz , Brian Femiano 译者: 傅杰 , 赵磊 , 卢学裕 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.2 使用Hadoop shell命令导入和导出数据到HDFS

HDFS提供了许多shell命令来实现访问文件系统的功能,这些命令都是构建在HDFS FileSystem API之上的。Hadoop自带的shell脚本是通过命令行来执行所有操作的。这个脚本的名称叫做hadoop,通常安装在$HADOOP_BIN目录下,其中$HADOOP_BIN是Hadoopbin文件完整的安装目录,同时有必要将$HADOOP_BIN配置到$PATH环境变量中,这样所有的命令都可以通过hadoop fs -command这样的形式来执行。

如果需要获取文件系统的所有命令,可以运行hadoop命令传递不带参数的选项fs。

hadoop fs


8

这些按照功能进行命名的命令的名称与Unix shell命令非常相似。使用help选项可以获得某个具体命令的详细说明。

hadoop fs –help ls


7

这些shell命令和其简要的参数描述可在官方在线文档http://hadoop.apache.org/docs/r1.0.4/file_system_shell.html中进行查阅。

在这一节中,我们将使用Hadoop shell命令将数据导入HDFS中,以及将数据从HDFS中导出。这些命令更多地用于加载数据,下载处理过的数据,管理文件系统,以及预览相关数据。掌握这些命令是高效使用HDFS的前提。

准备工作
你需要在http://www.packtpub.com/support这个网站上下载数据集weblog_entries.txt。

操作步骤
完成以下步骤,实现将weblog_entries.txt文件从本地文件系统复制到HDFS上的一个指定文件夹下。

1.在HDFS中创建一个新文件夹,用于保存weblog_entries.txt文件:

hadoop fs -mkdir /data/weblogs

2.将weblog_entries.txt文件从本地文件系统复制到HDFS刚创建的新文件夹下:

hadoop fs -copyFromLocal weblog_entries.txt /data/weblogs

3.列出HDFS上weblog_entries.txt文件的信息:

hadoop fs –ls /data/weblogs/weblog_entries.txt

图像说明文字在Hadoop处理的一些结果数据可能会直接被外部系统使用,可能需要其他系统做更进一步的处理,或者MapReduce处理框架根本就不符合该场景,任何类似的情况下都需要从HDFS上导出数据。下载数据最简单的办法就是使用Hadoop shell。
4.将HDFS上的weblog_entries.txt文件复制到本地系统的当前文件夹下:

hadoop fs -copyToLocal /data/weblogs/weblog_entries.txt ./weblog_entries.txt

5

复制HDFS的文件到本地文件系统时,需要保证本地文件系统的空间可用以及网络连接的速度。HDFS中的文件大小在几个TB到几十个TB是很常见的。在1Gbit网络环境下,从HDFS中导出10 TB数据到本地文件系统,最好的情况下也要消耗23个小时,当然这还要保证本地文件系统的空间是可用的。

下载本书的示例代码

你可以从http://www.packtpub.com下载你买过的任何书的示例代码,如果你买过本书还可以访问http://www.packtpub.com/support,并进行注册来让文件直接发送到你的邮箱

工作原理
Hadoop shell非常轻量地封装在HDFS FileSystem API之上。在执行hadoop命令时,如果传进去的参数是fs,实际上执行的是org.apache.hadoop.fs.FsShell这个类。在0.20.2版本中FsShell实例化了一个org.apache.hadoop.fs.FileSystem对象,并且将命令行参数与类方法映射起来。比如,执行hadoop fs –mkdir /data/weblogs相当于调用FileSystem.mkdirs(new Path("/data/weblogs"))。同样,运行hadoop fs –copyFromLocal weblog_entries.txt /data/weblogs相当于在调用FileSystem.copyFromLocal(newPath("weblog_entries.txt"), new Path("/data/weblogs"))。HDFS数据复制到本地系统的实现方式也是一样,等同于调用FileSystem.copyToLocal(newPath("/data/weblogs/ weblog_entries.txt"), new Path("./weblog_entries.txt"))。更多关于文件系统的接口信息描述可以见官方文档http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/fs/FileSystem.html

mkdir可以通过hadoop fs -mkdir PATH1 PATH2的形式来执行。例如,hadoop fs –mkdir /data/weblogs/12012012 /data/ weblogs/12022012将会在HDFS系统上分别创建两个文件夹/data/weblogs/12012012和/data/weblogs/12022012。如果文件夹创建成功则返回0,否则返回-1。

hadoop fs –mkdir /data/weblogs/12012012 /data/weblogs/12022012
hadoop fs –ls /data/weblogs

4

copyFromLocal可以通过hadoop fs –copyFromLocal LOCALFILEPATH URI的形式来执行,如果URI的地址(指的是HDFS://filesystemName:9000这个串)没有明确给出,则默认会读取core-site.xml中的fs.default.name这个属性。上传成功返回0,否则返回-1。

copyToLocal命令可以通过hadoop fs –copyToLocal [-ignorecrc] [-crc] URILOCAL_FILE_PATH的形式来执行。如果URI的地址没有明确的给出,则默认会读取core-site.xml中的fs.default.name这个属性。copyToLocal会执行CRC(Cyclic Redundancy Check)校验保证已复制的数据的正确性,一个失败的副本复制可以通过 参数–ignorecrc来强制执行,还可以通过-crc参数在复制文件的同时也复制crc校验文件。

更多参考
put命令与copyFromLocal类似,put更通用一些,可以复制多个文件到HDFS中,也能接受标准输入流。

任何使用copyToLocal的地方都可以用get替换,两者的实现一模一样。

在使用MapReduce处理大数据时,其输出结果可能是一个或者多个文件。最终输出结果的文件个数是由mapred.reduce.tasks的值决定的。我们可以在Jobconf类中通过setNumReduceTasks()方法来设置这个属性,改变提交作业的reduce个数,每个reduce将对应输出一个文件。该参数是客户端参数,非集群参数,针对不同的作业应该设置不同的值。其默认值为1,意味着所有Map(映射函数,以下都用Map表示)的输出结果都将复制到1个reducer上进行处理。除非Map输出的结果数据小于1 GB,否则默认的配置将不合适。reduce个数的设置更像是一门艺术而不是科学。在官方的文档中对其设置推荐的两个公式如下:

0.95×NUMBER_OF_NODES×mapred.tasktracker.reduce.tasks.maximum

或者

1.75×NUMBER_OF_NODES×mapred.tasktracker.reduce.tasks.maximum

假设你的集群有10个节点来运行Task Tracker,每个节点最多可以启动5个reduce槽位(通过设置tasktracker.reduce.tasks.maximum这个值来决定每个节点所能启动的最大reduce槽位数)对应的这个公式应该是0.95×10×4=47.5。因为reduce个数的设置必须是整数,所以需要进行四舍五入。

JobConf文档中给出了使用这两个公式的理由,具体见http://hadoop.apache.org/docs/
current/api/org/apache/hadoop/mapred/JobConf.html#setNumReduceTasks(int))。

0.95可以保证在map结束后可以立即启动所有的reduce进行map结果的复制,只需要一波就可以完成作业。1.75使得运行比较快的reducer能够再执行第二波reduce,保证两波reduce就能完成作业,使作业整体的负载均衡保持得比较好。

reduce输出的数据存储在HDFS中,可以通过文件夹的名称来引用。若文件夹作为一个作业的输入,那么该文件夹下的所有文件都会被处理。上文介绍的get和copyToLocal只能对文件进行复制,无法对整个文件夹进行复制2。当然Hadoop提供了getmerge命令,可以将文件系统中的多个文件合并成一个单独的文件下载到本地文件系统。

通过以下Pig脚本来演示下getmerge命令的功能:

weblogs = load '/data/weblogs/weblog_entries.txt' as
                (md5:chararray,
                  url:chararray,
                  date:chararray,
                  time:chararray,
                  ip:chararray);

md5_grp = group weblogs by md5 parallel 4;

store md5_grp into '/data/weblogs/weblogs_md5_groups.bcp';

Pig脚本可以通过下面的命令行来执行:

pig –f weblogs_md5_group.pig

3

该脚本逐行读取HDFS上的weblog_entries.txt文件,并且按照md5的值进行分组。parallel是Pig脚本用来设置reduce个数的方法。由于启动了4个reduce任务,所以会在输出的目录/data/weblogs/weblogs_md5_groups.bcp中生成4个文件。

注意,weblogs_md5_groups.bcp实际上是一个文件夹,显示该文件夹的列表信息可以看到:
2

在/data/weblogs/weblogs_md5_groups.bcp中包含4个文件,即part-r-00000、part-r-00001、part-r-00002和part-r-00003。

getmerge命令可以用来将4个文件合并成一个文件,并且复制到本地的文件系统中,具体命令如下:

hadoop fs -getmerge /data/weblogs/weblogs_md5_groups.bcp weblogs_md5_groups.bcp

操作完我们可以看到本地文件列表如下:


1

延伸阅读

  • u关于HDFS数据的读写,我们将在第2章中重点介绍如何直接利用文件系统的API进行读写。
  • 通过以下的两个链接可以对比出文件系统shell命令与Java API的不同:
http://hadoop.apache.org/docs/r1.0.4/file_system_shell.html http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/fs/FileSystem.html
相关文章
|
6月前
|
存储 Unix Shell
Shell 输出命令完全指南:echo 与 printf 的深度剖析
本文深入解析了 Shell 编程中 `echo` 和 `printf` 两个核心输出命令的用法与区别。`echo` 简单易用,适合基础输出;`printf` 功能强大,支持复杂格式化。文章从语法、转义序列、高级技巧到实际应用场景(如日志记录、进度显示)逐一讲解,并对比两者的性能与适用场景,帮助开发者根据需求灵活选择。最后通过进阶技巧和常见问题解答,进一步提升对两者的掌握程度。
325 1
|
7月前
|
网络协议 Shell 网络安全
面试官想听的不仅是命令——如何结构化回答“容器无Shell时如何测试外网”?
“说说看,如果一个Pod的容器没有Shell,如何测试它能否访问外网?”
面试官想听的不仅是命令——如何结构化回答“容器无Shell时如何测试外网”?
|
8月前
|
分布式计算 Hadoop 大数据
从Excel到Hadoop:数据规模的进化之路
从Excel到Hadoop:数据规模的进化之路
161 10
|
9月前
|
运维 Shell 数据库
Python执行Shell命令并获取结果:深入解析与实战
通过以上内容,开发者可以在实际项目中灵活应用Python执行Shell命令,实现各种自动化任务,提高开发和运维效率。
265 20
|
9月前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
304 7
|
9月前
|
安全 Shell 数据处理
使用Python执行Shell命令并获取结果
在实际应用中,可以根据需要选择适当的参数和方法来执行Shell命令,并处理可能出现的各种情况。无论是系统管理、自动化任务还是数据处理,掌握这些技巧都将极大地提高工作效率。
326 12
|
10月前
|
数据采集 分布式计算 Hadoop
使用Hadoop MapReduce进行大规模数据爬取
使用Hadoop MapReduce进行大规模数据爬取
|
11月前
|
人工智能 Shell iOS开发
AI Shell:在命令行里“对话” AI ,微软推出将 AI 助手引入命令行的 CLI 工具,打造对话式交互命令行
AI Shell 是一款强大的 CLI 工具,将人工智能直接集成到命令行中,帮助用户提高生产力。AI Shell 支持多种 AI 模型和助手,通过多代理框架提供丰富的功能和灵活的使用模式。
1338 7
|
11月前
|
Java Shell Windows
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
219 1
|
7月前
|
XML 存储 分布式计算
【赵渝强老师】史上最详细:Hadoop HDFS的体系架构
HDFS(Hadoop分布式文件系统)由三个核心组件构成:NameNode、DataNode和SecondaryNameNode。NameNode负责管理文件系统的命名空间和客户端请求,维护元数据文件fsimage和edits;DataNode存储实际的数据块,默认大小为128MB;SecondaryNameNode定期合并edits日志到fsimage中,但不作为NameNode的热备份。通过这些组件的协同工作,HDFS实现了高效、可靠的大规模数据存储与管理。
746 70

相关实验场景

更多