Hadoop之HDFS
一、概述
Hadoop是一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,而MapReduce则为海量的数据提供了计算 。
二、hadoop优点
Hadoop是一个能够对大量数据进行分布式处理的软件框架。 Hadoop 以一种可靠、高效、可伸缩的方式进行数据处理 。
Hadoop 是可靠的,因为它假设计算元素和存储会失败,因此它维护多个工作数据副本,确保能够针对失败的节点重新分布处理。
Hadoop 是高效的,因为它以并行的方式工作,通过并行处理加快处理速度。
Hadoop 还是可伸缩的,能够处理 PB 级数据 。
此外,Hadoop 依赖于社区服务,因此它的成本比较低,任何人都可以使用 。
Hadoop是一个能够让用户轻松架构和使用的分布式计算平台。用户可以轻松地在Hadoop上开发和运行处理海量数据的应用程序。它主要有以下几个优点 :
1.高可靠性。Hadoop按位存储和处理数据的能力值得人们信赖 。
2.高扩展性。Hadoop是在可用的计算机集簇间分配数据并完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中 。
3.高效性。Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
4.高容错性。Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配 。
5.低成本。与一体机、商用数据仓库以及QlikView、Yonghong Z-Suite等数据集市相比,hadoop是开源的,项目的软件成本因此会大大降低。
Hadoop带有用Java语言编写的框架,因此运行在 Linux 生产平台上是非常理想的。Hadoop 上的应用程序也可以使用其他语言编写,比如 C++ 。
hadoop大数据处理的意义
Hadoop得以在大数据处理应用中广泛应用得益于其自身在数据提取、变形和加载(ETL)方面上的天然优势。Hadoop的分布式架构,将大数据处理引擎尽可能的靠近存储,对例如像ETL这样的批处理操作相对合适,因为类似这样操作的批处理结果可以直接走向存储。Hadoop的MapReduce功能实现了将单个任务打碎,并将碎片任务(Map)发送到多个节点上,之后再以单个数据集的形式加载(Reduce)到数据仓库里。
三、Hadoop生态系统
HDFS
:Hadoop Distributed File System 作为Hadoop 生态体系中数据的存储的软件解决方案
MapReduce
:Hadoop中分布式计算框架(只需要实现少量的代码,就可以开发一个分布式的应用程序),对海量数据并行分析和计算
HBase
: 基于HDFS 的列式存储的NoSql
Hive
:是一款SQL解释引擎,能够将SQL语句翻译成MR代码
Flume
:分布式的日志收集系统,用于收集海量日志数据,并将其存储在hdfS中
kafka
:消息对列,实现对分布式应用程序间的解耦和数据缓冲
Zookeeper
:分布式协调服务,用户注册中心、配置中心、集群选举、状态检测、分布式锁
HDFS
1.伪集群安装
1)准备虚拟机
更改IP
删除MAC地址
更改主机名 vi /etc/sysconfig/network
2)安装JDK 8
3)配置Java环境变量
export JAVA_HOME=/home/java/jdk1.8.0_181
export PATH=
P
A
T
H
:
PATH:
PATH:JAVA_HOME/bin
4)配置主机名与IP的映射关系
[root@HadoopNode00 ~]# vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=HadoopNode00
[root@HadoopNode00 ~]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.11.20 HadoopNode00
5)关闭防火墙
[root@HadoopNode00 ~]# service iptables stop # 关闭防火墙
[root@HadoopNode00 ~]# chkconfig iptables off # 关闭防火墙开机自动启动
6)ssh免密登陆
[root@HadoopNode00 ~]# ssh-keygen -t rsa # 生成密钥
[root@HadoopNode00 ~]# ssh-copy-id HadoopNOde00
7)解压Hadoop
解压Hadoop到指定目录
[root@HadoopNode00 ~]# mkdir /home/hadoop/
[root@HadoopNode00 ~]# tar -zxvf /home/hadoop/hadoop-2.6.0.tar.gz -C /home/hadoop
8)配置Hadoop环境变量
9)配置 etc/hadoop/core-site.xml
10)配置 etc/hadoop/hdfs-site.xml
11)格式化namenode
[root@HadoopNode00 ~]# hdfs namenode -format
[root@HadoopNode00 ~]# tree /home/hadoop/hadoop-2.6.0/hadoop-root
12)启动hdfs
start-dfs.sh # 开启HDFS
stop-dfs.sh # 关闭hdfs
13)进入web界面
http://主机名:50070
windows下 配置域名与ip的映射:C:\Windows\System32\drivers\etc \hosts
2.HDFS Shell 相关操作
1). 上传 root目录下的install.log 到hdfs 根目录下
[root@HadoopNode00 ~]# hadoop fs -put /root/install.log /1.txt
2).ls 找刚才上传为文件命名为1.txt
[root@HadoopNode00 ~]# hadoop fs -ls /
Found 1 items
-rw-r–r-- 1 root supergroup 8901 2019-09-17 23:28 /1.txt
3).下载文件
[root@HadoopNode00 ~]# hadoop fs -get /1.txt /root/baizhi.txt
4).删除文件
[root@HadoopNode00 ~]# hadoop fs -rm /2.txt
5).查看文件
[root@HadoopNode00 ~]# hadoop fs -cat /1.txt
6).创建文件夹
[root@HadoopNode00 ~]# hadoop fs -mkdir /baizhi
[root@HadoopNode00 ~]# hadoop fs -ls /
7).复制文件
[root@HadoopNode00 ~]# hadoop fs -cp /1.txt /baizhi/
[root@HadoopNode00 ~]# hadoop fs -ls /
8).开启回收机制(core-site.xml)
3. Java API 操作HDFS
1).导入依赖
2)Windows 配置Hadoop环境
- 解压hadoop到指定的目录
- 拷贝hadoop.dll和winutils.exe到hadoop/bin 目录下
- 配置Hadoop环境变量
- 配置主机名和IP的映射关系
3)权限不足解决方案
org.apache.hadoop.security.AccessControlException: Permission denied: user=Administrator, access=WRITE, inode="/baizhi":root:supergroup:drwxr-xr-x
第一种:配置 hdfs-site.xml
第二种:
-DHADOOP_USER_NAME=root
第三种
System.setProperty(“HADOOP_USER_NAME”, “root”);
4) 相关操作
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.theories.suppliers.TestedOn;
import sun.awt.geom.AreaOp;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class App {
private Configuration configuration;
private FileSystem fileSystem;
@Before
public void getClient() throws Exception {
System.setProperty("HADOOP_USER_NAME", "root");
/*
* 准备配置对象
* */
configuration = new Configuration();
/*
* 添加相应的配置文件*/
configuration.addResource("core-site.xml");
configuration.addResource("hdfs-site.xml");
/*
* 通过FileSystem.newInstance 获得客户端对象*/
fileSystem = FileSystem.newInstance(configuration);
}
@Test
public void testUpload01() throws Exception {
/*
*
* 源文件 | 目标文件
* Path 对象
* */
fileSystem.copyFromLocalFile(new Path("G:\\A.docx"), new Path("/baizhi/2.docx"));
}
@Test
public void testUpload02() throws Exception {
/*
* 准备 本地输入流
* */
FileInputStream inputStream = new FileInputStream("G:\\A.docx");
/*
* 准备 hdfs 输出流
* */
FSDataOutputStream outputStream = fileSystem.create(new Path("/baizhi/3.docx"));
/*
* 使用工具类进行拷贝
* */
IOUtils.copyBytes(inputStream, outputStream, 1024, true);
}
@Test
public void testDownload01() throws Exception {
fileSystem.copyToLocalFile(false, new Path("/1.txt"), new Path("G:\\3.txt"), true);
}
@Test
public void testDownload02() throws Exception {
FileOutputStream outputStream = new FileOutputStream("G:\\4.txt");
FSDataInputStream inputStream = fileSystem.open(new Path("/1.txt"));
IOUtils.copyBytes(inputStream, outputStream, 1024, true);
}
@Test
public void test011() throws IOException {
RemoteIterator<LocatedFileStatus> list = fileSystem.listFiles(new Path("/"), true);
while (list.hasNext()) {
LocatedFileStatus locatedFileStatus = list.next();
Path path = locatedFileStatus.getPath();
System.out.println(path.toString());
}
}
@Test
public void test02() throws Exception{
fileSystem.delete(new Path("/baizhi"),false);
}
@Test
public void test03() throws Exception{
boolean exists = fileSystem.exists(new Path("/1.txt"));
if (exists){
System.out.println("文件存在");
}else {
System.out.println("文件不存在");
}
}
@Test
public void testy04() throws Exception{
fileSystem.mkdirs(new Path("/baizhi1243"));
}}
4.HDFS Architecture
HDFS为主从架构,HDFS中有一个主的NameNode,管理系统命名空间和管理客户端对文件的访问,其中还有DataNode负责和NameNode进行协调工作,DataNode负责数据的存储,在存储数据(文件)的过程中一个文件会被分成一个块或者多个块,在NameNode中存储了一些数据(存储的数据是块到DataNode的映射关系),datanode还根据NameNode的指令创建删除复制块。
namenode
:存储元数据(用户描述数据的数据),负责管理DataNode
datanode
:用于存储数据块的节点,负责响应客户端的对块的读写请求,向NameNode汇报自己的块信息
block块
:数据块,hdfs中对文件拆分的最小单元,切分尺度默认为128MB,每个块在默认情况下有三个副本
rack
:机架,使用机架配置文件对存储节点进行物理编排,用于优化存储和计算
1)什么是block块
(1)为什么块的大小为128MB?
在Hadoop1.x 块大小默认为64MB,在Hadoop2.x 默认为128MB
工业限制:一般来说机械硬盘的读取速度100MB左右
软件优化:通常认为最佳状态为寻址时间为传输时间的100分之一
(2)Block块的大小能否随意设置?
不能,如果BlockSize过大,可能导致多余存储空间浪费,导致存取时间过长 如果BlockSize过小,会导致寻址时间过长,同样造成效率低下。
(3)HDFS为什么不适合存储小文件
文件 | namenode内存占用 | datanode磁盘占用 |
---|---|---|
128MB 单文件 | 1个Blcok元数据的大小 | 128MB |
128*1MB | 128个Block元数据的大小 | 128MB |
namenode内存会过于紧张
2)Rack Awareness 机架感知
对于常见情况,当复制因子为3时,HDFS的放置策略是将一个副本放在本地机架中的一个节点上,另一个放在本地机架中的另一个节点上,将最后一个放在另一个机架中的另一个节点上。此策略可以减少机架间写入流量,从而提高写入性能。机架故障的可能性远小于节点故障的可能性;此策略不会影响数据可靠性和可用性保证。但是,它确实减少了读取数据时使用的聚合网络带宽,因为块只放在两个唯一的机架而不是三个。使用此策略时,文件的副本不会均匀分布在机架上。三分之一的副本位于一个节点上,三分之二的副本位于一个机架上,另外三个副本均匀分布在剩余的机架上。此策略可提高写入性能,而不会影响数据可靠性或读取性能。
查看默认机架
[root@HadoopNode00 ~]# hdfs dfsadmin -printTopology
3)NameNode 和 SecondaryNameNode 的 关系 (重点)fsimage文件:元数据信息的备份,会被加载到内存中
edits文件:Edits文件帮助记录增加和更新操作,提高效率
namenode在启动时会加载fsimage和edits的文件,所以在第一次启动的时候需要格式化namenode
当用户上传文件的时候或者进行其他操作的时候,操作记录会写入edits文件中,这样edits和fsimage文件加起来的元数据永远是最新的。
如果此时用户一直进行操作的话,edits文件会越来越大,这就导致了在下次启动的时候启动速度过慢。
为了解决这个问题,出现了SecondaryNameNode ,将当前的NameNode的edits和fsimage文件拷贝到自己的节点上,进行合并操作,在合并完成后,将新的fsimage文件传输到原来的namenode中,此时namanode再去加载最新的fsimage。
新的问题:在SecondaryNameNode 进行拷贝操作的时候,如果有客户端读写请求过来,势必要追加相应的操作记录到edits文件中,但是此时正在进行拷贝操作,改变则代表会造成数据紊乱,怎么办?解办法是:会有一个新的叫做edits-inprogress的文件被创建,新的操作将写入此文件中,等待SecondaryNameNode合并完成,将edits-inprogress文件改名成为当前的edits文件。
4)检查点
namenode使用fsimage和edits文件保存元数据,2nn会定期的下载主的(Active)namenode的fsimage文件和edits 文件,并在本地进行合并。
合并的时机就称之为检查点
检查点有两种触发机制:
(1) 默认一个小时进行合并
(2) 操作数量达到100W次进行合并
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600s</value>
<description>
The number of seconds between two periodic checkpoints.
Support multiple time unit suffix(case insensitive), as described
in dfs.heartbeat.interval.
</description>
</property>
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>The Secondary NameNode or CheckpointNode will create a checkpoint
of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless
of whether 'dfs.namenode.checkpoint.period' has expired.
</description>
</property>
5)Safemode
在启动时候加载fsimage和edits文件,等待其他的DataNode报告块信息,直至大部分块可用。在次期间,集群处于SafeMode,NameNode的安全模式本质上是HDFS集群的只读模式,它不允许对文件系统或块进行任何修改。
通常,在DataNode报告大多数文件系统块可用之后,NameNode会自动离开Safemode。
可以手动的进入或者退出SafeMode
[root@HadoopNode00 ~]# hdfs dfsadmin -safemode enter
Safe mode is ON
[root@HadoopNode00 ~]# hadoop fs -put /root/1.txt /
put: Cannot create file/1.txt._COPYING_. Name node is in safe mode.
[root@HadoopNode00 ~]# hdfs dfsadmin -safemode leave
Safe mode is OFF
[root@HadoopNode00 ~]# hadoop fs -put /root/1.txt /
6)DataNode工作机制
启动的时候会注册DataNode
周期向NameNode上报块信息,并且对其信息状态进行反馈,DataNode进行相应的操作
心跳不能出现10分钟以上的断连,必须重启DataNode才能重现上线