【填坑日记10】分布式之文件系统

文章目录

  • 前言
  • 分布式文件系统设计
    • GFS
      • 4个前提:
      • 设计预期
      • 架构 & 设计
    • HDFS

前言

前面将近十篇文章,基本上是搭建一个基于JS的web系统的基本流程,这部分内容基本都是在讲一些用户交互,信息展示的内容。接下来的步骤我想写一写后台的一些内容,当前前后台分离的情况下,我理解后台主要的工作就是对外提供计算能力(各种服务),而这些服务实际上是需要对海量的数据进行增删改查。
那么,主要的工作可以归纳与:

  • 计算
  • 结构化数据存储(数据库)
  • 非结构化数据存储(格式各样的文件)
    而在当前大数据的前提下,中心化的方案越来越不吃香了,所以这三样工作都加了一个前缀:分布式
  • 分布式计算
  • 分布式数据库
  • 分布式文件存储

琢磨这些东西那就跑不了Google的那几篇开创性的论文:

  • 计算 。MapReduce: Simplified Data Processing or Large Cluster
  • 分布式数据库。Bigtable
  • 分布式文件系统。GFS

我打算从GFS,也就是文件系统开始说起。

分布式文件系统设计

之前写过一个文章:
如何认识分布式系统
这篇文章从总体上描述了分布式系统是干啥用的。算是一篇科普性的文章吧。

GFS

先看看这篇论文,英文版的看起来太慢,幸好有各路大神的翻译版本。

4个前提:

  1. 所有的节点都是不可靠的,都是会发生故障的,和之前的集中式存储来说不一样,集中式存储都是花大成本去提高单点的可靠性。
  2. 巨大的文件存储需求。TB级的需求,而搜索系统中的很多文件都是几十KB的系统,几亿或者十亿级的文件数量,需要考虑重新设计文件系统的block和管理方式。让上层API不需要对大小文件做区别化的编程。
  3. 绝大部分都是追加形式的文件写,不会或极少的随机写操作。写完之后只会顺序读。这个是一个极重要的假设,如果业务需求是需要大量随机写操作的,这种分布式文件存储估计就会水土不服了。
  4. 应用系统和文件系统协同设计,里面提到了GFS是放弃了部分的一致性指标的。这里提一下分布式存储系统的几个评价指标
    评估一个存储系统来说,有一个CAP原则:
  • C:数据一致性(Consistency)
  • A:数据可用性(availability)
  • P:分区容错性(patition tolerance)
  • CAP原则:CAP原理是指在一个分布式的数据存储系统中,无法同时满足三个条件,最多能满足其中两项。分区容错性指分布式系统中各节点无法通信的情况,在一般的系统中,这点是肯定会出现而在设计中一定要考虑并规避的,根据cap原理,三重制约只能取其二,就只能在A和C中选,而一般我们会选择可用性A,放弃一致性C

设计预期

设计的系统是为了大量的追加写和顺序读操作的高性能,支持随机写和随机小批量读取操作(但是性能不做保证)。必须满足多生产者写入同一文件的同时保证消费者读取同一文件(放弃一定的一致性)。对网络的稳定性大于网络的低延迟。

架构 & 设计

