HDFS:Hadoop Distributed File System
分布式存储系统,提供了高可靠、高扩展性和高吞吐率的数据存储服务
HDFS优点:
1.高容错性:数据自动保存多个副本;副本丢失后,自动恢复
2.适合批处理:移动计算而非数据,数据位置暴露给计算框架
3.适合大数据处理
4.可构建在廉价的机器上:通过多副本提高可靠性;提供了容错和恢复机制
HDFS缺点:
高延迟数据访问
小文件存取:占用NameNode大量内存,
并发写入、文件随机修改:一个文件只能有一个写入者, 仅支持append操作
数据存储:
文件被切分为固定大小的数据块(block),hadoop1.x默认为64M,hadoop2.x默认为128M
存放方式:按大小切分为若干个block,存储在不同节点上,默认为每个block都有三个副本
block大小和副本数通过client端上传文件时设置,文件上传成功后,副本数可以变更,Block Size不能改变
HDFS架构
NameNode(文件包括fsimage、edits、fstime)
主要是接收客户端的读写服务,保存metadata(文件名,副本数,blk1,blk_2,{blk1,{node1,node2},{blk_2,{node2,node3}}},文件的owership和permission)}
metadata存储放磁盘文件名为fsimage,主要用于读请求
edits文件记录对metadata的操作信息
注:namenode记录着每个文件中各个块所在的数据节点信息,但它不会永久保存块的位置信息,因为这些信息会在系统启动时由datanode重建
工作特点:
1)NameNode始终在内存中保存metedata,用于处理读请求
2)当有写请求到来时,namenode会首先向edits文件写日志,成功返回后,才会修改内存,并且向客户端返回
3)Hadoop会维护一个fsimage文件,也就是namenode中metedata的镜像,但是fsimage不会随时与namenode内存中的metedata保持一致,而是每隔一段时间通过合并edits文件来更新内容
SecondaryNameNode
主要工作是帮助NN合并edits log,减少NN启动时间
SNN执行合并时机:
1)fs.checkpoint.period,默认为1小时
2)fs.checkpoint.size
SNN合并流程如下:
DataNode
启动DN线程时,向NN汇报block信息,通过向NN发送心跳保持与其联系(),3秒一次,如果NN1分钟没收到DN心跳,则认为其已经lost,并copy其上的block到其他的DN
副本放置策略:
第一个:放置在上传文件的DN,如果是集群外提交,则随机挑选一台磁盘不太满,cpu不太忙的节点
第二个:放在与第一个副本不同的机架的节点上
第三个:与第二个放同一个机架
更多副本时,随机
文件块(block):最基本的存储单位,HDFS默认Block大小是64MB
HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间
HDFS写流程
HDFS写流程时并行的,复制过程中,如果datanode出现问题,namenode删除有问题的datanode
1)初始化FileSystem,客户端调用create()来创建文件
2)FileSystem用RPC调用数据节点,在文件系统的命名空间中创建一个新的文件,元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件
3)FileSystem返回FSOutputStream,客户端用于写数据,客户端开始写入数据,FSOutputStream封装了一个DFSOutputStream对象,该对象负责处理datanode和namenode之间的通信
4)DFSOutputStream将数据分成块,写入data queue。data queue由Data Streamer读取,并通知元数据节点分配数据节点,用来存储数据块(每块默认复制3块)。分配的数据节点放在一个pipeline里。Data Streamer将数据块写入pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点
5)DFSOutputStream为发出去的数据块保存了ack queue,等待pipeline中的数据节点告知数据已经写入成功
6)当客户端结束写入数据,则调用stream的close函数。此操作将所有的数据块写入pipeline中的数据节点,并等待ack queue返回成功。最后通知元数据节点写入完毕
7)如果数据节点在写入的过程中失败,关闭pipeline,将ack queue中的数据块放入data queue的开始,当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。失败的数据节点从pipeline中移除,另外的数据块则写入pipeline中的另外两个数据节点。元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份
HDFS读流程:
注:HDFS读流程是顺序的,不是并行的
注:FileSystem用RPC调用元数据节点,得到文件的数据块信息,对于每一个数据块,元数据节点返回保存数据块的数据节点的地址
1)客户端通过FileSystem对象的open ()打开需要读取的文件
2)DistributedFileSystem通过RPC来调用namenode,以确定文件起始块的位置
3)对于每个块,namenode返回存有该块副本的datanode地址,此外,这些datanode根据它们与客户端的距离来排序,如果客户端本身就是一个datanode,那么该节点就会从本地datanode读取,DistributedFileSystem类返回一个FSDataInputStream对象,给客户端来读取数据,客户端调用FSDataInputStream的read()方法读取数据
4)存储着文件起始几个块的datanode地址的DistributedFileSystem随即连接距离最近的datanode,通过数据流反复调用read()方法,可以将数据从datanode传输到客户端
5)到达块的末端时,DFSInputStream关闭与该datanode的连接,然后寻找下一个最佳的datanode
注:设计的重点是namenode告知客户端每个块中最佳的datanode,并让客户端直接连接到该datanode检索数据
安全模式:
namenode启动:将fsimage存入内存-->执行编辑edits中的各种操作-->创建新的fsimage和一个空白的edits(SNN不参与)
此刻namenode运行在安全模式(namenode只只读的)
此阶段Namenode收集各个datanode的报告
系统中数据块的位置并不是namenode维护的,而是以列表形式存储在datanode中
hadoop搭建步骤
NN SNN DN
node1 1
node2 1 1
node3 1 1
node4 1 1
masters 存放secondarynamenode主机地址
slaves 存放datanode主机
1.主机名、防火墙、hosts、网络
vim /etc/hosts
2.时间同步
ntpdate -u s1a.time.edu.cn
3.jdk 环境变量配置
4.免密钥ssh登陆 node1 免密钥登陆node1-node4
5.修改配置文件
core-site.xml fs.defaultFS hadoop.tmp.sir(配置NN)
hdfs-site.xml(配置SNN的rpc和http地址)
masters (配置SNN节点)
slaves(配置DN节点)
6.同步配置文件 修改配置需保证集群配置相同
7.格式化namenode
8启动
RPC:Remote Procedure Call
通过Flume和Sqoop导出数据
Flume:大规模流数据-->HDFS,典型的应用是从另外一个系统中收集日志数据
Flume支持大量的数据源,比如tail,syslog和log4j
典型的配置:每个源机器上部署运行一个Flume节点,通过多层的聚合节点,最后将数据导入HDFS中
Flume提供了不同级别的投递可靠性,最大努力投递,端到端的投递
Sqoop:结构化的数据(关系型数据库)-->HDFS
应用场景:将白天的生产的数据库中的数据在晚间导入Hive数据仓库中进行分析
通过distcp并行复制:
介绍:Hadoop有一个有用的distcp分布式复制程序,该程序可以从Hadoop文件系统间复制大量系统数据,也可以将大量的数据复制到Hadoop中,distcp是作为一个MapReduce作业来实现的,该复制作业是通过集群中并行运行map来完成,默认情况下每个集群节点最多分配20个map任务
典型的应用场景:在两个HDFS集群间传输数据,
1)如果两个集群采用相同版本的Hadoop,就适合使用hdfs方案:
hadoop distcp hdfs:namenode1/foo hdfs://namenode2:bar
注:默认下distcp会跳过目标路径下已经存在的文件,可以通过-override选项覆盖现有的文件,通过-update选项选择有改动的文件
2)不同版本的Hadoop复制,可以使用基于只读HTTP协议的HFTP
hadoop distcp hftp://namenode1:50070/foo hdfs://namenode2:50070/bar
3)使用webhdfs协议复制,不用考虑任务不兼容问题
hadoop distcp webhdfs://namenode1:50070/foo webhdfs://namenode2:50070/bar