分布式存储系统的难点

在存储系统中,为了获得巨大的性能加成,一个很自然的想法就是采用分片(sharding),将数据分割存储到多台服务器上,这样获得了更大的存储容量,而且可以并行地从多台服务器读取数据。

我们在成百上千台服务器上进行分片,大量基数的情况下,出现错误的频率也大大提升,我们需要一个自动化的从错误中恢复的方法,这就引入了容错(fault tolerance)。

实现容错的最有用的方法就是复制(replication),使用副本存储相同的数据。

有了副本,就需要考虑副本之间的不一致性(inconsistency)问题。

为了解决不一致性的问题,需要进行一定的设计,使各个副本之间保持一致,这需要网络通信来令服务器交互。因此,一致性的代价就是低性能。

这是一个循环,我们需要进行一定的权衡和牺牲。

GFS的设计目标

  1. 系统必须将故障视为一种常态,能够迅速侦测、冗余并恢复失效的组件;
  2. 系统需要支持大文件(数GB),并且能够有效地进行管理;
  3. 系统的工作负载主要是两种读操作:大规模的流式读取和小规模的随机读取,前者来自同一个客户机的连续操作读取同一个文件的连续区域,后者通常是在文件某个随机位置读取几个KB,通常后者会被合并并排序按顺序批量读取,以此提高性能;
  4. 系统的写工作负载时大规模的、顺序的数据追加方式的写操作,数据一旦被写入之后文件就很少会被修改了,同时系统也要支持小规模的随机位置写入;
  5. 支持多客户端并行追加数据到同一个文件;
  6. 关注批处理的性能,而非系统的响应速度。

GFS设计概述



GFS有一个master节点(逻辑上的一个),多个chunkserver,为client提供服务。文件被分割成固定大小的chunk,chunk创建的时候,master服务器会给每个chunk分配一个不变的、全球唯一标识的64位chunk标识,chunk服务器把chunk以linux文件的形式保存在本地的硬盘上,并且根据指定的chunk标识和字节范围来读写数据。出于可靠性考虑,每个chunk可能会被复制到多个chunkserver上。

master节点管理所有的文件系统元数据,但不存储文件数据(这使得GFS将文件系统管理和数据存储分开了),这些元数据包括名字空间、访问控制信息、文件和chunk的映射信息、当前chunk的位置信息。master节点还管理着系统范围内的活动,比如chunk租用、孤儿chunk的回收、以及chunk在chunkserver之间的迁移。master节点用心跳信息周期地和每个chunkserver通讯,发送指令到各个chunkserver并接收chunkserver的状态信息。

GFS客户端代码以库的形式被链接到client的客户程序里,使client可以通过这些函数进入GFS系统访问数据。

一次读取的流程是,首先client将文件名和客户程序指定的字节偏移,根据固定的chunk大小转换成文件的chunk索引,然后把文件名和chunk索引发送给master节点,master节点将相应的chunk表示和副本的位置信息发送回client,client用文件名和chunk索引作为key来缓存这些信息。之后客户端发送请求到其中一个最近的副本处(根据ip计算距离),请求信息包括了chunk的标识和字节范围。

tips:单一的master节点虽然大大简化了设计,但也可能导致master节点成为系统的性能瓶颈所在。因此我们必须尽量减少master节点的读写。

客户端将从master获取的元数据缓存一段时间,后续的操作将直接和chunkserver进行数据读写,除非元数据信息过期或者文件被client重新打开。

一些讨论

chunk尺寸

chunk的大小是关键的设计参数之一,通常选用64MB,这个尺寸远远大于一般文件系统的blocksize(惰性分配可以避免因为大的chunk尺寸造成的内部碎片)。这样做有许多优点:1. 减少了client和master的通信,因为只需要一次和master节点的通信就可以获取chunk的位置信息,之后就可以对同一个chunk进行多次的读写操作;2. 采用较大的chunk尺寸时,client能够对一个块进行多次操作,通过与chunkserver保持较长时间的tcp连接来降低网络负载;3. 较大的chunk尺寸减少了对master存储能力的要求,同时元数据也更有可能全部放在master的内存中,这样访问速度会快很多。

