这是我参与「第四届青训营 」笔记创作活动的的第10天
HDFS 高可用和高扩展机制分析
上一文章中,我们了解了HDFS的架构和读写流程。 HDFS通过将文件分块来存储大文件,HDFS的组件有NameNode和DataNode,分别负责提供元数据和数据服务 在读/写数据时,HDFS客户端需要先从NameNode上获取数据读取/写入的DataNode地址,然后和DataNode交互来完成数据读/写。
一个可以用的系统和好用的系统,差距就是高可用和高扩展性
元数据高可用
在大数据运帷中,故障是不可避免,灾难是时有发生的,如果HDFS系统不可用,那么可能无法核算广告账单,直接引发收入损失、无法生产数据报表,数据驱动无从谈起、无法进行模型训练,引起用户体验下滑等。业务停止,带来的损失极大,所以HDFS系统的高可用性就至关重要。
故障类型包括硬件故障、软件故障、人为故障
灾难是指数据中心级别不可用,如:机房断电、机房空调停机、机房网络故障或阻塞
高可用的衡量
服务可用性指标:
- MTTR:多久恢复
- MTTF:故障多长时间
- MTBF:多久一次故障
可用性年化:A = MTBF/(MTBF + MTTR)
比如全年不可用时间:可用性99.9%,全年8.76小时不可用;可用性99.99% ,全年52.6分钟不可用;可用性99.999%,全年5.26分钟不可用

高可用的形式
服务高可用:热备份、冷备份
故障恢复操作:人工切换、自动切换。
人工的反应、决策时间都更长,高可用需要让系统自动决策。HDFS的设计中,采用了中心化的元数据管理节点NameNode.NameNode容易成为故障中的单点(single point of failure)
HDFS NameNode 高可用架构
组件介绍
- ActiveNamenode:主节点,提供服务,生产日志。
- StandbyNamenode:备节点,消费日志
- Zookeeper:为自动选主提供统一协调服务
- BookKeeper: 提供日志存储服务
- ZKFC:NameNode探活、触发主备切换
- HA Client:提供了自动切换的客户端
- edit log:操作的日志
围绕三个问题来看高可用
- 节点状态如何更新
- 操作日志如何同步
- 如何做到自动切换
状态机复制和日志
状态机复制时实现容错的常规方法
组件:状态机以及其副本、变更日志、共识协议
NameNode操作日志的生产消费
目录树和文件信息的更新
Active生产,Standby消费
物理日志与逻辑日志
- 日志系统:高可用、高扩展性、高性能、强一致(有序)

NameNode块状态维护
DataNode向active和standby同时发送Heartbeat和Block Report。active既接收,也发起变更;standby只接收,不发起变更。
Content Stale状态:主备切换后,避免DN的不确定状态。切换后的active不能要求处于此状态的节点删除信息,需等该节点进行完一次block report后解除该状态。

分布式协调组件 -Zookeeper
Zookeeper一般用于提供选主、协调、元数据存储
使用它的组件: HDFS、YARN、HBase Kafka、ClickHouse
HA核心机制:Watch
自动主备切换流程-Server侧
ZKFailoverController作为外部组件,驱动HDFS NameNode的主备切换
- 注册节点,监控节点状态
- 轮询探活:每个ZKFC与一个NameNode绑在一起,探知该NameNode状态
- 脑裂问题:多节点写同一日志,导致数据不一致
- Fence机制:阻止多节点写同一日志

自动主备切换流程-Client侧
核心机制:StandbyException,standby节点收到client请求时,返回standbyException,节点收到该异常后给其他节点发送请求,直到发送给active
Client自动处理
BookKeeper架构
BookKeeper存储日志:
- 低延时
- 持久性
- 强一致性
- 读写高可用
对比:日志系统和文件系统的复杂度

