HDFS是什么?
    HDFS(Hadoop Distributed File System ) , 意为: Hadoop分布式文件系统。
    是Apache Hadoop核心组件之一, 作为大数据生态圈最底层的分布式存储服务而存在。 也可以说大数据首先要解决的问题就是海量数据的存储问题。

    HDFS主要是解决大数据如何存储问题的。 分布式意味着是HDFS是横跨在多台计算机上的存储系统。
    HDFS是一种能够在普通硬件上运行的分布式文件系统,它是高度容错的,适应于具有大数据集的应用程序,它非常适于存储大型数据 (比如 TB 和 PB)。
    HDFS使用多台计算机存储文件, 并且提供统一的访问接口, 像是访问一个普通文件系统一样使用分布式文件系统。
    image.png

    Doug Cutting领导Nutch项目研发, Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能。
    Nutch的开发人员完成了相应的开源实现HDFS, 并从Nutch中剥离和MapReduce成为独立项目HADOOP。

    HDFS设计目标
    硬件故障(Hardware Failure) 是常态, HDFS可能有成百上千的服务器组成,每一个组件都有可能出现故障。因此故障检测和自动快速恢复是HDFS的核心架构目标。
    HDFS上的应用主要是以流式读取数据(Streaming Data Access) 。 HDFS被设计成用于批处理,而不是用户交互式的。相较于数据访问的反应时间,更注重数据访问的高吞吐量。
    典型的HDFS文件大小是GB到TB的级别。所以, HDFS被调整成支持大文件(Large Data Sets) 。它应该提供很高的聚合数据带宽,一个集群中支持数百个节点,一个集群中还应该支持千万级别的文件。
    大部分HDFS应用对文件要求的是write-one-read-many访问模型。一个文件一旦创建、写入、关闭之后就不需要修改了。这一假设简化了数据一致性问题,使高吞吐量的数据访问成为可能。
    移动计算的代价比之移动数据的代价低。一个应用请求的计算,离它操作的数据越近就越高效。将计算移动到数据附近,比之将数据移动到应用所在显然更好。
    HDFS被设计为可从一个平台轻松移植到另一个平台。这有助于将HDFS广泛用作大量应用程序的首选平台。

    适合场景
    大文件
    数据流式访问
    一次写入多次读取
    低成本部署,廉价PC
    高容错
    不适合场景
    小文件
    数据交互式访问
    频繁任意修改
    低延迟处

    主从架构
    分块存储
    副本机制
    元数据记录
    抽象统一的目录树结构(namespace)

    HDFS集群是标准的master/slave主从架构集群。
    一般一个HDFS集群是有一个Namenode和一定数目的Datanode组成。
    Namenode是HDFS主节点, Datanode是HDFS从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。
    官方架构图中是一主五从模式,其中五个从角色位于两个机架(Rack)的不同服务器上。

    image.png

    分块存储
    HDFS中的文件在物理上是分块存储(block) 的,默认大小是128M(134217728),不足128M则本身就是一块
    块的大小可以通过配置参数来规定,参数位于hdfs-default.xml中: dfs.blocksize。
    image.png

    副本机制
    文件的所有block都会有副本。副本系数可以在文件创建的时候指定,也可以在之后通过命令改变。
    副本数由参数dfs.replication控制, 默认值是3,也就是会额外再复制2份,连同本身总共3份副本。
    image.png

    元数据管理
    在HDFS中, Namenode管理的元数据具有两种类型:
    文件自身属性信息
    文件名称、权限,修改时间,文件大小,复制因子,数据块大小。
    文件块位置映射信息
    记录文件块和DataNode之间的映射信息,即哪个块位于哪个节点上。
    image.pngimage.png

    namespace
    HDFS支持传统的层次型文件组织结构。用户可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。
    Namenode负责维护文件系统的namespace名称空间,任何对文件系统名称空间或属性的修改都将被Namenode记录下来。
    HDFS会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如: hdfs://namenode:port/dira/dir-b/dir-c/file.data。
    image.png

    数据块存储
    文件的各个block的具体存储管理由DataNode节点承担。
    每一个block都可以在多个DataNode上存储。
    image.png

    文件系统协议
    HDFS Shell CLI支持操作多种文件系统,包括本地文件系统(file:///)、分布式文件系统(hdfs://nn:8020)等
    具体操作的是什么文件系统取决于命令中文件路径URL中的前缀协议。
    如果没有指定前缀,则将会读取环境变量中的fs.defaultFS属性,以该属性值作为默认文件系统。

    1. hadoop fs -ls file:/// #操作本地文件系统
    2. hadoop fs -ls hdfs://node1:8020/ #操作HDFS分布式文件系统
    3. hadoop fs -ls / #直接根目录,没有指定协议 将加载读取fs.defaultFS值

    目前版本来看,官方最终推荐使用的是hadoop fs。当然hdfs dfs在市面上的使用也比较多

    1. 创建文件夹 hadoop fs -mkdir [-p] <path> hadoop fs -mkdir /itcast
    2. 查看指定目录下内容 hadoop fs -ls [-h] [-R] [<path> ...]
    3. 上传文件到HDFS指定目录下 hadoop fs -put [-f] [-p] <localsrc> ... <dst> hadoop fs -put zookeeper.out /itcast
    4. hadoop fs -put zookeeper.out /itcast
    5. 查看HDFS文件内容 hadoop fs -cat <src> hadoop fs -cat /itcast/zookeeper.out
    6. 读取指定文件全部内容,显示在标准输出控制台。
    7. 注意:对于大文件内容读取,慎重。
    8. 下载HDFS文件 hadoop fs -get [-f] [-p] <src> ... <localdst> hadoop fs -get /itcast/zookeeper.out ./
    9. 拷贝HDFS文件 hadoop fs -cp [-f] <src> ... <dst> hadoop fs -cp /small/1.txt /itcast

    命令官方指导文档
    https://hadoop.apache.org/docs/r3.3.0/hadoop-project-dist/hadoop-common/FileSystemShell.html