大的chunk尺寸也有一定的缺陷:这通常会产生热点问题。小的文件包含较少的chunk,如果多个client同时对小文件进行访问,存储这些chunk的chunkserver会成为热点。也许多个client同时访问一个小文件并不是GFS设计目标中的常见情景,但是当GFS初次启动的时候,一个可执行文件在GFS上存储为singe-chunk文件,之后这个可执行文件在数百台机器上同时启动,此时热点问题就出现了。为了解决热点问题,通常使用更大的复制参数来保存可执行文件(在更多的chunkserver上复制更多份)、或者错开系统启动的时间、再或者允许client从其他client读取数据(这里就引入了一个新的通信路径)。

元数据

master服务器主要存储三种类型的元数据:文件和chunk的命名空间、文件和chunk的对应关系、每个chunk副本的存放地点。命名空间和对应关系的更新采用保存变更日志的方式更新master服务器的状态,日记由操作系统记录在磁盘上,具有持久性。存放地点不会由master服务器持久化保存,master服务器在启动或者有新的chunkserver加入时,向chunkserver询问存储的chunk信息,同时定期轮询更新,以此获得chunk副本最新的存放地点。

tips:master始终通过chunkserver获取chunk的存放地点,这一设计源于一个思想:只有chunkserver才能最终确定一个chunk是否在它的硬盘上。例如,chunkservre的故障可能会导致chunk的消失,而这是master无法自动获知的。

一致性

这里的一致性是指chunk副本之间的一致性,要求所有chunk副本中保存的内容都是已定义的,并且包含最后以此修改操作写入的数据。为了达到这样的一致性,GFS有以下两项措施:对chunk的所有副本的修改操作顺序一致、使用chunk的版本号来检测副本是否因为它所在的chunk服务器宕机而错过了修改操作导致其失效。GFS通过master服务器和所有chunkserver的定期握手来找到失效的chunkserver,并且使用checksum来校验数据是否损坏。一旦发现问题,数据要尽快利用有效的副本进行恢复。

系统交互



tips:设计系统时,一个重要原则时最小化所有操作和master节点之间的交互。

使用租约(lease)对chunk的多个副本进行主从管理,master节点为chunk的一个副本建立租约,把这个副本叫做主chunk,主chunk对chunk的所有更改操作进行序列化,所有的副本都遵从这个序列进行修改。

  1. 客户机向master节点询问哪一个chunkserver持有当前的租约,以及其他副本的位置(如果没有任何一个持有租约,那么master建立一个);
  2. master将主chunk的标识符和其他副本(也叫secondary副本)的位置返回给客户机,client缓存这些数据,只有当主chunk不可用,或者主chunk回复信息表明它已经不再持有租约的时候,client才需要重新跟master节点联系;
  3. client推送数据到所有的副本上(可以以任意顺序推送)(tips:chunkserver用LRU缓存这些数据; 此处网络IO负载非常高,需要合理规划网络拓扑数据流);
  4. 当所有副本都确认接收了数据,client发送写请求到主chunkserver(这个请求标识了之前推送到副本的数据),主chunkserver为所有操作分配连续的序列号,在本地执行。
  5. 主chunkserver将写请求传递给所有二级副本,二级副本以相同的顺序执行这些操作;
  6. 二级副本完成操作后会回复主chunkserver。
  7. 主chunkserver回复client,如果失败或者部分失败,client将重新执行3~7步。

