3、hadoop

一、hadoop简介

1、概述

Hadoop是Apache提供的一个开源的、可靠的、可扩展的系统架构,可以利用分布式架构来进行海量数据的存储以及计算。需要注意的是Hadoop处理的是离线数据,即在数据已知以及不要求实时性的场景下使用。

2、版本

在这里插入图片描述

3、模块

(1)Common:在Hadoop1.0中,包含HDFS、MapReduce和其他项目公共内容,从Hadoop2.0开始,HDFS和MapReduce被分离为独立的子项目,其余内容为Hadoop Common
(2)HDFS:用于分布式环境下数据的存储
(3)Yarn:Hadoop2.0版本中出现,用于进行资源管理和任务调度的框架.
(4)MapReduce:从Hadoop2.0开始,基于Yarn,用于在海量数据的场景下进行并行计算
(5)Ozone:基于HDFS进行对象的存储
(6)Submarine:基于Hadoop进行机器学习的引擎

4、相关组件

(1)HBase: 类似Google BigTable的分布式NoSQL列数据库。(HBase和Avro已经于2010年5月成为顶级 Apache 项目)
(2)Hive:数据仓库工具,由Facebook贡献
(3)Zookeeper:分布式锁设施,提供类似Google Chubby的功能,由Facebook贡献
(4)Avro:新的数据序列化格式与传输工具,将逐步取代Hadoop原有的IPC机制。
(5)Pig: 大数据分析平台,为用户提供多种接口
(6)Ambari:Hadoop管理工具,可以快捷的监控、部署、管理集群
(7)Sqoop:于在Hadoop与传统的数据库间进行数据的传

二、hadoop安装

1、上传文件

在这里插入图片描述

2、解压文件夹

在这里插入图片描述ll

3、关闭防火墙

4、配置主机名

5、配置主机名和ip的映射

6、配置免密登录

见前一篇文章

7、安装并配置jdk(hadoop是java写的,其运行也需要java的支持)

8、配置hadoop

(1)配置hadoop-env.sh

a. 编辑hadoop-env.sh:vim hadoop-env.sha.
b. 修改JAVA_HOME的路径,修改成具体的路径。例如:export JAVA_HOME=/home/software/jdk1.8b.
c. 修改HADOOP_CONF_DIR的路径,修改为具体的路径,例如:export HADOOP_CONF_DIR=/home/software/hadoop-2.7.1/etc/hadoopc.
d. 保存退出文件
e. 重新加载生效:source hadoop-env.s

(2)配置 core-site.xml

a. 编辑core-site.xml:vim core-site.xmla.
b. 添加如下内容
<property>
    <!-- 指定HDFS中的主节点 - namenode -->
    <name>fs.defaultFS</name>
    <value>hdfs://hadoop01:9000</value> 
</property> 
<property>
    <!-- 执行Hadoop运行时的数据存放目录 -->    
    <name>hadoop.tmp.dir</name>    
    <value>/home/software/hadoop-2.7.1/tmp</value> 
</property>

(3)配置 hdfs-site.xm

a. 编辑hdfs-site.xml:vim hdfs-site.xmla.
b. 添加如下配置: 
<property>
    <!-- 设置HDFS中的复本数量 -->    
    <!-- 在伪分布式下,值设置为1 -->    
    <name>dfs.replication</name>    
    <value>1</value>
</property>
c. 保存退出

(4)配置 mapred-site.xml

a. 将mapred-site.xml.template复制为mapred-site.xml:cp mapred-site.xml.template mapred-site.xmla.
b. 编辑mapred-site.xml:vim mapred-site.xmlb.
c. 添加如下配置:
<property>
    <!-- 指定将MapReduceYarn上运行  -->    
    <name>mapreduce.framework.name</name>    
    <value>yarn</value> 
</property>
d. 保存退出

(5)配置 yarn-site.xml

a. 编辑yarn-site.xml:vim yarn-site.xmla.
b. 添加如下内容:
<!-- 指定Yarn的主节点 - resourcemanager --> 
<property>
    <name>yarn.resourcemanager.hostname</name>    
    <value>hadoop01</value> 
