zoukankan      html  css  js  c++  java
  • 《大规模分布式存储系统》读书摘记(持续更新)

    3 分布式系统
    3.5 容错
    故障检测:
    • 心跳协议
    • 当机器发生故障时,需要将上面的服务迁移到其他服务器上,为了保证强一致性,需要确保故障机器不再提供服务;
    • 主要问题:正常机器和故障机器之间需要对“故障机器是否应该被认为发生故障而停止服务”达成一致。异步网络中多态机器无法达成一致。
    • 租约:带有超时时间的一种授权。考虑一个提前量。P51
    故障恢复:
    • 分布式存储系统分为:单层结构和双层结构。一般都为单层,每个数据分片维护多个副本;Bigtable为双层,存储和服务分开,服务层只有一个副本。
    • 单层结构系统维护多个副本,贮备副本之间通过操作日志同步。
    • 两层结构系统将所有数据持久化写入底层的共享分布式文件系统,每个数据分片同一时刻只有一个提供服务的节点。
    • 故障检测和故障恢复过程中,不能提供写服务和强一致性读服务。故障检测事件较长,一般为几秒到十几秒,故障恢复时间较短,两层结构故障恢复只是将数据索引加载到内存中,而不是数据。
    • 为了实现高可用性,总控节点也需要一个备机。
     
    3.6 可扩展性
    总控节点:
    • 一般分布式系统中总控节点只需维护数据分片的位置信息,并执行调度,分布式文件系统中还需要维护文件系统目录树,所以内存容量可能会优先成为瓶颈。
    • 如果总控节点成为瓶颈,可以采用两级结构。在总控机与工作机之间增加一层,虽然看似增加了一次网络请求,但是客户端总是能够缓存总控机上的元数据,因此并不会带来额外的开销。
    数据库扩容:
    • 假设数据库中有3张表格,首先根据业务将三张表格垂直拆分到不同的DB中,再将每张表通过哈希的方式水平拆分到不同的存储节点。每个拆分后的DB通过主从复制维护多个副本,且允许分布到多个数据中心。
    • 通常采用双倍扩容,将每个分片拆分为两个分片。
    异构系统:
    • 同构系统:将存储节点分为若干组,每组内的节点服务相同的数据,一个节点为主节点,其余为从节点。这样的系统的问题在于增加副本时要迁移的数据量非常大,时间长,在迁移的过程中很有可能存储节点再次发生故障。所以这样的节点很难做到自动化。
    • 异构系统:每个分片的副本可以分布到集群中的任何一个存储节点。发生故障时,原有的服务有整个集群的存储节点来恢复。由于整个集群参与恢复数据,故恢复时间短,集群越大,效果越明显。
     
    3.7 分布式协议
    两阶段提交协议(2PC):
    • 保证跨多个节点操作的原子性,实现分布式事务
    • 两类节点:协调者(一个),事物参与者(多个)
    • 两个阶段:①请求提交。协调者通知参与者准备提交或者取消事务,然后进入表决过程。在表决阶段,参与者将告知协调者自己的决策(同意或取消)。②当且仅当所有参与者同意提交事务,协调者才通知所有的参与者提交事务,否则通知取消事务。
    • 两阶段提交协议是阻塞协议,执行过程中需要锁住其他更新,且不能容错,大部分分布式系统都敬而远之,放弃对分布式事务的支持。
    • 解决多个节点之间一致性问题(通过操作日志同步数据)
    • 主节点故障,多个备节点提议自己成为主节点,Paxos协议保证所有节点最终达成一致。
    • ........
    Paxos与2PC:
    • Paxos用于保证一个数据分片的多个副本之间的数据一致性(尤其分布在不同的数据中心时)
    • 2PC用于保证多个数据分片的操作的原子性(多态服务器上的操作要么全部成功要么全部失败)
    • Paxos的两种用法:①实现全局的锁服务或者命名和配置服务(Google Chubby以及Apache Zookeeper)②将数据复制到多个数据中心(Google Megastore以及Google Spanner)
    • 2PC与Paxos结合使用:2PC保证多个数据分片上的操作的原子性,Paxos保证一个数据分片的多个副本之间的一致性。Paxos解决2PC协议中协调者宕机的问题,当协调者出现宕机时,Paxos选举出新的协调者继续提供服务
    跨机房部署:
    • 集群整体部署(较常见),每个机房一个总控节点
    • 单个集群跨机房部署,总共一个总控节点
    • Paxos选主副本,总控节点和工作节点不需要保持租约
    4 分布式文件系统
    4.1 Google文件系统
    系统架构:
    • 三种角色:GFS Master(主控服务器)、GFS ChunkServer(CS,数据块服务器)、GFS客户端
    • 客户端(GFS提供给应用程序的访问接口)首先访问主控节点,获取CS信息,然后访问CS获取数据
    • 客户端只缓存元数据,不缓存文件(由GFS应用特点决定)
    关键问题:
    • 租约机制:
      • Master将写chunk通过租约授权给CS,该CS称为主CS,其他副本所在CS为备CS。
      • 如果其中一个chunk备副本下线后又上线,在此过程中主副本有更新,此时Master会删除过期的chunk(通过版本号解决)。
    • 一致性模型:
      • GFS主要设计为追加而不是改写,主要是因为追加的一致性模型相对简单(追加失败只是读到过期数据,而不是错误数据)
      • 多客户端并发追加时可能出现数据被打断,导致数据不连续的问题,即某些数据中夹杂这其他客户端的数据(追求性能导致,由应用层处理这些问题)
    • 追加流程
      • 追加流程请看书
      • 两个特色:流水线(减少延时)和分离数据流、控制流(优化数据传输)
    • 容错机制
      • Master容错:操作日志、检查点、实时热备
      • Master上存储的三种数据:命名空间、文件到chunk的映射、chunk副本的位置
      • Master先操作日志再修改内存
      • Master持久化前两种数据,可以选择不持久化第三种数据,因为chunk副本位置信息在CS上也有保存
      • chunk的所有副本写入成功才算成功
      • CS会对存储的数据维持校验和(chunk以64M为单位,chunk又以64KB为单位划分为Block,每个Block对应一个32位校验和)
      • 读取一个chunk时会比较校验和
    Master设计:
    • Master内存占用:
      • 前两种数据持久化存储,最后一种不持久化,前面说过了
      • 不会成为系统的瓶颈
    • 负载均衡:
      • chunk的所有副本不会放在同一个机架
      • 影响chunk副本创建位置的因素:①新副本所在CS的磁盘利用率低于平均水平;②限制每个CS“最近”创建的数量;③每个chunk的所有副本不能在同一个机架。
      • 以上第二点保证一台刚上线的CS不会因为磁盘利用率低导致大量chunk迁移上来而将它压垮的情况
      • 副本数小于一定数量之后会复制,有一个优先级
      • Master定期扫描副本分布情况,发现磁盘使用量或机器负载不均衡,将执行重新负载均衡操作
      • 限制重新复制和重新负载均衡任务的拷贝速度,以免影响正常读写
    • 垃圾回收
      • 延迟删除
      • Master定期检查,如果删除文件超过一段时间,就把文件从内存元数据中删除,在心跳协议中Master通知CS哪些chunk被删除
    • 快照:
      • 使用写实复制机制生成快照
      • “快照”只增加chunk一个引用计数,修改的时候才复制成新chunk,再对其做修改
      • 步骤:①通过租约机制回收对文件的每个chunk写权限,停止对文件的写服务;②Master拷贝文件名等元数据生成一个新的快照文件;③对执行快照的文件的所有chunk增加引用计数
    ChunkServer设计:
    • 删除chunk时只需要将chunk移动到每个磁盘的回收站,新建chunk时可以重用
    • 磁盘和IO密集型应用,需要将磁盘和网络操作异步化
     
    4.2 Taobao File System(Blob存储系统)
    • 文档、图片、视频一般成为Blob数据,存储Blob数据的系统成为Blob系统,Blob文件系统的特点是写入后基本都是只读,很少出现更新操作。
    • 两个问题:①Metadata信息量过大,无法存储在单台机器上;②减少图片读取的IO次数
    • 设计思路:多个逻辑图片文件共享一个物理文件
    系统架构:
    • 借鉴GFS,但是有很大不同。
    • 不维护文件目录树,每个小文件用64位编号表示;由于读多写少,可以将写流程做的更加简单有效
    • 一个集群两个NameServer(一主一备)、多个DataServer,NS通过心跳对DS监测。
    • 每个DS上有多个dsp进程,每个dsp对应一个挂载点,一个挂载点对一个独立磁盘
    • 大量小文件合并成一个大文件(64M的Block),并有唯一ID,默认存储三份
    • 应用客户端不缓存文件数据,只缓存NS元数据
    • 追加流程:
      • TFS读多写少,及时每次写操作都经过NS也不会出现问题
      • 不支持多客户端写,同一时刻每个Block只能有一个写操作,多个客户端的写操作会被串行化
      • TFS写流程不够优化:①每个写请求都需要多次访问NS;②数据推送没有采用流水线方式减少延迟
    讨论:
    • 通过Tair进行对图片去重。采用hash算法为图片文件计算指纹,图片写入之前在Tair中查找是否存在指纹,写入以后需要将指纹以及在TFS中的位置信息保存到去重系统(Tair)中
    • 图片在TFS中的位置通过<Block id, File id>来标识
     
    4.3 Fackbook Haystack
    系统架构:
    • 设计思路:多个逻辑文件共享一个物理文件(和TFS类似)
    • 三部分:目录(逻辑卷着和物理卷轴的对应关系、照片id到逻辑卷着之间的映射关系)、存储(以一个很大的物理卷轴为单位,多个存储节点上的物理卷轴组成一个逻辑卷轴)、缓存(解决对CDN过于依赖的问题)
    • Haystack缓存只缓存用户浏览器发送的请求且要求请求的Haystack存储节点是可写的
    • 写流程:
      • 请求Haystack目录获取逻辑卷轴 -> 生成照片唯一id将数据写入每一个对应的物理卷轴(每一个物理卷轴都要成功)
      • 只支持追加操作,更新照片时增加一张编号相同的照片到系统中,若逻辑卷轴和原来的不同,则在目录中修改成最新的逻辑卷着,若逻辑卷轴相同,以偏移大的照片文件为准
    • 容错处理:
      • 存储节点出错时,所有物理卷轴对应的逻辑卷轴标记为只读;未完成写操作全部失败;若故障不可恢复,需要进行拷贝(小时级别)
      • 目录有贮备数据库做持久化储存,由主备数据库提供容错机制
    • Haystack目录功能:
      • ①提供逻辑卷轴到物理卷轴的映射,维护照片id到逻辑卷轴的映射;
      • ②提供负载均衡;
      • ③屏蔽CDN服务;
      • ④标记某些逻辑卷轴为只读
    5 分布式键值系统
    5.1 Amazon Dynamo
    • 存储原始数据,不解析数据的具体内容
    • Dynamo设计时面临的问题及最终的解决方案:
      • 数据分布                   :   改进的一致性哈希(虚拟节点)
      • 复制协议                   :   复制写协议
      • 数据冲突处理            :   向量时钟
      • 临时故障处理            :   数据回传机制
      • 永久故障后的恢复     :   Merkle哈希树
      • 成员资格及错误检测  :   基于Gossip的成员资格和错误检测协议
    数据分布:
    • 采用改进的一致性哈希算法将数据分布到多个存储节点中
    • Dynamo中每个节点维护整个集群的信息,客户端也缓存整个集群的信息
    • 为保证每个节点缓存最新的成员信息,所有节点周期性通过Gossip协议从其他节点任意选择一个与之通信的节点,连接成功后交换集群信息
    • Gossip协议的执行过程请看书(P87)
    • 种子节点
    一致性与复制:
    • 思路:假设数据存储N份,DHT(一致性哈希表)定位到的数据所属节点为K,则数据存储在节点K、K+1、....、K+N-1上。如果第K+i(0<=i<=N-1)台机器宕机,则往后找一台机器K+N临时替代;如果第K+i台机器重启,则数据回传;若永久失效,机器K+N需要进行数据同步操作(Merkle树)
    • NWR:N表示复制的备份数,R表示成功读操作的最少节点数,W表示成功写操作的最少节点数
    • 当W+R>N时,就能保证当存在不超过一台机器故障的时候,至少能够读到一份有效数据
    • 向量时钟用[nodes,counter]对表示,nodes表示节点,counter表示初始为0的计数器,更新一次加1(P89)
    • Dynamo只保证最终一致性,如果多个节点之间的更新顺序不一致,客户端可能读取不到期望的结果
    容错:
    • 数据回传(临时故障)
    • Merkle树同步(永久故障):Merkle树非叶子节点对应多个文件(子节点值组合后的哈希值),叶子节点对应单个文件(文件内容的哈希值)
    • 读取修复(NWR)
    负载均衡:
    • 随机分配。效果不错,但可控性比较差
    • 数据范围等分+随机分配
    读写流程:
    • 写数据:
      • 根据一致性哈希计算出存储节点,选择一个副本作为本次写的协调者
      • 并发的往所有副本发送写请求,每个副本将接收到的数据写入本地
      • 副本写入成功后回复协调者
      • 若写入失败,协调者会将它加入重试列表不断重试
      • 所有协调者写入成功后,协调者回复客户端写入成功
    • 读数据:
      • 根据一致性哈希选择存储节点,选择一个副本作为本次读的协调者
      • 协调者根据并发策略选择R个副本,并发发送读请求
      • 当所有副本都读取成功时,协调者回复客户端
      • 两种情况:数据一致和数据不一致
  • 相关阅读:
    大数据处理系列之(二)系统过载保护
    大数据处理系列之(一)Java线程池使用
    js实现递归菜单无限层
    treeTable实现排序
    spring-dm 一个简单的实例
    Equinox OSGi服务器应用程序的配置步骤 (支持JSP页面)
    Spring DM 2.0 环境配置 解决Log4j问题
    Spring.DM web开发环境搭建
    STL容器的排序
    排序例子
  • 原文地址:https://www.cnblogs.com/big-xuyue/p/4107417.html
Copyright © 2011-2022 走看看