myDFS
Hadoop
-
Hadoop核心组件:
- Hadoop HDFS:分布式文件存储系统
- Hadoop YARN:集群资源管理和任务调度的框架,用于解决资源任务调度
- Hadoop MapReduce:分布式计算框架,用于解决海量数据计算
-
Hadooop生态圈
-
HDFS hadoop Distributed file system
特点:
- 横跨多台计算机
- 高度容错
- 适用于具有大数据集的应用程序
- 在多台计算机上,提供统一的访问接口,像是访问一个普通文件系统一样。
设计目标:
- 故障检测和自动快速修复(核心架构目标)
- HDFS关注数据访问的高吞吐量,弱化数据访问的反应时间(小文件会有高延迟,大文件效果略好)| 流式读取数据|批处理
- 轻写入,重读取,提供的修改API较少,读取API很丰富
特性:
-
主从架构:
master / slave 主从架构集群
master对映Namenode,slave对映Datanode
-
分块存储:
将文件在物理上分块存储(block),默认大小是128M,不足128则本身构成一块
-
副本机制:
文件的所有block都有副本,副本在文件创建时指定,也可以在之后通过命令修改
默认有两个副本
-
元数据记录:
元数据:记录数据的数据
元数据分类:
-
文件自身属性信息:
文件名称 / 权限 / 修改时间 / 文件大小 / 复制因子 / 数据库大小
-
文件块位置映射信息
记录文件库和DataNode之间的映射信息,即:哪个块位于哪个节点上
-
-
抽象统一的目录树结构(nameSpace命名空间)
对上层提供的层次型文件组织结构,对用户提供创建目录/文件删除移动等API
NameNode的作用就是维护NameSpace命名空间,任何对nameSpace的修改都要由NameNode实现
-
数据块存储:
主从之间各司其职,一条命令之后,nameSpace在其内部修改目录结构,也调控dataNode真实删除信息
每一个block都可以在多个DataNode上存储
HDFS工作流程:
-
主角色: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处理些边缘业务(元数据文件夹的合并...)
写入流程
过程说明:
-
客户端创建对象实例Distributed File System(毕竟java)此对象中封装了与HDFS操作相关的方法
-
调用DFS对象的create方法,通过RPC请求nameNode创建文件
到达NameNode可以插入各种钩子 / 拦截器 / 过滤器 执行各种检测判断
类似目标文件是否存在,父目录是否存在,客户端权限是否足够。。。
检查通过以后,NameNode返回FSDataOutputSttream输出流给客户端用于写数据
-
客户端通过FSDataOutputStream流写入数据
将数据分成一个个数据包(默认64k),内部组件DataStreamer请求NameNode挑选出适合存储数据副本的一组dataNode地址(dataStreamer负责管理管道 | 同步到哪三个节点)
写入策略:
namenode仅需要等待最小复制块(默认为1)返回成功即可,即知道成功复制到一台从机上就算成功,后续失败的复制异步完成。
-
Pipeline管道:
用于在上传文件写数据过程中,由一主写多从的解决方案
一般思路:master只写入一个从,其余复制过程在从之间异步完成 / master负责写完三分从
Pipeline思路:
客户端将数据块写入第一个数据节点,第一个节点保存数据之后在将块复制到第二个数据节点,第二个保存后再复制到第三个数据节点
类似第一种
-
ACK应答响应:
为了保证在pipeline之间的传递的可靠性,信息传输需要通过ACK确认接收
-
默认三副本存储策略:
第一个副本:优先存储在客户端本地,否则存储在随机位置
第二个副本:不同于第一块副本的不同机架
第三个副本:和第二块副本相同机架不同机器
可能由于硬件问题导致策略降级,但主要做到数据不能存储在一台机器上
FastDFS
目标特性:
-
解决大容量文件存储和高并发访问,文件存取时实现了负载均衡
-
实现软件方式的RAID,可以用廉价的IDE硬盘进行存储
RAID:Redundant Array of Independent Disks将多个硬盘驱动器组合在一起
-
支持存储服务器在线扩容
-
支持相同内容的文件仅保存一份,节约磁盘空间
NFS: Network File System:
NFS允许不同计算机之间通过网络透明地访问和共享文件,就好像这些文件是本地文件一样
和云存储的区别在于:
- NFS应用常用是企业内网/本地网络中搭建文件服务器,云存储则是分布式的
架构原理:
-
客户端Client
指访问FastDFS的客户端设备,通常是应用服务器
-
访问服务器(跟踪服务器)TrackerServer
作用:
反向代理存储服务器
- 服务注册:管理存储服务器集群,当StorageServer启动时,会把自己注册到跟踪服务器上,并定期报告自身状态信息,包括硬盘剩余空间,文件同步状况,文件上传下载次数统计等(像是nameNode中的元数据)
- 服务发现:Client访问存储服务器前,必须先访问TrackerServer,动态获取到连接信息。
高可用性:
为了保证高可用,一个FastDFS集群中可以有多个TrackerServer节点,由集群自动选举一个leader节点
-
存储服务器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,路径信息,文件名等信息
- 心跳信息,确保本机没有挂
- 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类型