</property> 
<!-- NodeManager的数据获取方式 --> 
<property>
    <name>yarn.nodemanager.aux-services</name>    
    <value>mapreduce_shuffle</value> 
</property>
c. 保存退出

(6)配置slaves

a. 编辑slaves:vim slavesa.
b. 添加从节点信息,例如:hadoop01b.
c. 保存退出

(7)配置hadoop的环境变

a. 编辑profile文件:vim /etc/profilea.
b. 添加Hadoop的环境变量,例如:
	export HADOOP_HOME=/home/software/hadoop-2.7.1
	export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
	或
	export JAVA_HOME=/home/software/jdk1.8.0_131
	export HADOOP_HOME=/home/software/hadoop-2.7.1
	export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
c. 保存退出
d. 重新生效:source /etc/profiled

(8)格式化namenode:hadoop namenode -format
(9)启动hadoop:start-all.sh

9、出错处理方式:

1、停掉集群
stop-all.sh
2、删除hadoop安装包下的tmp目录
3、检查配置文件
4、重新格式化
5、重新启动

10、常见错误及处理方法

(1)问题:The authenticity of host ‘0.0.0.0 (0.0.0.0)’ can’t be established.RSA key fingerprint is 62:46:08:c6:0d:fd:93:25:d0:78:d8:d5:08:ff:cb:da.
解决方法:修改/etc/ssh/ssh_config文件(或$HOME/.ssh/config)中的配置,将#StrictHostKeyChecking ask中的ask改为no并去掉# 改好配置后,重新启动sshd服务即可(service sshd restart)。
(2)问题:localhost: Host key verification failed.
解决方法:去掉slaves文件中的localhost
(3)Java版本问题:安装1.8后,使用java-version查看版本时仍为1.7
解决方法:更改Java默认版本:

update-alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_131/bin/java 300
update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.8.0_131/bin/javac 300       
update-alternatives --config java

三、HDFS细节

在这里插入图片描述

1、Block

(1)数据块是hdfs数据存储的最基本的单位
(2)当hdfs存储超大文件时,hdfs会以一个标准将大文件切分为多块进行分布式存储
(3)block在hadoop1.0的时候是64M,但是在hadoop2以上的版本都是128M
(4)切块的优点:
a. 能够存储超大文件
b. 有利于数据的复制
(5)在hdfs中,如果一个文件小于数据块的大小。并不会占用整个数据块的空间,实际是多少就占用多少
在这里插入图片描述

[root@hadoop01 home]# hadoop fs -put bok /book
21/08/19 10:06:31 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[root@hadoop01 home]# cd software/
[root@hadoop01 software]# hadoop fs -put hadoop-2.7.1_64bit.tar.gz /hadoop
21/08/19 10:09:20 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

在这里插入图片描述

2、NameNode

(1)NameNode是用来存储元数据的,并且用来管理datanode
(2)namenode维护的hdfs的元数据信息

    a. 文件的存储路径
	b. 文件的大小
	c. block块的大小
	d. 文件和blockid的映射关系
	e. 文件的权限
	f. 上传的用户
	g. Block的数量关系
	h. 复本的数量
	i. block和datanode对应的关系

(3)每一条元数据的大小是150B左右
(4)namenode不适合存储大量的小文件
(5)元数据信息存储在内存及磁盘中。存到内存中是为了快速查询,存在磁盘是为了元数据的可靠
(6)元数据持久化到namenode节点的硬盘上,目录由core-site.xml->dfs.tmp.dir属性决定
(7)元数据保存到了/home/software/hadoop-2.7.1/tmp/dfs/name/current

[root@hadoop01 current]# cd /home/software/hadoop-2.7.1/tmp/dfs/name/current

(8)和元数据相关的文件:

	a. Fsimage:元数据的镜像文件,存储namenode元数据信息,并不是实时同步内存中元数据信息的,而是落后于内存中的元数据信息
	b. edits:记录操作日志。记录namenode所要执行的操作