分布式系统(二)——GFS的更多相关文章

  1. 分布式系统(二) --SOA 以及一些网络通信协议TCP/UDP SYN攻击

    SOA(面向服务的架构):Service Oriented Architecture面向服务的架构.也就是把工程拆分成服务层.表现层两个工程.服务层中包含业务逻辑,只需要对外提供服务即可.表现层只需要 ...

  2. 【MIT 6.824 】分布式系统 课程笔记(二)Lecture 03 : GFS

    Lecture 03 : GFS 一.一致性 1, 弱一致性 可能会读到旧数据 2, 强一致性 读到的数据都是最新的 3, 一致性比较 强一致性对于app的写方便, 但是性能差 弱一致性有良好的性能, ...

  3. 转:Google论文之二----Google文件系统(GFS)翻译学习

    文章来自于:http://www.cnblogs.com/geekma/archive/2013/06/09/3128372.html 摘要 我们设计并实现了Google文件系统,它是一个可扩展的分布 ...

  4. 分布式系统漫谈一 —— Google三驾马车: GFS,mapreduce,Bigtable

    分布式系统学习必读文章!!!! 原文:http://blog.sina.com.cn/s/blog_4ed630e801000bi3.html 分布式系统漫谈一 —— Google三驾马车: GFS, ...

  5. [分布式系统学习] 6.824 LEC3 GFS 笔记

    Google File System 第三课的准备是阅读论文GFS.该论文是分布式系统中经典论文之一. 读完做一点小总结. GFS的feature 1. 非POXIS接口API,支持对文件和文件夹的创 ...

  6. [分布式系统学习]阅读笔记 Distributed systems for fun and profit 抽象 之二

    本文是阅读 http://book.mixu.net/distsys/abstractions.html 的笔记. 第二章的题目是"Up and down the level of abst ...

  7. 看完这篇,保证让你真正明白:分布式系统的CAP理论、CAP如何三选二

    引言 CAP 理论,相信很多人都听过,它是指: 一个分布式系统最多只能同时满足一致性(Consistency).可用性(Availability)和分区容错性(Partition tolerance) ...

  8. Net分布式系统之二:CentOS系统搭建Nginx负载均衡

    一.关于CentOS系统介绍 CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统)是Linux发行版之一,它是来自于Red Hat ...

  9. Net分布式系统之二:CentOS系统搭建Nginx负载均衡(下)

    上一篇文章介绍了VMWare12虚拟机.Linux(CentOS7)系统安装.部署Nginx1.6.3代理服务做负载均衡.接下来介绍通过Nginx将请求分发到各web应用处理服务. 一.Web应用开发 ...

随机推荐

  1. 日常Java 2021/10/13

    Java枚举 values(), ordinal()和valueOf()方法位于java.lang.Enum类中: values()返回枚举类中所有的值 ordinal()方法可以找到每个枚举常量的索 ...

  2. 深入理解mysql锁与事务隔离级别

    一.锁 1.锁的定义     锁即是一种用来协调多线程或进程并发使用同一共享资源的机制 2.锁的分类 从性能上分类:乐观锁和悲观锁 从数据库操作类型上分类:读锁和写锁 从操作粒度上分类:表锁和行锁 2 ...

  3. Learning Spark中文版--第五章--加载保存数据(2)

    SequenceFiles(序列文件)   SequenceFile是Hadoop的一种由键值对小文件组成的流行的格式.SequenceFIle有同步标记,Spark可以寻找标记点,然后与记录边界重新 ...

  4. 零基础学习java------31---------共享单车案例,html快速入门(常见标签,get和post的区别)

     一 .单车案例 二. HTML快速入门 红字表示要掌握的内容 超文本标记语言,此处的标记指的即是关键字,其用处是用来写页面(展示数据). 语法:(1)./当前目录:../ 父级目录 (2)注释符号: ...

  5. 商业爬虫学习笔记day2

    1. get传参 (1)url中包含中文报错解决方法 urllib.request.quote("包含中文的url", safe = "string.printtable ...

  6. 【bfs】洛谷 P1443 马的遍历

    题目:P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 记录一下第一道ac的bfs,原理是利用队列queue记录下一层的所有点,然后一层一层遍历: 其中: 1.p ...

  7. 100个Shell脚本——【脚本9】统计ip

    [脚本9]统计ip 有一个日志文件,日志片段:如下: 112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com "/ ...

  8. Android 利用Settings.Global属性跨应用定义标志位

    https://blog.csdn.net/ouzhuangzhuang/article/details/82258148 需求 需要在不同应用中定义一个标志位,这里介绍下系统级别的应用和非系统级别应 ...

  9. Shell脚本的条件控制和循环语句

    条件判断:if语句 语法格式: if [ expression ] then Statement(s) to be executed if expression is true fi 注意:expre ...

  10. 应用springMVC时如果配置URL映射时如下配置

    应用springMVC时如果配置URL映射时如下配置 [html] view plaincopy<servlet> <servlet-name>appServlet</s ...