这是我参与【第四届青训营】笔记创作活动的第5天
HDFS的高可用和高扩展性|青训营笔记
一、元数据服务高可用
1.1高可用的衡量
1.2 HDFS NameNode高可用架构
- ActiveNamenode: 主节点,提供服务,生产日志
- StandbyNamenode:备节点,消费日志
- ZooKeeper:为自动选主提供统一协调服务
- BookKeeper: 提供日志存储服务
- ZKFC: 提供自动切换的客户端
- HA Clinet : 操作日志
理论基础-状态机复制和日志
状态机复制是实现容错的常规方法
组件:
状态机以及其副本
变更日志
共识协议
NameNode状态持久化
NameNode操作日志的生产消费
Active生产,Standby(可能有多个)消费
物理日志:存储了物理单元(一般是磁盘的page)变更的日志形式
逻辑日志: 存储了逻辑变更(如rename/a to /b)的日志形式
日志系统:高可用 高扩展性 高性能 强一致性(有序)
1.4 HDFS 主备切换
- DataNode 心跳与块汇报需要同时向 active NN 和 standby NN 上报,让两者可以同时维护块信息。但只有 active NN 会下发 DN 的副本操作命令。
- content stale 状态:在发生主备切换后,新 active NN 会标记所有 DN 为 content stale 状态,代表该 DN 上的副本是不确定的,某些操作不能执行。直到一个 DN 完成一次全量块上报,新 active NN 才标记它退出了 content stale 状态。
- 脑裂问题: 由于网络隔离、进程夯筑(GC问题)等原因,旧的active NN没有完成下主,新的active NN就已经上主,此时会存在双主。此时会存在双主,client的请求发送给两者都可能成功,但不能保证一致性(两个NN状态不再同步)和持久化(只能保留一个NN状态)。
- fence机制:在新active NN上主并正式处理请求之前,先要确保旧active NN已退出主节点的状态。一般使用RPC状态检测,发现超时或失败则调用系统命令杀死旧active NN的进程。
自动主备切换 - ZooKeeper 是广泛使用的选主组件,它通过 ZAB 协议保证了多个 ZK Server 的状态一致,提供了自身的强一致和高可用。
- ZooKeeper 的访问状态是znoe,可以确保znode创建的原子性和互斥性。 client可以创建零食znode, 临时znode在client心跳过期后自动被删除。
- ZK提供Watch机制,允许多个client一起监听一个znode的状态变更,并在状态变化时收到消息回调
- 基于临时 znode 和 Watch 机制,多个客户端可以完成自动的主选举
- ZKFailoverController:一般和 NN 部署在一起的进程,负责定时查询 NN 存活和状态、进行 ZK 侧主备选举、执行调用 NN 接口执行集群的主备状态切换、执行 fence 等能力。
- Hadoop 将集群主备选举的能力和 NN 的服务放在了不同的进程中,而更先进的系统一般会内置在服务进程中。
高可用日志系统 BookKeeper - 高可靠:数据写入多个存储节点,数据写入就不会丢失
- 高可用:日志存储本身是高可用的。因为日志流比文件系统本身的结构更为简单,日志系统高可用的实现也更为简单。
- 强一致:日志系统是追加写入的形式,Client 和日志系统的元数据可以明确目前已经成功的写入日志的序号(entry-id)。
- 可扩展:整个集群的读写能力可以随着添加存储节点 Bookie 而扩展。
BookKeeper Quorum 协议(基于鸽巢原理,在多个副本间确保高可用、高性能的多副本变更协议) - 日志写入是追加,不是状态变更,只需要确认目前的 entry-id,相对更简单。
- Write Quorum:一次写入需要写入到的存储节点数
- Ack Quorum:一次写入需要收到的响应数,小于 write quorum。
- 高性能:不用等所有副本写入成功,降低了的长尾延迟(后文会再次介绍长尾延迟)。
- Ensemble:通过轮询(Round-Robin)来确认 write quorum 实际对应的存储节点实
二、数据存储高可用
2.1 单机存储的数据高可用机制
回到单机存储-RAID
提供RAID功能的NAS设备
RAID:将多个廉价、不可靠、低性能、容量小的磁盘组装到一起,提供可靠、高性能、大容量逻辑磁盘服务的一组磁盘列阵方案
- RAID 0:将数据分块后按条带化的形式分别存储在多个磁盘,提供大容量、高性能。
- RAID 1:将数据副本存储在多个磁盘,提高可靠
- RAID 3:将数据分块存储的基础上,将数据校验码存储在独立的磁盘上,提高高可靠、高性能。 多副本方案:将数据存储在多个DN上
Exasure Coding方案:将数据分段,通过特殊的编码方式存储额外的校验快, 并条带化的组成结构,存储在DN上
- 条带化:原来块对应文件内连续的一大段数据。条带化后,连续的数据按条带(远小于块的单位)间隔交叉的分布在不同的块中
- 成本更低:多副本方案需要冗余存储整个块,EC方案需要冗余存储的数据一般更少
HDFS多副本
优点: - 读写路径简单
- 副本修改简单
- 高可用
2.2 HDFS的数据高可用机制
2.3 考虑网络架构的数据高可用
2.4 HDFS多机房容灾方案简介
多机场部署的部件
- ZooKeeper
- BookKeeper
- NameNode
- DataNode
容灾期间的策略 - 容灾期间,限制跨机房写入
- 容灾期间,限制跨机房副本复制
三、元数据高扩展性
3.1 元数据扩展性挑战
HDFS NameNode是集成式服务,部署在单个机器上,内存和磁盘容量、CPU的计算力都不能无线扩展
挑战
- 名字空间分裂
- DataNode汇报
- 目录树结构本身复杂
扩展性方案 - scale up:通过单机的 CPU、内存、磁盘、网卡能力的提升来提升系统服务能力,受到机器成本和物理定律的限制。
- scale out:通过让多台机器组成集群,共同对外提供服务来提升系统服务能力。一般也称为高扩展、水平扩展。
常见的Scale Out方案 - 水平分区和垂直分区:水平分区指按照key来将数据划分到不同的存储上;垂直分区指将一份数据的不同部分拆开存储,用key关联起来。partition一般都水平划分,又称shard。
- 常用于 KV 模型,通过 hash 或者分段的手段,将不同类型 key 的访问、存储能力分配到不同的服务器上,实现了 scale out。
- 重点:不同单元之间不能有关联和依赖,不然访问就难以在一个节点内完成。例如 MySQL 的分库分表方案,难以应对复杂跨库 join。 KV模型的系统可以使用partition
- Redis
- Kafka
- MySQL(分库分表)
federation 架构 - 使得多个集群像一个集群一样提供服务的架构方法,提供了统一的服务视图,提高了服务的扩展性。
- 文件系统的目录树比 kv 模型更复杂,划分更困难。
- 邦联架构的难点一般在于跨多个集群的请求 BlockPool
- 将文件系统分为文件层和块存储层,对于块存储层,DN 集群对不同的 NN 提供不同的标识符,称为 block pool。
- 解决了多个 NN 可能生成同一个 block id,DN 无法区分的问题
viewfs - 邦联架构的一种实现,通过客户端配置决定某个路径的访问要发送给哪个 NN 集群。
- 缺点:客户端配置难以更新、本身配置方式存在设计(例如,只能在同一级目录区分;已经划分的子树不能再划分)。
NNProxy - ByteDance 自研的 HDFS 代理层,于 2016 年开源,项目地址: github.com/bytedance/n…
- 主要提供了路由管理、RPC 转发,额外提供了鉴权、限流、查询缓存等能力。