在这里插入图片描述

达到条件之后,fsimage才会去同步内存中的元数据:i 时间达到1小时、 ii edits文件达到64M、 iii 手动通过命令同步 vi 重启集群的时候会同步

(9)当写请求的时候,namenode会首先将操作记录到edits文件汇总,写成功后,会去修改内存,更新元数据,内存修改完成后,会像客户端返回一个ack信号。代表更新成功,此时,fsimage文件中的数据没有发生更改。所以说,fsimage中的数据不是实时的数据。需要达到条件再进行更新
(10)namenode是通过心跳机制来管理datanode的
(11)datanode会每隔3s向namenode汇报自身情况
a. 自己节点的状态(正常、退役、服役)
b. 自己存储的数据块
c. 自身剩余的空间容量
(12)如果超过10min没有向namenode发送心跳,那么namenode会认为此datanode lost了,然后namenode就会将此节点的数据转移到其他的服务器(找相对空闲的节点进行转移)

3、SecondaryNameNode

(1)SecondaryNameNode不是namenode的热备份,而是协助namenode完成元数据的合并
(2)SecondaryNameNode是hadoop1.0的机制,在hadoop2.0的伪分布式可以看见,但是如果是hadoop2.0的完全分布式就不会看见
在这里插入图片描述
(3)当达到条件之后,SNN会将NN中的fsimage和edits文件通过网络的方式拷贝到SNN
(4)同时namenode中会创建一个edits_inprogress来保存新的请求。
(5)在SNN,会将拷贝过来的fsimage中的元数据加载进内存,将edits文件中记录的最新的操作请求,在内存中进行更新,将更新后的元数据写入到新的文件fsimage.ckpt中
(6)写好的新的文件fsimage.ckpt再拷贝会namenode
(7)循环以上处理方式

4、DataNode

(1)在hdfs中,数据是存放在datanode上面的,是以block块形式存放的
(2) 存放block块的位置:/home/software/hadoop-2.7.1/tmp/dfs/data/current/BP-976893665-192.168.232.129-1629336175258/current/finalized/subdir0/subdir0/
在这里插入图片描述
(3)在hdfs启动的时候, 每一个datanode会将当前存储的数据块的信息告诉namende节点
(4)之后, datanode节点会不断的向namenode发送心跳报告,默认是3s- 发送
(5)发送的心跳信息包括 节点的状态以及数据块的信息
(6)如果namenode 10min没有收到datanode的心跳,就会认为已经丢失,那么namenode会将这个datanode上的block复制到其他的datanode上
(7)如果是伪分布式,复本的数量只能设置为1,因为如果数量大于1,会导致hdfs一直处于安全模式不能退出
(8)安全模式:如果datanode在进行汇报的时候,namenode统计出来某一个文件本来有三个数据块,但是根据datanode汇报的信息,只有两个块存在,有块丢失了, 这个时候namenode就会进行复本的复制以达到三个块,在复制的过程中,会进入安全模式,在安全模式中,hadoo集群只能对外提供读服务,不能提供写服务。

4、复本的放置策略

(1)在hdfs中,支持多复本策略,如果不指定,默认是3.这个数量可以通过属性来进行指定。dfs.replication
(2)第一个复本:
a. 集群内部上传,谁上传就放在谁身上
b. 集群外部上传,谁空闲就放在谁身上
(3)第二个复本:
a,在hadoop2.7之前:第二个复本放在和第一个复本不同的机架的节点上
b.在hadoop2.7之后:第二个复本放在和第一个复本相同的机架的不同节点上
(4)第三个复本:
a.在hadoop2.7之前:第三个复本放在和第二个复本相同的机架的不同节点上
b.在hadoop2.7之后:第三个复本放在和第二个复本不同的机架的节点上

5、基本命令

