目录

一、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