HDFS分布式文件系统
Hadoop学习笔记
1. Hadoop简介
1.1 Hadoop架构
- Hadoop由三个模块组成:
分布式存储HDFS、
分布式计算MapReduce、
资源调度引擎Yarn
1.2 Hadoop历史
-
Hadoop作者Doug Cutting
-
Apache Nutch作为前者的一部分,主要包括web爬虫、全文检索;2003年“谷歌分布式文件系统GFS”论文,2004年开源版本NDFS
-
2004年“谷歌MapReduce”论文,2005年Nutch开源版MapReduce
2. HDFS是什么?
-
HDFS是Hadoop中的一个存储子模块
-
HDFS (全称Hadoop distributed File System),即hadoop的分布式文件系统
-
File System文件系统:操作系统中负责管理和存储文件信息的软件;具体地说,它负责为用户创建文件,存入、读出、修改、转储、删除文件等
-
当数据集大小超出一台计算机的存储能力时,就有必要将它拆分成若干部分,然后分散到不同的计算机中存储。管理网络中跨多台计算机存储的文件系统称之为分布式文件系统(distributed filesystem)
2.1 HDFS特点
2.1.1 优点:
- 适合存储大文件,能用来存储管理PB级的数据;不适合存储小文件
- 处理非结构化数据
- 流式的访问数据,一次写入、多次读写
- 运行于廉价的商用机器集群上,成本低
- 高容错:故障时能继续运行且不让用户察觉到明显的中断
- 可扩展
2.1.2 局限性
- 不适合处理低延迟数据访问
- DFS是为了处理大型数据集分析任务的,主要是为达到高的数据吞吐量而设计的
- 对于低延时的访问需求,HBase是更好的选择
- 无法高效存储大量的小文件
- 不支持多用户写入及任意修改文件
2.2 小结
3. HDFS篇
3.1 HDFS命令
- HDFS命令与linux 命令的相似性
3.2 WEB UI界面
- 访问HDFS的web界面,浏览器访问
node01:50070
3.3 HDFS编程
-
HDFS java API编程
-
方式一:
mvn clean package -DskipTests # 在工程目录下执行
-
方式二:利用IDEA图形化界面
-
运行jar包
hadoop@node01 target]$ hadoop jar hdfs-1.0-SNAPSHOT.jar com.kaikeba.com.hdfs.FilecopyFromLocal
-
如何查看官方api文档
网址:https://hadoop.apache.org/docs/r2.7.3/api/index.html
-
HDFS代码
写数据
package com.kaikeba.hadoop.hdfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IoUtils; import java.io.*; import java.net.URI; /** * 将本地文件系统的文件通过java-API写入到HDFS文件 */ public class copyFileFromLocal { public static void main(String[] args){ //本地磁盘路径 String source="C:/test.txt"; //先确保/data目录存在 String destination="hdfs://node01:8020/test.txt";//HDFS的路徑 InputStream in = null; try { in = new BufferedInputStream(new FileInputStream(source)); //HDFS读写的配置文件 Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(destination),conf); //调用Filesystem的create方法返回的是FSDataOutputStream对象 //该对象不允许在文件中定位,因为HDFS只允许一个已打开的文件顺序写入或追加 OutputStream out = fs.create(new Path(destination)); IoUtils.copyBytes(in, out, 4096, true); } catch (FileNotFoundException e) { System.out.println("exception"); e.printstacktrace(); } catch (IOException e) { System.out.println("exception1"); e.printstacktrace(); } } }
读数据
package com.kaikeba.hadoop.hdfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IoUtils; import java.io.bufferedoutputstream; import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; /** * 从HDFS读取文件 * 打包运行jar包 [bruce@node01 Desktop]$ hadoop jar com.kaikeba.hadoop-1.0-SNAPSHOT.jar com.kaikeba.hadoop.hdfs.ReadFileFromHDFS */ public class ReadFileFromHDFS { public static void main(String[] args) { try { //源文件 String srcFile = "hdfs://node01:8020/test.txt"; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(srcFile),conf); FSDataInputStream hdfsInStream = fs.open(new Path(srcFile)); //本地文件 bufferedoutputstream outputStream = new bufferedoutputstream(new FileOutputStream("C:/01 HK/高级03班/test01.txt")); IoUtils.copyBytes(hdfsInStream, outputStream, 4096, true); } catch (IOException e) { e.printstacktrace(); } } }
3.4 小结
-
学习HDFS命令,学会借助help命令
-
根据HDFS与linux命令的相似性,举一反三
-
HDFS API编程时,要学会查看api文档
4. 核心概念block
4.1 数据块block
4.1.1 HDFS block块
-
问:HDFS中一个44M大小的块会不会占据128M的空间?
-
问:这样存储有没有问题?
4.2 block副本
-
因为HDFS是用普通的商用服务器搭建起来的;所以有节点出问题的可能性;
-
那么如果每个block只有一份的话,当block所在的节点宕机后,此block将无法访问,进而导致文件无法完整读取
-
为保正数据的可用及容错,HDFS设计成每个block共有三份,即三个副本
-
如何设置副本数?
-
replication = 3
-
hdfs-site.xml
<property> <name>dfs.replication</name> <value>3</value> </property>
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GTEJfI1V-1606831135371)(assets/Image201906211108.png)]
4.3 机架存储策略
-
实际机房中,会有机架,每个机架上若干服务器
-
第一块:在本机器的HDFS目录下存储Block的第一个副本。
第二块:在不同Rack(机架,暂且称为r1)的某个Datanode(称为dn2)上存储Block的第二个副本。
第三块:在dn2所在机架r1下,找一台其它的datanode节点,存储Block的第三个副本。
更能多副本:随机节点
了解下服务器参数:https://item.jd.com/4564487.html
机架:https://item.jd.com/16829137698.html
4.4 block的一些操作
-
设置文件副本数,有什么用?
[hadoop@node01 ~]$ hdfs fsck
- 查看文件中损坏的块
[hadoop@node01 ~]$ hdfs fsck /tmall-201412-1w.csv -list-corruptfileblocks
- 查看文件的块基本信息
hdfs fsck /02-041-0029.mp4 -files -blocks -locations
[hadoop@node01 ~]$ hdfs fsck /tmall-201412-1w.csv -delete
4.5 小结
- HDFS上的文件分块存储
- 每个块有3个副本
- 考虑机架存储策略
- 关于block的一些常用命令:hdfs fsck
5. HDFS架构
- 大多数分布式框架都是主从架构
- HDFS也是主从架构Master|Slave或称为管理节点|工作节点
5.1 NameNode
5.1.1 文件系统
- file system文件系统:操作系统中负责管理和存储文件信息的软件;具体地说,它负责为用户创建文件,存入、读取、修改、转储、删除文件等
- 读文件 =>>找到文件 =>> 在哪 + 叫啥?
- 元数据
- 命名空间
5.1.2 HDFS-NameNode
- HDFS本质上也是文件系统filesystem,所以它也有元数据Metadata;
- 元数据Metadata保存在NameNode内存中
- NameNode作用
- HDFS元数据
说明:
①为hdfs-site.xml中属性dfs.namenode.edits.dir的值决定;用于namenode保存edits.log文件
②为hdfs-site.xml中属性dfs.namenode.name.dir的值决定;用于namenode保存fsimage文件
5.2 Datanode
5.3 SeconddaryNameNode
-
为什么引入SecondaryNameNode
-
为什么元数据存储在NameNode在内存中?
-
这样做有什么问题?如何解决?
-
HDFS编辑日志文件 editlog:在NameNode节点中的编辑日志editlog中,记录下来客户端对HDFS的所有更改的记录,如增、删、重命名文件(目录);
-
作用:一旦系统出故障,可以从editlog进行恢复;
-
但editlog日志大小会随着时间变在越来越大,导致系统重启根据日志恢复的时候会越来越长;
-
为了避免这种情况,引入检查点机制checkpoint,命名空间镜像fsimage就是HDFS元数据的持久性检查点,即将内存中的元数据落磁盘生成的文件;
-
此时,namenode如果重启,可以将磁盘中的fsimage文件读入内容,将元数据恢复到某一个检查点,然后再执行检查点之后记录的编辑日志,最后完全恢复元数据。
-
但是依然,随着时间的推移,editlog记录的日志会变多,那么当namenode重启,恢复元数据过程中,会花越来越长的时间执行editlog中的每一个日志;而在namenode元数据恢复期间,HDFS不可用。
-
为了解决此问题,引入secondarynamenode辅助namenode,用来合并fsimage及editlog
-
-
SecondaryNameNode定期做checkpoint检查点操作
- 创建检查点checkpoint的两大条件:
- Secondary NameNode首先请求原NameNode进行edits的滚动,这样新的编辑操作就能够进入新的文件中
- Secondary NameNode通过HTTP GET方式读取原NameNode中的fsimage及edits
- Secondary NameNode读取fsimage到内存中,然后执行edits中的每个操作,并创建一个新的统一的fsimage文件
- Secondary NameNode通过HTTP PUT方式将新的fsimage发送到原NameNode
- 原NameNode用新的fsimage替换旧的fsimage,同时系统会更新fsimage文件到记录检查点的时间。
- 这个过程结束后,NameNode就有了最新的fsimage文件和更小的edits文件
-
SecondaryNameNode一般部署在另外一台节点上
- 因为它需要占用大量的cpu时间
- 并需要与namenode一样多的内存,来执行合并操作
-
如何查看edits日志文件
hdfs oev -i edits_0000000000000000256-0000000000000000363 -o /home/hadoop/edit1.xml
-
如何查看fsimage文件
hdfs oiv -p XML -i fsimage_0000000000000092691 -o fsimage.xml
-
checkpoint相关属性
属性 值 解释 dfs.namenode.checkpoint.period 3600秒(即1小时) The number of seconds between two periodic checkpoints.
| dfs.namenode.checkpoint.txns | 1000000 | 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. |
| dfs.namenode.checkpoint.check.period | 60(1分钟) | The SecondaryNameNode and CheckpointNode will poll the NameNode every ‘dfs.namenode.checkpoint.check.period’ seconds to query the number of uncheckpointed transactions. |
5.4 心跳机制
工作原理:
- NameNode启动的时候,会开一个ipc server在那里
- Datanode启动后向NameNode注册,每隔3秒钟向NameNode发送一个“心跳heartbeat”
- 心跳返回结果带有NameNode给该Datanode的命令,如复制块数据到另一Datanode,或删除某个数据块
- 如果超过10分钟NameNode没有收到某个Datanode 的心跳,则认为该Datanode节点不可用
- Datanode周期性(6小时)的向NameNode上报当前Datanode上的块状态报告BlockReport;块状态报告包含了一个该 Datanode上所有数据块的列表
心跳的作用:
-
通过周期心跳,NameNode可以向Datanode返回指令
-
可以判断Datanode是否在线
-
hadoop集群刚开始启动时,99.9%的block没有达到最小副本数(dfs.namenode.replication.min默认值为1),集群处于安全模式,涉及BlockReport;
心跳相关配置
- hdfs-default.xml
- 心跳间隔
属性 | 值 | 解释 |
---|---|---|
dfs.heartbeat.interval | 3 | Determines datanode heartbeat interval in seconds. |
- block report
More Actions属性 | 值 | 解释 |
---|---|---|
dfs.blockreport.intervalMsec | 21600000 (6小时) | Determines block reporting interval in milliseconds. |
5.5 负载均衡
$HADOOP_HOME/sbin/start-balancer.sh -t 5% # 磁盘利用率最高的节点若比最少的节点,大于5%,触发均衡
5.6 小结
- NameNode负责存储元数据,存在内存中
- Datanode负责存储block块及块的元数据
- SecondaryNameNode主要负责对HDFS元数据做checkpoint操作
- 集群的心跳机制,让集群中各节点形成一个整体;主节点知道从节点的死活
- 节点的上下线,导致存储的不均衡,可以手动触发负载均衡
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。