命令说明
hadoop fs -put bok /book上传文件到hdfs
hadoop fs -mkdir /student在hdfs上创建目录
hadoop fs -get /aaa /opt将hdfs上aaa文件下载到本地opt目录下
hadoop fs -cat /book查看hdfs上文件的内容
hadoop fs -rmdir /student删除hdfs上的空目录
hadoop fs -rnr /student删除hdfs上不为空的目录
hadoop fs -rm /aaa删除hdfs上的普通文件
hadoop fs -ls /列出/路径下的文件
hadoop fs -lsr /递归列出/路径下的所有的文件
hadoop fs -mv /bok/hehe更改hdfs上文件的名字
hadoop fs -cp /hehe/demo拷贝hdfs上的文件
hadoop fs -touchz /nihao在hdfs上创建一个空白的文件

6、读取流程

在这里插入图片描述
(1)客户端需要向namenode发送RPC请求
(2)namenode会根据情况(文件过大,切块过多,一次返回数据量太大)返回全部或部分的block的列表,并且返回对应block以及该block对应的复本存储在datanode上的位置
(3)client会选举离客户端最近的datanode去读取block。如果客户端本身就是datanode,那么会直接从本地读取
(4)读取完一个block会进行checksum的校验,即验证读取到的block大小和声明的block大小是否一致。如果读取datanode数据出现错误,客户端会通知namenode,然后再从下一个离得近的datanode上读取相应的复本
(5)读取完当前的block数据后,关闭当前datanode的链接,并为读取下一个block寻找最佳的datanode
(6)当读取完列表中的block后,会通知namenode返回下一批block的列表,接着读取
(7)当文件最后一个block读取完成后,客户端会链接namenode告诉其关闭文件。

7、写入流程

在这里插入图片描述
(1)客户端向namenode发送rpc请求
(2)namenode会检查要创建的文件是否已经存在,并检查客户端是否有权限(原生的hadoop对于权限这块没有涉及)
(3)namenode就会返回客户端要写入数据的datanode的地址
(4)客户端就开始向第一个离得较近的datanode开始写入数据,写的时候是以packets(对数据进行封包)进行写入。并且底层会以队列的形式管理packets。底层是以管道pipeline的形式将数据包发送给所有的datanode
(5)最后一个datanode写入数据成功后,会返回一个ack给第二个datanode,同样,第二个datamode写入成功后,会返回第一个datanode一个ack信号,同样第一个写完后,会返回给客户端一个ack信号。三个datanode都写完之后,从队列中删除已发送的packets
(6)如果传输过程中,有个datanode出现了故障,那么当前的pipeline会关闭,出现故障的datanode会从当前pipeline中移除,剩余的block会继续在剩余的datenode中继续以pipeline的形式传输,同时namenode会分配一个新的datanode,保持复本的数量

8、删除流程

(1)客户端向namenode发起RPC请求
(2)现在namenode上将此文件的元数据删除,但是此时数据并没有真正的删除
(3)datanode会定时向namenode汇报自身的情况,在汇报的时候,namenode会告诉datanode说此文件的元数据已经被删除了
(4)通知datanode删除自身的block块数据

四、在eclipse中集成hadoop插件

在这里插入图片描述

1、将上面的jar包放入下面两个包(eclipse的安装目录下)中

在这里插入图片描述

2、将hadoo-2.7.1_64bit.tar解压到D盘

在这里插入图片描述

3、将hadoopbin_for_hadoop2.7.1中的内容放到解压到的hadoop-2.7.1/bin下面

在这里插入图片描述

4、新建如下两个系统变量

在这里插入图片描述
在这里插入图片描述
编辑环境变量path
在这里插入图片描述

5、打开eclipse,点击windows->perferences->Hadoop Map/Reduce->选择安装目录

在这里插入图片描述

6、点击windows->show view -> other->MapReduce Tools ->Map/Reduce Locations

在这里插入图片描述
点击如下图标
在这里插入图片描述
配置如下内容
在这里插入图片描述

7、点击windows->show view->Project Explorer出现如下内容

在这里插入图片描述

五、回收站机制

1、开启回收站机制

