关于DFS

126 阅读10分钟

myDFS

Hadoop

  1. Hadoop核心组件:

    • Hadoop HDFS:分布式文件存储系统
    • Hadoop YARN:集群资源管理和任务调度的框架,用于解决资源任务调度
    • Hadoop MapReduce:分布式计算框架,用于解决海量数据计算
  2. Hadooop生态圈

    image20230927103002742

  3. HDFS hadoop Distributed file system

    image20230927104057001

    特点:

    • 横跨多台计算机
    • 高度容错
    • 适用于具有大数据集的应用程序
    • 在多台计算机上,提供统一的访问接口,像是访问一个普通文件系统一样。

    设计目标:

    • 故障检测和自动快速修复(核心架构目标)
    • HDFS关注数据访问的高吞吐量,弱化数据访问的反应时间(小文件会有高延迟,大文件效果略好)| 流式读取数据|批处理
    • 轻写入,重读取,提供的修改API较少,读取API很丰富

    特性:

    • 主从架构:

      master / slave 主从架构集群

      master对映Namenode,slave对映Datanode

      image20230927110227476

    • 分块存储:

      将文件在物理上分块存储(block),默认大小是128M,不足128则本身构成一块

    • 副本机制:

      文件的所有block都有副本,副本在文件创建时指定,也可以在之后通过命令修改

      默认有两个副本

    • 元数据记录:

      元数据:记录数据的数据

      元数据分类:

      • 文件自身属性信息:

        文件名称 / 权限 / 修改时间 / 文件大小 / 复制因子 / 数据库大小

        image20230927110927786

      • 文件块位置映射信息

        记录文件库和DataNode之间的映射信息,即:哪个块位于哪个节点上

        image20230927110947519

    • 抽象统一的目录树结构(nameSpace命名空间)

      对上层提供的层次型文件组织结构,对用户提供创建目录/文件删除移动等API

      NameNode的作用就是维护NameSpace命名空间,任何对nameSpace的修改都要由NameNode实现

  • 数据块存储:

    主从之间各司其职,一条命令之后,nameSpace在其内部修改目录结构,也调控dataNode真实删除信息

    每一个block都可以在多个DataNode上存储

HDFS工作流程:

image20230927111910365

  • 主角色:nameNode

    nameNode是访问HDFS的唯一入口

    nameNode内部通过内存和磁盘文件两种方式管理元数据

    • 仅存储HDFS的元数据
    • NameNode知道HDFS中任何给定文件的块列表和位置,由此从块重构建文件
    • NameNode不持久化存储每个文件中各个块所在dataNode具体位置,而是在系统重启时从DataNode重建——由下层DataNode节点向上汇报
    • NameNode运行中会消耗大量内存
    • NameNode在整个集群中是单点故障的--nameNode一坏整个集群就坏
  • 从角色:dataNode

    负责具体的数据块的存储

    dataNode的数量决定HDFS集群整体的数据存储能力

    • dataNode启动时,会将自己注册到NameNode并汇报自己负责持有的快列表
    • 当某个dataNode关闭时,不会影响数据的可用性,nameNode安排其他Datanode进行副本复制
    • dataNode所在机器通常配置有大量的硬盘空间
  • secondaryNameNode

    充当NameNode的辅助节点,但不会替代nameNode

    是帮助NameNode处理些边缘业务(元数据文件夹的合并...)

写入流程

image20230927165605215

过程说明:

  1. 客户端创建对象实例Distributed File System(毕竟java)此对象中封装了与HDFS操作相关的方法

  2. 调用DFS对象的create方法,通过RPC请求nameNode创建文件

    到达NameNode可以插入各种钩子 / 拦截器 / 过滤器 执行各种检测判断

    类似目标文件是否存在,父目录是否存在,客户端权限是否足够。。。

    检查通过以后,NameNode返回FSDataOutputSttream输出流给客户端用于写数据

  3. 客户端通过FSDataOutputStream流写入数据

    将数据分成一个个数据包(默认64k),内部组件DataStreamer请求NameNode挑选出适合存储数据副本的一组dataNode地址(dataStreamer负责管理管道 | 同步到哪三个节点)

    写入策略:

    namenode仅需要等待最小复制块(默认为1)返回成功即可,即知道成功复制到一台从机上就算成功,后续失败的复制异步完成。

  • Pipeline管道:

    用于在上传文件写数据过程中,由一主写多从的解决方案

    一般思路:master只写入一个从,其余复制过程在从之间异步完成 / master负责写完三分从

    Pipeline思路:

    客户端将数据块写入第一个数据节点,第一个节点保存数据之后在将块复制到第二个数据节点,第二个保存后再复制到第三个数据节点

    类似第一种

    image20230927170153819

  • ACK应答响应:

    为了保证在pipeline之间的传递的可靠性,信息传输需要通过ACK确认接收

    image20230927171152626

  • 默认三副本存储策略:

    第一个副本:优先存储在客户端本地,否则存储在随机位置

    第二个副本:不同于第一块副本的不同机架

    第三个副本:和第二块副本相同机架不同机器

    可能由于硬件问题导致策略降级,但主要做到数据不能存储在一台机器上

FastDFS

目标特性:

  1. 解决大容量文件存储和高并发访问,文件存取时实现了负载均衡

  2. 实现软件方式的RAID,可以用廉价的IDE硬盘进行存储

    RAID:Redundant Array of Independent Disks将多个硬盘驱动器组合在一起

  3. 支持存储服务器在线扩容

  4. 支持相同内容的文件仅保存一份,节约磁盘空间

