目录:
- HDFS简介
- HDFS架构说明
- HDFS读文件流程
- HDFS写文件流程
- HDFS 可靠性
- HDFS shell
- IDEA 开发工具使用
- Java 操作HDFS
- 全分布式集群搭建
一.简介
HDFS(Hadoop Distributed File System,分布式文件系统)基于Ggoogel发布的GFS论文设计开发,其除具备其他分布式文件系统相同特性外,还有自己的特性:
- 高容错:认为硬件总是不可靠的,有副本的存在,所以高可靠。
- 高吞吐量:为大量数据访问应用提供高吞吐量支持,增加节点的方式来实现。
- 大文件存储:支持存储TB-PB级别的数据,分块存储来实现。
说明:
关于为什么不能做大量小文件、随机写入、低延迟读取的解析:
移动计算能力说明:
硬件失效:副本的作用
流式数据访问:数据传递采用流的方式,数据流
副本的分配原则
二.HDFS架构说明
- NameNode
- 存储hdfs的metadata,比如命名空间信息,块信息等等。运行时所有数据都保存到内存,整个HDFS可存储的文件数受限于NameNode的内存大小。这些信息也可以持久化到磁盘上
- NameNode保存元信息的种类有:
NameNode管理文件系统的命名空间。它维护着文件系统树及整棵树内所有的目录和文件,文件目录的所有者及其权限。这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件和编辑日志文件。NameNode也记录着每个文件中各个块所在的数据节点信息,但它并不永久保存块的位置信息,因为这些信息在系统启动时由数据节点重建。 - 元信息的持久化
在NameNode中存放元信息的文件是fsimage(文件系统镜像)。在系统运行期间所有对元信息的操作都保存在内存中并被持久化到另一个文件edits中。并且edits文件、fsimage文件会被SecondaryNameNode周期性的合并。
- 一个Block在NameNode中对应一条记录(一般一个block占用150字节),如果是大量的小文件,会消耗大量内存。同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间。处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件
- NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性
- Secondary NameNode
- SecondaryNameNode并不是NameNode的备份,SecondaryNameNode的角色就是定期的合并edits和fsimage文件。定时与NameNode进行同步(定期合并文件系统镜像和编辑日志,然后把合并后的传给NameNode,替换其镜像,并清空编辑日志,类似于CheckPoint机制),但NameNode失效后仍需要手工将其设置成主机)
同步流程如下:
- 合并之前告诉NameNode把所有的操作写到新的edites文件并将其命名为edits.new
- SecondaryNameNode从NameNode请求fsimage和edits文件
- SecondaryNameNode把edits和fsimage文件合并成新的fsimage文件
- NameNode从SecondaryNameNode获取合并好的新的fsimage并将旧的替换掉,并把edits用第一步创建的edits.new文件替换掉
- 更新fstime文件中的检查点
- DataNode
- DataNode是hdfs中的worker节点,它负责存储数据块
- 负责为系统客户端提供数据块的读写服务,同时还会根据NameNode的指示来进行创建、删除和复制等操作。
- 还会通过心跳定期向NameNode发送所存储文件块列表信息,后续也会定时报告修改信息
- 当对hdfs文件系统进行读写时,NameNode告知客户端每个数据驻留在哪个DataDode,客户端直接与DateNode进行通信,DataNode还会与其它DataNode通信,复制这些数据块以实现冗余。
- Block数据(块数据)
- 基本存储单位,一般大小为64M,现在默认是128M(配置大的块主要是因为:
1.减少搜寻时间,一般硬盘传输速率比寻道时间要快,大的块可以减少寻道时间;
2.减少管理块的数据开销,每个块都需要在NameNode上有对应的记录;
3.对数据块进行读写,减少建立网络的连接成本) - 一个大文件会被拆分成一个个的块,然后存储于不同的机器。如果一个文件少于Block大小,那么实际占用的空间为其文件的大小
- 基本的读写类似于磁盘的页,每次都是读写一个块
- 每个块都会被复制到多台机器,默认复制3份
HDFS架构其它关键设计要点说明:
- 统一的文件系统名字空间(元数据):HDFS对外仅呈现一个统一的文件系统
- 统一的通讯协议:统一采用RPC方式通信。NameNode被动的接收Client,DataNode的RPC请求
- 空间回收机制:支持回收站机制,以及副本数的动态设置机制
- 数据组织:数据存储以数据块为单位,存储在操作系统的文件系统上
- 访问方式:提供Java API,HTTP方法,SHELL方式访问HDFS数据。
说明:
NN与DN之间交流方式(也就是NN怎么确定DN没有出现问题):
fsimage合并:
NN与SN协作:
rpc协议、空间回收机制:
三.HDFS读文件流程
四.HDFS写文件流程
HDFS - 写文件
- HDFS client将文件写入本地磁盘的文件中
- 当临时文件大小达到一个block大小时,HDFS client通知NameNode,申请写入文件
- NameNode在HDFS的文件系统中创建一个文件,并把该block id和要写入的DataNode的列表返回给HDFS client
- HDFS client收到这些信息后,将临时文件写入DataNodes
- HDFS client将文件内容写入第一个DataNode(一般以4kb为单位进行传输)
- 第一个DataNode接收后,将数据写入本地磁盘,同时也传输给第二个DataNode
- 依此类推到最后一个DataNode,数据在DataNode之间是通过pipeline的方式进行复制的
- 后面的DataNode接收完数据后,都会发送一个确认给前一个DataNode,最终第一个DataNode返回确认给HDFS client
- 当HDFS client接收到整个block的确认后,会向NameNode发送一个最终的确认信息
- 如果写入某个DataNode失败,数据会继续写入其他的DataNode。然后NameNode会找另外一个好的DataNode继续复制,以保证冗余性
- 每个block都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性
- 文件写完后(HDFS client关闭),NameNode提交文件(这时文件才可见,֘如果提交前,NameNode垮掉,那文件也就丢失了。fsync:只保证数据的信息写到NameNode上,但并不保证数据已经被写到DataNode中)
Rack aware(机架感知)
通过配置文件指定机架名和DNS的对应关系
假设复制参数是3,在写入文件时,会在本地的机架保存一份数据,然后在另外一个机架内保存两份数据(同机架内的传输速度快,从而提高性能)
整个HDFS的集群,最好是负载平衡的,这样才能尽量利用集群的优势
五.HDFS可靠性
HDFS - 可靠性
- DataNode可以失效
DataNode会定时发送心跳到NameNode。如果一段时间内NameNode没有收到DataNode的心跳消息,则认为其失效。此时NameNode就会将该节点的数据(从该节点的复制节点中获取)复制到另外的DataNode中 - 数据可以毁坏
无论是写入时还是硬盘本身的问题,只要数据有问题(读取时通过校验码来检测),都可以通过其他的复制节点读取,同时还会再复制一份到健康的节点中 - NameNode不可靠,可以搭建集群
四.HDFS shell:Hadoop Shell常用命令
- 开启虚拟机
- 在虚拟机中开启hdfs
- 在windows中开启xshell,连接虚拟机后,就可以在xshell中操作hdfsl:hadoop-常用的操作命令 操作命令
- 还可以在windows中的web界面查看hdfs信息,通过ip地址访问,需要先在虚拟机中关闭防火墙,在windows中才能通过浏览器访问(关闭防火墙的方式在下面,有暂时关闭和永久关闭两种方式)
还可以进行文件下载,windows和虚拟机是通过ip进行通信(两个主机之间通过ip地址打交道)
五.IDEA开发工具
使用IDEA的目的仅仅是多熟悉一个java开发项目工具。具体配置过程:
- 下载IDEA和jdk
- 安装IDEA,关联jdk
- 配置
- 快捷键
- 常见用法总结
六.Java 操作HDFS
注意:
方式3:
方式4:
文件追加需要注意:
七.全分布式集群搭建
- 准备三台服务器
- 安装虚拟机(01),在虚拟机中安装centOS7(linux),在01中下载java,并安装,然后下载hadoop,并安装
- 克隆虚拟机01,为02号
- 克隆虚拟机01,为03号
注意:虚拟机有克隆和快照(为虚拟机的不同状态创建快照)
- 配置主机名、ip和mac
- 将02、03的mac地址进行修改,因为01、02、03三者都是一样
步骤:
虚拟机右键设置-网络适配器 - 修改主机名和ip地址
- 在windows下开启xshell,将这三台主机进行连接
- 进行免密操作:01,02,03之间会互相访问,需要进行免密才能进行数据交流
- 第一步:首先01需要和自己进行免密
在01中执行
ssh-keygen,然后一路回车下去,这条命令会生成.ssh(不是文件夹,也不是文件),并在此目录下会生成公钥和私钥
进行root用户下,进入 .ssh下,可以看到有三个文件 - 第二步:01号通过公钥和自己做免密
在.ssh目录下执行:cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys - 第三步:01要将自己的公钥发送给02做免密
- 02先创建 .ssh目录,所以在01上需要执行一次生成免密的文件
ssh-keygen - 01将公钥发送到02的tmp目录
scp id_rsa.pub root@192.168.200.101:/tmp
scp:server copy 服务器之间复制文件的命令 - 在02中将/tmp/id_sa.pub文件复制到root/.ssh下
cat tmp/id_rsa.pub >>~/.ssh/authorized_keys
- 第四步:在01中测试能否免密连接02
ssh 192.168.200.101
可以看到ok了 - 第二种和其它主机做免密的方法:这种方法相当于上面这种方法的第三步
ssh-copy-id -i 192.168.200.102
- ip和主机关联