hadoop学习心得20-09-08

前言

hadoop学习心得
今天主要学了关于Hadoop中hdfs的一些操作

提示:以下皆为本人学习心得,不能保证正确,欢迎大神指点交流。

一、HDFS

1、HDFS简介

HDFS(Hadoop Distributed File System),是一个分布式文件系统,用于存储文件,通过目录树来定位文件。
HDFS适合一次写入、多次读取的场景,且不支持文件的修改。一般用于做数据分析,而不适合用作网盘应用。

2、HDFS的优缺点

优点:

  1. 高容错性:数据保存为多个副本,一个副本丢失后,可以自动恢复。
  2. 适合处理大量数据。
  3. 可以构建在廉价的机器上,通过多副本机制提高可靠性。

缺点

  1. 不适合低延时数据访问,不能用来做实时运算
  2. 无法高效处理大量小文件
  3. 不支持并发写入、不支持文件随机修改。

3、HDFS的组成架构

官方提供的HDFS组件关系图

  • NameNode

    是HDFS架构中的老大,是作为管理者(Master)存在的。
    	1、管理HDFS的名称空间;
    	2、配置副本策略;
    	3、管理数据块(Block)映射信息;
    	4、处理客户端读写请求。
    
  • DataNode

    是HDFS中的底层工作者(slaves)身份,负责执行实际的操作
    	1、存储实际的数据块
    	2、执行数据块的读/写操作
    
  • SecondaryNameNode

    并不是NameNode2号,而是NameNode的副手角色,当NameNode宕机时不能马上替换NameNode。
    	1、辅助NameNode,分担其工作量
    		合并Fsimage和Edits,并推送给NameNode
    	2、经济情况下辅助恢复NameNode
    	
    
  • Client

    客户端
    	1、文件切分由客户端完成
    	2、与NameNode交互,获取文件位置信息
    	3、与DataNode交互,完成读写
    	4、Client可以通过命令管理hdfs,如NameNode的格式化
    	5、通过命令访问HDFS
    

二、HDFS shell 操作

1.基本语法

bin/hadoop fs <命令>

bin/hdfs dfs <命令>

一些常用命令(实际使用的时候可以通过自带的–help指令查询):

  -help 查询指令
  -ls 显示目录
  -mkdir 创建目录
  -cat 显示文件内容
  -chgrp、-chown、-chmod 同linux系统对应指令
  -cp 复制
  -mv 移动
  -get 下载文件到本地
  -put 从本地发送文件到HDFS
  -rm 删除文件
  -rmdir 删除目录
  -setrep 设置HDFS中文件的副本数

2.HDFS客户端操作(java代码编写

1、客户端环境准备

需要准备好版本对应的JDK与对应pc环境编译后的Hadoop
并配置好环境变量。
我所使用的是JDK1.8与Hadoop2.7.2

2、maven导入依赖

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.8.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-common</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-client</artifactId>
			<version>2.7.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-hdfs</artifactId>
			<version>2.7.2</version>
		</dependency> 		
</dependencies>

如需要配置log4j在resources目录下新建文件为“log4j.properties”,写入:

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

3、java代码编写

通过jutil提供的注解实现初始化和资源关闭代码块的封装,减轻开发学习中不必要的多余操作

//通过jutil可以方便的实现快速的初始化配置信息和关闭资源,如下
public class HDFSClient {
    private Configuration conf = new Configuration();;
    private FileSystem fs;
    
    //通过Before注解可以让我们的测试代码运行前实现所需的初始化,更适合我们学习。
    @Before
    public void init() throws Exception {
    //在test前通过hadoop提供的FileSystem配置好相应的
    //HDFS地址,其中的hadoop201为我的集群的namenode所在host,9000是hadoop提供的代码访问端口
    //conf 配置文件,有多种配置方法
    //“kgg”为对应启动HDFS的linux的用户名,可以
        fs = FileSystem.get(new URI("hdfs://hadoop201:9000"),conf,"kgg");
    }
    
    //此处为任何你要尝试的java代码
    @Test
	public void method(){}

	//通过After注解实现资源的释放
    @After
    public void close() throws IOException{
        if (fs != null) {
            fs.close();
        }
    }
}

所实际起作用的代码编写,因为那些HDFS提供的API操作都只要调用其提供的方法即可,顾略过不表。
这里仅记录一个通过IO操作将HDFS的文件分块下载的代码


    /**
     * 分块读取的思路就是通过hadoop文件的固定分块大小来读取文件的操作
     * 将数据从输入流分批次读固定大小到缓冲中然后写入输出流。
     * 本次选用的文件是hadoop本身的压缩包,大小大于一块,HDFS会分两块存储,所以先读一块
     * 然后再关闭输出流再读一块到新文件中。之后拼接判断文件是否出错。
     * 如果要跳过前几块、直接seek跳跃文件指针即可。
     */
    @Test
    public void testCopyFromHDFS()throws Exception{
        //打开输入流,因为文件从HDFS下载,所以通过Hadoop的FileSystem获取输入流
        FSDataInputStream fis = fs.open(new Path("/h.tar.gz"));
        //输出流,要下载到本地,所以用java自带的输出流
        FileOutputStream fos = new FileOutputStream("e:/work/test/h.tar.gz.part1");
        //创建字节字符串做缓存,长度为1024,这样一次就可以读取1024b即1kb数据
        byte[] buf = new byte[1024];
        //循环读取数据,循环1024*128次,即一共读取128m数据,也即一个HDFS中的数据块
        for (int i=0;i<1024*128;i++){
            fis.read(buf);
            fos.write(buf);
        }
        //通过IOUtils关闭输出流并打开一个指向新文件的输出流
        IOUtils.closeStream(fos);
        fos = new FileOutputStream("e:/work/test/h.tar.gz.part2");
        //因为剩下的数据只有不到一个数据块的操作了,所以不用计量读取数据,直接copyBytes即可
        IOUtils.copyBytes(fis,fos,conf);
        //不要忘记关闭流
        IOUtils.closeStream(fis);
        IOUtils.closeStream(fos);
    }

总结

以上便是本篇文件的内容了,今天主要学习了HDFS的相关知识和一些客户端的shell操作指令。
同时学习了怎样用java代码实现对HDFS进行操作。
个人认为其中最要注意的一点还是要区分清楚HDFS的路径和本地路径的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值