这是我参与「第四届青训营 」笔记创作活动的第5天。
今日内容:#HDFS高可用高扩展机制分析
学习目标:了解HDFS高可用、高扩展机制。
一、课前预习
1.Quorum机制
Quorum 的定义如下:假设有 N 个副本,更新操作 wi 在 W 个副本中更新成功之后,则认为此次更新操作 wi 成功,把这次成功提交的更新操作对应的数据叫做:“成功提交的数据”。
对于读操作而言,至少需要读 R 个副本,其中,W+R>N ,即 W 和 R 有重叠,一般,W+R=N+1。
N = 存储数据副本的数量
W = 更新成功所需的副本
R = 一次数据对象读取要访问的副本的数量
2.路径前缀匹配
例如:找出一个字符串集合中所有以ab开头的字符串。我们只需要用所有字符串构造一个trie树,然后输出以a->b->开头的路径上的关键字即可。
trie树前缀匹配常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。
3.复制状态机
在分布式系统中是一个很简单却很强大的模型,也是一种很有价值的思想。
多个节点上,从相同的初始状态开始,执行相同的一串命令,产生相同的最终状态。
实现容错服务的一种常规方法,主要通过复制服务器,并协调客户端和这些服务器镜像间的交互来达到目标。
二、课中笔记
1.元数据高可用
1.1需求
HDFS Client 属于是胖客户端(fat/rich client),客户端中实现了数据读写的容错等较为复杂的逻辑。
HDFS 的读写路径
数据读取:Client 从 NN 上获取到文件信息和块的位置(getFileInfo+getBlockLocation),从对应 DN 上读取数据。当一个 DN 读取失败时,会去尝试块的其他 DN。
数据写入:Client 要求 NN 创建文件(create),并依次获得不同的 DN 来写入数据块(addBlock)。Client 通过链式写入来同时写入数据到多个 DN。在整个写入完成后,会让 NN 关闭文件(complete)。
高可用:系统在困境(adversity,比如硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并达到期望性能)
容灾:
在相隔较远的异地,建立两套或多套功能相同的系统,互相监视和功能切换,当一处系统因意外(如火灾、地震等)停止工作时,可以切换到另一处。
1.2高可用衡量
MTTR(Mean Time To Repair):平均修复时间。
MTTF(Mean Time To Failure):平均失效时间,运行到故障间的时间,用于不可修复的系统(制造业)。
MTBF(Mean Time Between Failures):平均无故障时间,两次故障间的间隔,用于可修复的系统(软件)。
全年不可用时间(99.9/99.99/99.999%)
1.3高可用形式
冷备份:备份服务的数据,可以和数据归档相结合。在主服务故障时,利用备份的数据重启。
热备份:主服务和备服务同时运行,在主服务故障时,切换到备服务。
切换方式:
人工切换、自动切换:(探活组件、分布式共识协议等手段)
2.高可用架构
2.1
Active NameNode:提供服务的 NameNode 主节点,生产 editlog。 Standby NameNode:不提供服务,起备份作用的 NameNode 备节点,消费 editlog editlog:全局顺序,操作日志。
ZooKeeper:开源的分布式协调组件,主要功能有节点注册、主节点选举、元数据存储。 BookKeeper:开源的日志存储组件,存储 editlog
ZKFC:和 ZK、NN 通信,进行 NN 探活和自动主备切换。
HA Client:处理 StandbyException,在主备节点间挑选到提供服务的主节点。
2.2理论
状态机复制模型:实现容错服务的一种常规方法,主要通过复制服务器,并协调客户端和这些服务器镜像间的交互来达到目标。这个方法也同时提供了理解和设计复制管理协议的一套基本框架。
状态机:一个状态机从“初始”状态开始,每一个输入都被传入转换函数和输出函数,以生成一个新的状态和输出。在新的输入被接收到前,状态保持不变,而输出同时被传输给恰当的接受者。
状态机复制:确定性的状态机具有「处理确定的输入后,状态唯一确定」的特性。状态机复制利用这个特性实现多个相同的状态机副本的同步更新。
变更日志:触发状态机更新的变更操作,具有全局确定的顺序。
共识协议:确保每个副本都能收到相同的日志的共识协议,常见的有 Paxos、Raft、ZAB。
checkpoint 机制:将旧的 FSImage 和 EditLog 合并生成新的 FSImage 的流程,在完成后旧的数据可以被清理以释放空间。
2.2操作日志生产消费
物理日志:存储了物理单元变更的日志。(Inode10000,9999)
逻辑日志:存储了逻辑变更(例如 rename /a to /b)的日志。
2.3NameNode块状态维护
Content Stale状态:主备切换后,避免DN不确定状态
HDFS 主备切换:
content stale 状态:在发生主备切换后,新 active NN 会标记所有 DN 为 content stale 状态,代表副本不确定,某些操作不能执行。直到一个 DN 完成一次全量块上报,新 active NN 才标记它退出了 content stale 状态。
ZooKeeper 是广泛使用的选主组件,它通过 ZAB 协议保证了多个 ZK Server 的状态一致,提供了自身的强一致和高可用。
访问单位是znode, client 可以创建临时 znode,临时 znode 在 client 心跳过期后自动被删除。
ZK 核心功能:
Watch,允许多个 client 一起监听znode 的状态变更,并在状态变化时收到一条通知消息(callback)。
Server侧主备切换
ZKFC(failoerController)驱动主备切换。查询 NN 存活和状态、进行 ZK 侧主备选举、执行调用 NN 接口执行集群的主备状态切换、执行 fence 等能力
脑裂问题:因为网络隔离、进程夯住(例如 Java GC)等原因,旧的 active NN 没有完成下主,新的 active NN 就已经上主,此时会存在双主。client 的请求发给两者都可能成功,但不能保证一致性(两个 NN 状态不再同步)和持久化(只能保留一个 NN 状态)。
fence 机制:在新 active NN 上主并正式处理请求之前,先要确保旧 active NN 已经退出主节点的状态。一般做法是先用 RPC 状态检测,发现超时或失败则调用系统命令杀死旧 active NN 的进程。
Client侧主备切换
核心机制:StandbyException
基于临时 znode 和 Watch 机制,多个客户端可以完成自动的主选举。
Hadoop 将集群主备选举的能力和 NN 的服务放在了不同的进程中,而更先进的系统一般会内置在服务进程中。
2.4高可用日志系统 BookKeeper
高可靠:数据写入多个存储节点,防丢失。
高可用:日志存储本身是高可用的。因为日志流比文件系统本身的结构更为简单,日志系统高可用的实现也更为简单。
强一致:追加写入的形式,Client 和日志系统的元数据可以明确目前已经成功的写入日志的序号(entry-id)。
可扩展:整个集群的读写能力可以随着添加存储节点 Bookie 而扩展。
Quorum 协议
基于鸽巢原理,在多个副本间确保高可用、高性能的多副本变更协议
多副本间一般通过 version-id 来描述状态的新旧。
高可用:多个副本确保了高可用(后文会再次介绍多副本高可用)。
高性能:不用等所有副本写入成功,降低了的长尾延迟(后文会再次介绍长尾延迟)。
日志写入是追加,不变更,只需要确认目前的 entry-id。
Write Quorum:一次写入需要写入到的存储节点数。
Ack Quorum:一次写入需要收到的响应数,小于 write quorum。
高性能:不用等所有副本写入成功,降低了的长尾延迟(后文会再次介绍长尾延迟)。
Ensemble:通过轮询(Round-Robin)来确认 write quorum 实际对应的存储节点实例,可以比较简单的完成副本放置和扩展。
2.数据存储高可用
2.1回到单机存储
RAID:将多个廉价、不可靠、低性能、容量小的磁盘组装在一起,提供高可靠、高性能、大容量逻辑磁盘服务。
三种raid方案
RAID 0: 条带化形式分别存储,提供大容量、高性能。
RAID 1:副本存储在多个磁盘上。冗余机制。
RAID 3:分块存储的基础上,将校验码存储在独立的磁盘上。容错校验。
2.2多副本方案、容错
数据块存储在多个 DN 上。
Erasure Coding :
将数据分段,通过特殊的编码方式存储额外的校验块,并条带化的组成块,存储在 DN 上。
读写简单,修复简单,高可用。
条带化:
连续的数据按条带(远小于整个块的单位)间隔交错的分布在不同的块中。(需要的数据小,就可以不受其他数据影响不可读。修复优势。需要大的时候,可以拼接。)
业界常用Reed Solomon 算法。
成本更低:多副本方案需要冗余存储整个块,EC 方案需要冗余存储的数据一般更少。
2.3网络架构
机架/机柜:将几个服务器统一供电、提供对外网络的固定的物理设备。
TOR top of rack:机架顶部(或底部)的交换机,负责机架内服务器和数据中心的其他服务器的网络通信。
机房和数据中心:大量服务器集中放置的场所。
机房:基础设施建设,例如物理承重、空调、防水、消防。
数据中心:强调机房的业务属性。
网络拓扑:按数据中心->机架->机器的顺序,描述进程在网络空间中所处的位置。
跨机房专线:
由网络服务商提供,连接机房的专用网络。
稳定性和安全性好于公网。
相比于数据中心内网络,吞吐更为有限、延迟更高、成本更高。
故障域
基础设施中可能发生故障的区域或组件。每一个域都有自己的风险和挑战,由个别几个因素决定整个故障域的服务能力,需要进行架构。
机架感知
以 TOR 为关键点,机架是一个故障域。数据副本全部放置在一个机架中,当相应 TOR 故障时数据就无法访问。
机房感知
以机房的基础设施(空调、电力)和跨机房专线为关键点,它们发生故障时整个机房会发生故障,导致不可用。
多机房解决容量、容灾问题。读取优先本地。
3.元数据高扩展性
3.1扩展性方案
scale up:通过单机能力提升来提升系统服务能力,受到机器成本和物理定律的限制。
scale out:通过部署多台机器,一般也称为高扩展、水平扩展。
Kv模型:使用partition 方法。
水平分区和垂直分区:水平分区指按 key 来将数据划分到不同的存储上;垂直分区指将一份数据的不同部分拆开存储,用 key 关联起来。partition 一般都水平分区,又称 shard。
federation 架构
使得多个集群像一个集群一样提供服务的架构方法,提供了统一的服务视图,提高了服务的扩展性。
3.2社区解决方案
blockpool
将文件系统分为文件层和块存储层,对于块存储层,DN 集群对不同的 NN 提供不同的标识符,称为 block pool。
viewfs
邦联架构的一种实现,通过客户端配置决定某个路径的访问要发送给哪个 NN 集群。
缺点:客户端配置难以更新、本身配置方式存在设计。
3.3NNProxy
字节自研的 HDFS 代理层。
3.4小文件问题
HDFS 设计上是面向大文件的,小于一个 HDFS Block 的文件称为小文件。
元数据问题:多个小文件相对于一个大文件,使用了更多元数据服务的内存空间。
数据访问问题:多个小文件相对于一个大文件,I/O 更加的随机,无法顺序扫描磁盘。
计算任务启动慢:计算任务在启动时,一般会获得所有文件的地址来进行 MapReduce 的任务分配,小文件会使得这一流程变长。
典型的 MR 流程中,中间数据的文件数和数据量与 mapper*reducer 的数量成线性,而为了扩展性,一般 mapper 和 reducer 的数量和数据量成线性。于是,中间数据的文件数和数据量与原始的数据量成平方关系。
小文件合并任务:计算框架的数据访问模式确定,可以直接将小文件合并成大文件而任务读取不受影响。通过后台运行任务来合并小文件,可以有效缓解小文件问题。通过 MapReduce/Spark 框架,可以利用起大量的机器来进行小文件合并任务。