(1)首先停掉集群

[root@hadoop01 opt]# stop-all.sh

(2)编辑core-site.xml文件

[root@hadoop01 opt]# cd /home/software/hadoop-2.7.1/etc/hadoop/
[root@hadoop01 hadoop]# vim core-site.xml

(3)添加如下内容

<!-- 开启回收站-->
<property>
<name>fs.trash.interval</name>
<value>10</value>
</property>

2、开启回收站机制后

(1)再次执行删除命令,运行结果如下

[root@hadoop01 hadoop]# hadoop fs -rm /nihao
21/08/19 15:10:43 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
21/08/19 15:10:44 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 10 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://hadoop01:9000/nihao' to trash at: hdfs://hadoop01:9000/user/root/.Trash/Current

在这里插入图片描述
(2)恢复文件,执行:

hadoop fs -mv /user/root/.Trash/Current/nihao

(3)如果不移动,10min后自动删除

六、eclipse写API

1、新建java Project并添加jar

在这里插入图片描述
new->Folder
在这里插入图片描述
将下面的两个图片中的四个区域中的jar复制到上步建立的hdfs_jar中,会有重复,直接覆盖
在这里插入图片描述
在这里插入图片描述
选中hdfs_jar中的所有jar包,右击选择build Path
在这里插入图片描述

2、开始编写hdfsTest

(1)读取文件

//读取文件
@Test
public void readFile() throws IOException, URISyntaxException {
	// --创建配置对象org.apache.hadoop.conf.Configuration;
	Configuration conf = new Configuration();
	// --获取hdfs文件系统对象org.apache.hadoop.fs.FileSystem;
	FileSystem fs = FileSystem.get(new URI("hdfs://192.168.232.129:9000"), conf);
	// --获取读取hdfs文件的输入流
	FSDataInputStream in = fs.open(new Path("/demo/hehe"));
	// --获取输出流将读到的内容写到本地文件
	FileOutputStream out = new FileOutputStream("D://aaa.txt");
	// -整合输入输出流org.apache.hadoop.io.IOUtils;
	IOUtils.copyBytes(in, out, conf);
	}

(2)上传文件

//--上传文件
	@Test
	public void putFile() throws IOException, URISyntaxException {
		// --创建配置对象
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://192.168.232.129:9000"), conf);
		// --获取输出流
		FSDataOutputStream out = fs.create(new Path("/park1"));
		// --获取输入流读取本地文件
		ByteArrayInputStream in=new ByteArrayInputStream("hello hdfs".getBytes());
//		FileInputStream in = new FileInputStream("D:/aaa.txt");
		IOUtils.copyBytes(in, out, conf);
	}

(3)删除文件

//--删除文件
	@Test
	public void deleteFile() throws IOException, URISyntaxException {
		// --创建配置对象
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://192.168.232.129:9000"),conf);
		fs.delete(new Path("/park"));
	}

(4)创建文件夹

//--创建文件夹
	@Test
	public void testMkdir() throws IOException, URISyntaxException {
		// --创建配置对象
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://192.168.232.129:9000"),conf);
		fs.mkdirs(new Path("/video"));
	}

(5)查看指定目录下的文件

//--查看指定目录下的文件
	@Test
	public void testLs() throws IOException, URISyntaxException {
		// --创建配置对象
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://192.168.232.129:9000"),conf);
		FileStatus[] listStatus = fs.listStatus(new Path("/hadoop"));
		for (FileStatus fileStatus:listStatus) {
			System.out.println(fileStatus);
		}
	}

(6)获取文件块信息

//--获取文件块信息
	@Test
	public void getBlock() throws IOException, URISyntaxException {
		// --创建配置对象
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(new URI("hdfs://192.168.232.129:9000"),conf);
		BlockLocation[] data = fs.getFileBlockLocations(new Path("/hadoopaaa"), 0, Integer.MAX_VALUE);
		for (BlockLocation blockLocation : data) {
			System.out.println(blockLocation);
		}
	}

(7)import包

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值