目录
一、HDFS
二、分布式文件管理系统的优缺点
三、HDFS shell操作及客户端
四、HDFS数据操作
五、NN和2NN的工作机制
六、集群安全模式
七、datanode的工作机制
八、数据完整性
九、服役新节点
十、老节点退役
十一、datanode的多目录配置
十二、小文件处理
十三、回收站
十四、纠删码
一、HDFS
分布式文件管理系统,分布式的意思是多态设备,适合一次性写入,多次读出的场景,只支持追加修改
HDFS 有client、namenode、secondnamenode、datanode模块。
二、分布式文件管理系统的优缺点
优点
1、高可靠性
2、适合大数据
3、可以布置在相对廉价的服务器、
缺点:
1、不适合存储小文件
2、不适合低延时数据访问
文件块:
HDFS的数据存储是以文件块的形式存储,hadoop1.x默认文件块大小64MB,hadoop2.x 至最新hadoop3.2.1以128MB为大小。实际开发中,结合服务器硬盘的传输速度,一般自定义在与传输速度临近的1024字节倍数附近,如:读写速度300MB/S,则定义为256MB。
三、HDFS shell操作及客户端
hdfs dfs cat\ls\mkdir\put\get\\copyToLocal\mkdir\rm\moveFromLocal\mv\rm\rmdir\tail...
hdfs dfsadmin -refreshNodes
Java客户端操作
1、配置hadoop依赖
2、创建hadoop的环境变量、HADOOP_HOME=依赖的文件路径 PATH=%HADOOP_HOME%/bin
3、创建maven工程,修改pom文件,增加junit依赖、hadoop依赖等,如下:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>compile</scope>
</dependency>
</dependencies>
4、在main文件下的resource文件夹内创建log4j2.xml,增加如下配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" strict="true" name="XMLConfig">
<Appenders>
<!-- 类型名为Console,名称为必须属性 -->
<Appender type="Console" name="STDOUT">
<!-- 布局为PatternLayout的方式,
输出样式为[INFO] [2018-01-22 17:34:01][org.test.Console]I'm here -->
<Layout type="PatternLayout"
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
</Appender>
</Appenders>
<Loggers>
<!-- 可加性为false -->
<Logger name="test" level="info" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<!-- root loggerConfig设置 -->
<Root level="info">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
5、在maven的main下创建类实现所需功能。
6、常用方法,增删改查:distributeFileSystem(uri,conf,user),或FileSystem.get(uri,conf,user)
1、增:fs.copyFromLocalFile(boolean delSrc, boolean overwrite, Path src, Path dst),src:源路径。dst:目标路径
2、删:fs.delete(path,boolean)。path:删除路径。boolean:是否要进行迭代删除,若是false只能删除文件和空目录
3、改:fs.rename(path1,path2) path1:以移动的初始路径。path2:目的路径。如果目的路径不存在则是修改文件名。
4、查:fs.listfiles(path,boolean)。path:文件目录;boolean:是否进行迭代。获取结果用getpath(),getblock()......
5、 fs.liststatus(path),常用方法:isfile()、isdir()
四、HDFS数据操作
1、文件的写入:
1、Java用户端创建DistributeFileSystem对象,对象会与namenode发出传输数据请求。
2、namenode在收到请求后,会校核存储目录是否存在,校核权限等等,然后回应客户端,可以存储数据
3、客户端fs对象会再次请求namenode,传输第一个block信息。
4、namenode在接收到请求后,会根据block信息以及目前datanode的存储情况,返回给客户端存储该block处的datanode
5、客户端会创建文件输出流,以最近距离优先原则,与最近的datanode1发出传输数据请求,datanode1会与datanode2发出请求,datanode2会对datanode3发出请求。datanode3确认后,会回应datanode2的请求,确认可以创建传输流,datanode2在收到3的回应后,会同样回应datanode1,datanode1最后会回应客户端。在客户端收到回应后,传输流就创建完成。
6、客户端会将第一个block文件是以packet为单位传输(packet的大小为64kb,packet内是n多个chunk,每个chunk大小为512byte+4byte的效验值)
源码解释:传输时,创建好的packet会进入dataqueue,传输流会从dataqueue中获取packet,将packet传输给datanode1,此时,也会将packet传输给ackqueue。另外一个流,responseprossor会监听datanode1、datanode2、datanode3的回应,当3个节点确认接收到packet后,packet会从ackqueue中移除。
7、packet在pipeline内的传输是客户端-datanode1,datanode1-datanode2,datanode2-datanode3
* DFSOutputStream creates files from a stream of bytes.
*
* The client application writes data that is cached internally by
* this stream. Data is broken up into packets, each packet is
* typically 64K in size. A packet comprises of chunks. Each chunk
* is typically 512 bytes and has an associated checksum with it.
*
* When a client application fills up the currentPacket, it is
* enqueued into dataQueue. The DataStreamer thread picks up
* packets from the dataQueue, sends it to the first datanode in
* the pipeline and moves it from the dataQueue to the ackQueue.
* The ResponseProcessor receives acks from the datanodes. When an
* successful ack for a packet is received from all datanodes, the
* ResponseProcessor removes the corresponding packet from the
* ackQueue.
*
* In case of error, all outstanding packets and moved from
* ackQueue. A new pipeline is setup by eliminating the bad
* datanode from the original pipeline. The DataStreamer now
* starts sending packets from the dataQueue.
2、文件的写出
1、客户端向namenode发出请求,请求下载数据
2、namenode会根据客户端的请求,确认存放数据的datanode并返回给客户端
3、客户端会以距离最近原则,向最近的datanode发出数据读取请求。
4、datanode在接收到请求后,会以packet为单位的输出流将数据发送到客户端
5、在请求下载其余block时,客户端会从新以距离最近原则对最近的datanode发起请求,而后获得其余block的方式与第一相同。
6、客户端在获取到所有的block后,会进行数据的合并操作,最终获得完整的数据。
3、距离计算
两个节点到共同父节点的距离之和
4、机架感知
For the common case, when the replication factor is three, HDFS’s placement policy is to put one replica on the local machine if the writer is on a datanode, otherwise on a random datanode, another replica on a node in a different (remote) rack, and the last on a different node in the same remote rack.
5、3个备份的存储方案:
hadoop2.x:若存储需求从某datanode的节点上发出,则先在该节点的datanode上储存一份,若从客户端发出的存储请求,则第一个备份存储在随机一个datanode。第二个备份存储在和第一个备份相同的机架,不同的datanode上。最后一份备份在与之前不同的机架的任意一个datanode上。
hadoop3.x:若存储需求从某datanode的节点上发出,则先在该节点的datanode上储存一份,若从客户端发出的存储请求,则第一个备份存储在随机一个datanode。第二份备份存储在与第一份不同的机架任意一份datanode,第三份存储在与第二个同一机架不同的datanode上。
五、NN和2NN的工作机制
1、NN用于存储元数据信息:
1、NN的存储方式是内存存储元数据信息,磁盘存储编辑日志edit和内存镜像fsimage。
2、初次启动集群时,NN会创建一个编辑日志edit和内存元数据镜像fsimage,当用户进行数据操作时,会edit会记录用户操作,然后再对内存中的元数据进行操作。
3、当二次启动集群时,NN会把磁盘中的edit和fsimage合并加载到内存,恢复元数据。
2、2NN用来辅助NN
1、当达到1小时或者是NN的edit存储满时,2NN会询问NN是否需要checkpoint,若是NN返回需要,NN会生成新的edit,旧的edit停止写入。2NN会将NN中的旧edit和fsimage复制过去,然后2NN会在内存中对就edit和fsimage进行合并,产生新的fsimage。然后将新的fsimage发送给NN。
2、NN的磁盘中只会保存2个fsimage,但会保存全部的edit
3、NN内存中的数据恢复
1、NN会将磁盘中最新的edit和fsimage在内存中合并,恢复数据。
2、若是NN节点磁盘数据也遭到破坏,则可将磁盘存储的edit和fsimage完全删除,从2NN获取最新的eidt和fsimage,最大限度的还原内存数据。
3、所谓合并,就是将Edits和Fsimage加载到内存中,照着Edits中的操作一步步执行,最终形成新的Fsimage)。
查看方式:转化成xml下载到win上在查看。
[user@hadoop102 current]$ pwd
/opt/module/hadoop-3.1.3/data/tmp/dfs/name/current
[user@hadoop102 current]$ hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-3.1.3/fsimage.xml
[user@hadoop102 current]$ cat /opt/module/hadoop-3.1.3/fsimage.xml
[user@hadoop102 current]$ sz /opt/module/hadoop3.1.3/fsimage.xml 下载到本地
[user@hadoop102 current]$ hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-3.1.3/edits.xml
[user@hadoop102 current]$ cat /opt/module/hadoop-3.1.3/edits.xml
[user@hadoop102 current]$ sz /opt/module/hadoop3.1.3/edits.xml
六、集群安全模式
1、当集群非第一次启动时,edit编辑日志和fsimage加载到内存合并成元数据,但从fsimage的内容可以看出,并没有存储block信息,所以,集群启动后,NN在合并完edit和fsimage后,会进入监听模式,NN会等待datanode的汇报,当namenode获得99.9%的block满足最小副本原则,默认1个副本,退出安全模式
2、安全模式之下,只可查看,不可操作
3、常用命令
bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态)
4、应用:可以写个脚本,监督是否退出安全模式,并在退出安全模式后执行操作。
七、datanode的工作机制
1、datanode启动后,会找namenode进行注册。
2、datanode会隔段时间对存储的block进行校验,并将校验值与存储block时的校验值比较。若出现问题,则不再向namenode汇报该block
3、datanode每隔一小时会向namenode汇报所有块信息,若出现块的校验值与初始校验值不同,则不再上报该块。
4、datanode每3秒钟会进行一次“心跳”,即与namenode汇报自己状态,心跳会接收namenode传达给datanode的指令
5、若namenode在10分钟30秒后还没有收到datanode的心跳,则认为该节点已不可使用
八、数据完整性
1、datanode在读取block时,会进行校验,若校验结果与存储时的校验结果不同,则认为数据已损坏,无法读取,
2、常见的校验算法 crc(32) md5(128) sha1(160),默认使用crc
九、服役新节点
1、配置core-site、hdfs-site、yarn-site、mapred-site与集群相同,若需要脚本启动,需要修改workers
2、配置白名单,默认情况下,只要是新节点的配置有namenode信息,则新节点启动后会自动加入集群。一般情况下都是提前配置白名单,只有在白名单的节点才能加入集群。配置方式如下:
1、在NameNode的/opt/module/hadoop-3.1.3/etc/hadoop目录下分别创建whitelist 和 blacklist文件
[user@hadoop102 hadoop]$ pwd
/opt/module/hadoop-3.1.3/etc/hadoop
[user@hadoop102 hadoop]$ touch whitelist
[user@hadoop102 hadoop]$ touch blacklist
2、在whitelist中添加如下主机名称,假如集群正常工作的节点为102 103 104 105
hadoop102
hadoop103
hadoop104
hadoop105
3、在NameNode的hdfs-site.xml配置文件中增加dfs.hosts 和 dfs.hosts.exclude配置
<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/whitelist</value>
</property>
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/blacklist</value>
</property>
配置好之后重启集群
十、老节点退役
1、白名单:不可行,原因:退役节点datanode直接关闭,数据未交接,出现了数据丢失
2、黑名单:推荐,原因:加入黑名单后,退役节点会进入退役阶段,此时进行数据交接,在交接完成后进入退役状态。该退役节点未关闭
十一、datanode的多目录配置
需要在hdfs-site.xml文件中增加如下配置,然后删除data和log重新格式化启动集群
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///${hadoop.tmp.dir}/data1,file:///${hadoop.tmp.dir}/data2</value>
</property>
十二、小文件处理
1、把指定目录下的文件归档成har
[user@hadoop102 hadoop-3.1.3]$ bin/hadoop archive -archiveName input.har –p /user/input /user/output
2、查看har内的文件
[user@hadoop102 hadoop-3.1.3]$ hadoop fs -lsr /user/output/input.har
[user@hadoop102 hadoop-3.1.3]$ hadoop fs -lsr har:///user/output/input.har
3、解归档文件
[user@hadoop102 hadoop-3.1.3]$ hadoop fs -cp har:/// user/output/input.har/* /user
十三、回收站
1、启用回收站,修改core-site.xml,配置垃圾回收时间为1分钟。可根据自己的实际情况设置回收站
<property>
<name>fs.trash.interval</name>
<value>1</value>
</property>
2、查看回收站,回收站在集群中的路径:/user/.Trash/….
3、修改访问垃圾回收站用户名称,进入垃圾回收站用户名称,默认是dr.who,修改为使用的用户 [core-site.xml]
<property>
<name>hadoop.http.staticuser.user</name>
<value>user</value>
</property>
4、若通过java客户端删除的不会进入回收站,除非进行以下操作,调用方法
Trash trash = New Trash(conf);
trash.moveToTrash(path);
5、数据恢复,在垃圾站的数据进入垃圾袋之前可以从垃圾站中把数据移动回来,手速够快。
[user@hadoop102 hadoop-3.1.3]$ hadoop fs -mv /user/.Trash/Current/user/input /user/input
十四、纠删码
1、hadoop3.0之后,增加了纠删码机制,引入的好处是,传统的3个副本的存储方式,虽然可靠性高,但是会造成磁盘利用率低, 会产生2倍的冗余开销。纠删码的引入,可以降低数据的冗余,节省约50%左右的存储空间,当然,带来好处的同时,也有缺点:纠删码需要内部进行运算,就会消耗一定的资源。
2、内置纠删码,hadoop3.0之后,内置了5中纠删码,查看:
Erasure Coding Policies:
ErasureCodingPolicy=[Name=RS-10-4-1024k, Schema=[ECSchema=[Codec=rs, numDataUnits=10, numParityUnits=4]], CellSize=1048576, Id=5], State=DISABLED
ErasureCodingPolicy=[Name=RS-3-2-1024k, Schema=[ECSchema=[Codec=rs, numDataUnits=3, numParityUnits=2]], CellSize=1048576, Id=2], State=DISABLED
ErasureCodingPolicy=[Name=RS-6-3-1024k, Schema=[ECSchema=[Codec=rs, numDataUnits=6, numParityUnits=3]], CellSize=1048576, Id=1], State=ENABLED
ErasureCodingPolicy=[Name=RS-LEGACY-6-3-1024k, Schema=[ECSchema=[Codec=rs-legacy, numDataUnits=6, numParityUnits=3]], CellSize=1048576, Id=3], State=DISABLED
ErasureCodingPolicy=[Name=XOR-2-1-1024k, Schema=[ECSchema=[Codec=xor, numDataUnits=2, numParityUnits=1]], CellSize=1048576, Id=4], State=DISABLED
解释:数据切割时,是按照1024k的整数倍切割,如果超过128MB则会按块的大小切割。
RS-10-4-1024k:使用RS编码,每10个数据单元(cell),生成4个校验单元,共14个单元,也就是说:这14个单元中,只要有任意的10个单元存在(不管是数据单元还是校验单元,只要总数=10),就可以得到原始数据。每个单元的大小是 1024k=1024*1024=1048576。
RS-3-2-1024k:使用RS编码,每3个数据单元,生成2个校验单元,共5个单元,也就是说:这5个单元中,只要有任意的3个单元存在(不管是数据单元还是校验单元,只要总数=3),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
RS-6-3-1024k:使用RS编码,每6个数据单元,生成3个校验单元,共9个单元,也就是说:这9个单元中,只要有任意的6个单元存在(不管是数据单元还是校验单元,只要总数=6),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
RS-LEGACY-6-3-1024k:策略和上面的RS-6-3-1024k一样,只是编码的算法用的是rs-legacy。
XOR-2-1-1024k:使用XOR编码(速度比RS编码快),每2个数据单元,生成1个校验单元,共3个单元,也就是说:这3个单元中,只要有任意的2个单元存在(不管是 数据单元还是校验单元,只要总数=2),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576。
启动纠删码:
3、开启对RS-3-2-1024k策略的支持
为啥不用默认的RS-6-3-1024k策略呢,理论情况下,该策略需要9台DN的支持,而RS-3-2-1024k策略需要5台DN的支持
[user@hadoop202 hadoop-3.1.3]$ hdfs ec -enablePolicy -policy RS-3-2-1024k
Erasure coding policy RS-3-2-1024k is enabled