Quorum机制
Quorum机制就是多副本一致性读写,一般应用在多副本对象存储,用版本号标识数据新旧
BookKeeper Quorum
Sloppy Quorum机制,应用在日志场景中,顺序追加、只写
- Write Quorum:写入副本数
- Ack Quorum:响应副本数
BookKeeper Ensemble机制
选择策略
- Round-Robin Load Balancer
- 优势:数据均衡
数据存储高可用
单机存储
RAID ,即Redundant Array of Independent Disks,独立磁盘冗余阵列,具有廉价、高性能、大容量、高可用等特点 RAID有三个方案:RAID 0:条带化、RAID 1:冗余、RAID 3:容错校验

HDFS的数据高可用
HDFS多副本- HDFS版本的RAID 1
多副本放置,同一个块数据放在多个datanode上
优势:使用checksum进行校验、读写路径简单、副本修复简单、高可用

Erasure Coding原理-HDFS版本的RAID 2/3
业界常用Reed Solomon算法

HDFS Erasure Coding - HDFS版本的RAID 2
将数据划分为条带,按照条带保存EC
和多副本比较:读写速度、成本、修复速度、读写路径的实现
网络架构
Server:一台服务器
机架(Rack):放服务器的架子
TOR(Top of Rack):机架顶部的交换机
POD(Point Of Delivery):数据中心中一个物理区域
数据中心(Data Center):集中部署服务器的场所
多机房容灾
多机房解决的问题:容量问题、容灾问题
HDFS双机房放置的设计
- 写入时,每个数据块在两个机房至少各有一个副本,数据实时写入到两个机房
- 读取时,优先读本地的副本,避免了大量的跨机房读取
元数据高扩展性
元数据节点扩展性的挑战
HDFS NameNode是个集中式服务,部署在单个机器上,内存和磁盘的容量、CPU的计算力都不能无限扩展。
scale up:扩容单个服务器的能力
scale out:部署多个服务器来服务
存在挑战:NameSpace分裂、DataNode汇报、目录树结构本身复杂
常见的Scale Out方案
上图的三种数据路由方式:服务器侧、路由侧、客户端侧
KV模型的系统可以使用partition,如:Redis、Kafka、MySQL(分库分表)
存储数据高扩展性
超大集群的长尾问题
延迟的分布一般用百分数来表示访问的延迟的统计特征,例如p95延迟为1ms,代表95%的请求延迟要低于1ms,但后5%的请求延迟会大于1ms
长尾延迟:尾部(p99/p999/p999)的延迟,衡量系统最差的请求的情况。会显著的要差于平均值
木桶原理:尾部延迟放大,即访问的服务变多,尾部的请求就会越发的慢
长尾问题的表现为慢节点,即读取速度过慢,导致客户端阻塞。 慢节点的发生难以避免和预测。如在共享资源、后台维护活动、请求多级排队、功率限制;固定的损耗、机器损坏;混沌现象;下都可能发生慢结点。
离线任务也会遇到长尾问题:全部任务完成时间取决于最慢的任务什么时候完成;集群规模变大,任务的数据量变大;只要任何数据块的读取受到长尾影响,整个任务就会因此停滞
超大集群下的数据可靠性
在超大集群下,有一部分机器是损坏来不及修理的;副本放置策略完全随机;DN的容器足够大的条件下,必然有部分数据全部副本在损坏的机器上,发生数据丢失。且叠加长尾问题,容易导致整个任务无法执行下去。
Copyset方案
将DataNode分为若干个Copyset选块在copyset内部选择,减少了副本放置的组合数,从而降低副本丢失的概率
负载均衡和数据迁移
不均匀问题
- 避免热点
- 降低成本
- 可靠性
- 数据读取/写入不均匀:节点容量不均匀、数据新旧不均匀、访问类型不均匀
- 资源负载不均匀
HDFS作为大数据离线分析场景的核心组件,高可用和高扩展性是架构设计的重中之重,高可用确保了业务能稳定运行,HDFS上存储的数据随时可用访问。高扩展性确保了HDFS能存储的数据流能随着资源投入无限扩展下去,业务发展不被基础组件拖累