【填坑日记10】分布式之文件系统_第1张图片

  • GFS是位于Linux操作系统之上的存储层,依赖Linux操作系统的FS管理系统,而不是直接操作裸盘。

  • GFS采用主从结构(Master - Chunk)。GFS 存储的文件都被分割成固定大小的 Chunk。在 Chunk 创建的时候,Master 服务器会给每个 Chunk 分配一个不变的、全球唯一的 64 位的 Chunk 标识。Chunk 服务器把 Chunk 以 Linux 文件的形式保存在本地硬盘上,并且根据指定的 Chunk 标识和字节范围来读写块数据。出于可靠性的考虑,每个块都会复制到多个块服务器上。缺省情况下,我们使用 3 个存储复制节点,不过用户可以为不同的文件命名空间设定不同的复制级别。
    Master 节点管理所有的文件系统元数据。这些元数据包括名字空间、访问控制信息、文件和 Chunk 的映射信息、以及当前 Chunk 的位置信息。Master 节点还管理着系统范围内的活动,比如,Chunk 租用管理4、孤儿 Chunk5的回收、以及 Chunk 在 Chunk 服务器之间的迁移。Master 节点使用心跳信息周期地和每个 Chunk服务器通讯,发送指令到各个 Chunk 服务器并接收 Chunk 服务器的状态信息。
    客户端读取一份数据会与GFS系统有两次交互:

  1. 在Master节点读取元数据,也就是获取需要读取数据的地址信息。
  2. 依赖地址信息去访问相应的Chunk服务器,进行数据交换。
  • 缓存:无论是客户端还是 Chunk 服务器都不需要缓存文件数据。客户端缓存数据几乎没有什么用处,因为大部分程序要么以流的方式读取一个巨大文件,要么工作集太大根本无法被缓存。无需考虑缓存相关的问题也简化了客户端和整个系统的设计和实现。Chunk 服务器不需要缓存文件数据的原因是,Chunk 以本地文件的方式保存,Linux 操作系统的文件系统缓存会把经常访问的数据缓存在内存中。
  • Chunk大小选择:64MB,这个和操作系统的一样,同样存在取舍的问题,小了会增加数据交换的次数和master的元数据管理成本。大了就会造成很多的碎片,具体的优缺点分析在论文里简单的提了一下,更详细的block设计取舍可以参考操作系统原理这门技术了。
  • 元数据:Master保存了GFS整个文件命名空间、文件和 Chunk 的对应关系、每个 Chunk 副本的存放地点。数据保存在Master的内存中(这就和上面的Chunk有关联了)。前两种类型的元数据8同时也会以记录变更日志的方式记录在操作系统的系统日志文件中,日志文件存储在本地磁盘上,同时日志会被复制到其它的远程Master服务器上。采用保存变更日志的方式,我们能够简单可靠的更新 Master 服务器的状态,并且不用担心 Master 服务器崩溃导致数据不一致的风险。Master 服务器不会持久保存 Chunk 位置信息。Master服务器在启动时,或者有新的 Chunk 服务器加入时,向各个 Chunk 服务器轮询它们所存储的 Chunk 的信息。master并不持久保存这些位置信息。
  • 元数据操作日志:用于数据恢复,checkpoint,单独的线程来创建Checkpoint文件,和Oracle的有点类似,LGWR等线程
  • 日志文件的重要性:多个备份,只有把相应的日志记录写入到本地以及远程机器的硬盘后,才会响应客户端的操作请求。

HDFS

GFS是google内部的系统,而HDFS是一个Apache的开源子项目Hadoop的一个组件。HDFS:Hadoop Distributed File System。从这个名称就能看出来。
HDFS总的设计目标与GFS很类似,

  • 适用于大型的文件读取,不适用于海量小文件存储
  • 不适用于随机读写
  • 不适用于低时延的应用

HDFS是GFS的一个简化版本,架构上看:

  • GFS的Master/Thunk,HDFS的NameNode/DataNode。其中Master和NameNode都是保存元数据、整体命名空间
  • 客户端直接与Thunk或者DataNode进行数据交换
  • 基本数据存储单元:Thunk-64MB,Block-128MB。
  • 通过操作日志进行数据恢复

HDFS提供了一些其他类型的节点:

  • Secondary NameNode。为了解决NameNode的单点失效问题,引入的新类型的节点,节点定期合并主Namenode的namespace image和edit log。避免edit log过大,通过创建检查点checkpoint来合并。它会维护一个合并后的namespace image副本, 可用于在Namenode完全崩溃时恢复数据
  • Checkpoint Node。NameNode启动后会从最新的checkpoint image开始,然后合并edit log演变成最新的状态。创建一个checkpoint需要一定的时间,为了不给NameNode造成压力,checkpoint node定期构建checkpoint,再同步给NameNode。
  • Backup Node。和checkpoint node类似,backup node也是定位构建checkpoint image的。而且Backup Node还将namespace直接加载在本地内存里。相当于和NameNode一样了。对于每个NameNode,目前只允许配置一个Backup Node。而且利用Backup node模式就不允许使用CheckPoint Node了。
  • 当然,最重要的区别,GFS不开源,大家一般都是通过那篇论文去了解其设计思路和理念,而HDFS是基于这个思路和理念做出来的开源软件,我们要用的话,没去Google就只能用用HDFS了。

后续只能是用HDFS去做分布式文件系统,把GFS拉进来记录是因为这篇论文把相关的思路都写在一起了,记录起来比较方便。

你可能感兴趣的:(笔记,HDFS,分布式存储,分布式)