NFS: Network File System:

NFS允许不同计算机之间通过网络透明地访问和共享文件,就好像这些文件是本地文件一样

和云存储的区别在于:

  • NFS应用常用是企业内网/本地网络中搭建文件服务器,云存储则是分布式的

架构原理:

image20230927192000369

  1. 客户端Client

    指访问FastDFS的客户端设备,通常是应用服务器

  2. 访问服务器(跟踪服务器)TrackerServer

    作用:

    反向代理存储服务器

    • 服务注册:管理存储服务器集群,当StorageServer启动时,会把自己注册到跟踪服务器上,并定期报告自身状态信息,包括硬盘剩余空间,文件同步状况,文件上传下载次数统计等(像是nameNode中的元数据)
    • 服务发现:Client访问存储服务器前,必须先访问TrackerServer,动态获取到连接信息。

    高可用性:

    为了保证高可用,一个FastDFS集群中可以有多个TrackerServer节点,由集群自动选举一个leader节点

  3. 存储服务器StorageServer

    数据存储服务器,文件和meta data都在存储服务器上

    特点:

    • 可采用高可用的方式进行数据存储
    • FastDFS集群中StorageServer按组(group)提供服务,不同组的StoraServer不会相互通信,同组内的StorageServer之间会相互连接进行文件同步
    • StorageServer采用binlog文件记录文件上传没删除等更新操作,binlog中只记录文件名,不记录文件内容。(异步执行binlog完成一致性)
    • 文件同步旨在同族内的Storage server之间进行,由源头服务器push给目标服务器(so what about 控制反转?)

    优点:

    • 文件不分块存储,文件和系统中的文件一一对应(可能导致文件不能过大)
    • 对文件内容做hash处理,避免出现重复文件,节约磁盘空间
    • 下载文件支持HTTP协议,可基于内置的web server或外部web server
    • 支持在线扩容,动态添加卷
    • 支持文件冗余备份和负载均衡
    • 存储服务器上可保存文件属性(meta-data)
    • v2.0网络通信采用libevent,支持大并发访问

    缺点:

    • 直接按文件存储,可直接查看文件内容,缺乏文件安全性
    • 数据同步无校验,存在静默IO问题,降低系统可用性
    • 单线程数据同步,仅适合存储小文件(4KB到500MB之间)
    • 备份数根据存储分卷(分组)决定,缺乏文件被分数设置的灵活性
    • 单个挂载点异常会导致整个存储节点下线
    • 缺乏多机房容灾支持
    • 静态的负载均衡机制

存储策略:

  • 为了支持大容量,存储节点采用分卷(分组)的组织方式。

    卷与卷之间的文件是相互独立的,一个文件经过hash确定存储在哪个卷中

    一个卷可以由一台或多态存储服务器组成,一个卷下的存储服务器中的文件都是相同的,多余的数据起到冗余备份作用,多台机器起到负载均衡作用

  • 在一个卷中增加服务器时,要完成文件的自动同步

    当系统存储空间不足时,可以动态添加卷

文件上传的整体流程

当客户端请求tracker进行上传操作时,会获取到存储服务器的相关信息,主要包括IP和端口,根据返回信息上传文件,通过存储服务器写入磁盘,并返回给客户端ffile_id,路径信息,文件名等信息

image20231002200150827

  1. 心跳信息,确保本机没有挂
  2. tracker中应该有表示文件摘要的k-v,k是通过某种hash算法生成的摘要(非MD5),用此实现降重

预备知识:

常见分布式文件系统:

FastDFS,GFS,HDFS,Lustre,Ceph,GirdFS,mogileFS,TFS

  • 分布式文件系统的应用场景

    图片、视频等非结构化数据,需要存储到文件系统

    Nginx作为静态资源服务器,只是将对静态资源的请求直接路由到资源,而不会经过tomcat和其他中间件,但Nginx本身并不管理文件

    例如:

    • 电商网站存储图片
    • 视频网站存储视频
    • 网盘存储各种文件
    • 社交网络存储图片、视频、文字...
  • file & blob

    File是基于Blob封装的文件类型(二进制数据+文件名)

    Blob是二进制大对象,可以包含任何类型的数据,例如图像、文本、音频视频

    File易于和用户计算机文件系统交互,blob则比较底层,通常用于在客户端进行数据处理

  • 大文件分片:

    例如场景:上传视频时会有进度条

    上传大文件必然需要分片上传,分片实则就是将大文件分成多个blob,然后分别发Ajax

    • 问题1:

      上传中断后,再次上传怎么只上传剩下的

      • 前端用一次Ajax先获取到后台有无此文件,以及存了多少

      • 问题1.1:怎么明确前后端所指是同一份文件——hash

      • 问题1.2:由于hash计算需要全篇的数据,如果大文件真的大,无法全部导入内存计算哈希

        解决方案:增量运算,先算一片的hash,将值添加到下一片,再算hash

  • http请求的content-type

    用于指示http请求或响应中数据的类型和编码方式

    影响前端怎么发送,以及后端怎么接收

    • text/plain:纯文本类型
    • text/html:表示html文档,通常在浏览器中呈现为网页
    • application/json:JSON
    • multipart/form-data:常用于文件上传,后端multipartfile接收
    • application/octet-stream:位置类型的二进制数据
    • image/jpeg等MIME类型