这是我参与「第四届青训营 」笔记创作活动的第9天
HDFS 高可用与高扩展性机制分析
元数据高可用
高可用的需求
服务高可用的需求
-
故障类型:
- 硬件故障
- 软件故障
- 人为故障
-
灾难:数据中心级别不可用
- 机房断电
- 机房空调停机
- 机房间网络故障、拥塞
-
如果HDFS 系统不可用:
- 无法核算广告账单,直接引发收入损失
- 无法生产数据报表,数据驱动无从谈起
- 无法进行模型训练,引起用户体验下滑
业务停止的损失极大,所以HDFS 系统的高可用性就至关重要
高可用的衡量
- 服务可用指标:
- MTTR:发现一次故障需要多久恢复
- MTTF:平均一次故障花费多少时间
- MTBF:多久会有一次故障
可用性的年化
-
可用性:
A = MTBF/(MTBF + MTTR) -
不可用时间:
- 可用性 99.9%,全年8.76 小时不可用
- 可用性 99.99%,全年52.6分钟不可用
- 可用性 99.999%,全年5.26分钟不可用
高可用的形式
- 服务高可用:
- 热备份:有一个相同服务跑着
- 冷备份:将关键数据备份,将备份在其他服务上重启
- 故障恢复操作
- 人工切换
- 自动切换 HDFS的设计中,采用了中心化的元数据管理节点NameNode,容易成为故障中的单点
HDFS 主备同步实现
HDFS NameNode 高可用架构
-
组件介绍:
- ActiveNamenode:主节点,提供服务,生产日志
- StandbyNamenode:备节点,消费日志
- ZooKeeper:为自动选主提供统一协调服务
- BookKeeper:提供日志存储服务
- ZKFC:NameNode探活、触发主备切换
- HA Client:提供了自动切换的客户端
- edit log:操作的日志
-
围统三个问题来看高可用:
- 节点状态如何更新
- 操作日志如何同步
- 如何做到自动切换
理论基础-状态机复制和日志
状态机复制时实现容错的常规方法
- 组件
- 状态机以及其副本
- 变更日志
- 共识协议
NameNode状态持久化
FSImage和EditLog:
FSImage:整个目录树,各个节点,各个节点的子节点,父节点是那些Checkpoint机制:
NameNode 操作日志的生产消费
日志:目录树和文件信息的更新
Active 生产 Standby消费
-
物理日志与逻辑日志
- 逻辑日志:-A-B到-A-C
-
日志系统:
- 高可用
- 高扩展性
- 高性能
- 强一致(有序)
NameNode 块状态维护
-
回顾
- DataNode Heartbeat 心跳
- DataNode Block Report
-
区别
- Active 即接收,也发起变更(发起相应处理)
- Standby 只接收,不发起变更
-
Content Stale 状态
- 主备切换后,避免DN的不确定状态
HDFS 自动主备切换
分布式协调组件-ZooKeeper
一般用于提供选主、协调、元数据存储
-
使用它的组件:
- HDFS、 YARN. HBase
- Kafka. ClickHouse等
-
HA核心机制:Watch
自动主备切换流程 - Server 侧
ZKFailoverController: 作为外部组件,驱动HDFS NameNode 的主备切换
- 注册节点,监控节点状态
- 监控部署在一起的NameNode的状态
轮询探活
脑裂问题
Fence 机制
自动主备切换流程 - Client 侧
核心机制:StandbyException 会存一组DataNode地址
Client自动处理
日志系统 BookKeeper简介
BookKeeper架构
- BookKeeper存储日志
- 低延时
- 持久性
- 强一致性
- 读写高可用
- 对比:日志系统和文件系统的复杂度
Quorum 机制
-
Quorum 机制:多副本一致性读写
-
场景:
- 多副本对象存储,用版本号标识数据新旧
-
规则:
- 1.Q.+Qw >Q
- 2.Qw >Q/2
-
思考:日志场景比对象保存更简单
BookKeeper Quorum
-
Sloppy Quorum 机制
-
日志场景:顺序追加、只写
-
Wnte Quorum:写入副本数
-
Ack Quorum:响应副本数
BookKeeper Ensemble
Ensemble 机制
-
Round-Robin Load Balancer
- 第一轮 :1.2.3
- 第二轮:2,3.4
- 第三轮:3,4,1
- 第四轮:4,1,2
-
优势:数据均衡
数据存储高可用
单机存储的数据高可用机制
回到单机存储-RAID
- Redundant Array of Independent Disks
RAID 方案讲解
- RAID 0:条带化
- RAID 1:冗余
- RAID 3:容错校验
HDFS 的数据高可用机制
HDFS多副本:
HDFS 版本的RAID 1
图:Hadoop的多副本放置
- 优点:
- 读写路径简单
- 副本修复简单
- 高可用
Erasure Coding 原理
DFS 版本的RAID 2/3
业界常用Reed Solomon算法
图: Reed Solomon 算法原理
HDFS Erasure Coding
HDFS 版本的RAID 2(条带化)
图:直接保存的EC和Stripe(条带化)后保存的EC
- 和多副本比较:
- 读写速度
- 成本
- 修复速度
- 读写路径的实现
考虑网络架构的数据高可用
网络架构
- Server:一台服务器
- 机架(Rack):放服务器的架子。
- TOR(Top of Rack):机架顶部的交换机。
- POD(Point of Delivery):数据中心中的一个物理区域
- 数据中心(Data Center):集中部署服务器的场所
副本放置策略-机架感知
一个TOR 故障导致整个机架不可用
VS
降低跨rack流量
trade-off:一个本地、一个远端
图:HDFS的多机架放置
案例:字节跳动的 HDFS 多机房容灾方案简介
字节跳动的 HDFS 集群 从单机房演进到双机房,再从双机房演进到更多的机房。
-
多机房解决的问题
- 容量问题
- 容灾问题
-
HDFS 双机房放置的设计
- 写入时,每个数据块在两个机房至少各有一个副本,数据实时写入到两个机房。
- 读取时,优先读本地的副本,避免了大量的跨机房读取
-
多机房部署的组件:
- ZooKeeper
- BookKeeper
- NameNode
- DataNode
-
容灾期间的策略:
- 容灾期间,限制跨机房写入
- 容灾期间,限制跨机房副本复制
元数据高扩展性
元数据扩展性挑战
元数据节点扩展性挑战
HDFS NameNode 是个集中式服务,部署在单个机器上,内存和磁盘的容量、CPU 的计算力都不能无限扩展。
-
scale up vs. scale out
- 扩容单个服务器的能力
- 部署多个服务器来服务
-
挑战
- 名字空间分裂
- DataNode 汇报
- 目录树结构本身复杂
常见的 Scale Out 方案
-
KV模型的系统可以使用 partition
- Redis
- Kafka
- MySQL(分库分表)
-
右图:三种数据路由方式
- 服务端侧
- 路由层
- 客户端侧
社区的解决方案
社区解决方案-BlockPool
解决DN同时服务多组NN的问题
-
文件服务分层:
- Namespace
- Block Storage
-
用blockpool来区分DN的服务
- 数据块存储
- 心跳和块上报
社区解决方案-viewfs
Federation架构:将多个不同集群组合起来,对外表现像一个集群一样。
右图:viewfs 通过在 client-side的配置,指定不同的目录访问不同的NameNode。
局限性:运维复杂
字节跳动的 NNProxy 方案
字节跳动的 NNProxy
NNProxy是 ByteDance 自研的HDFS代题层提供了路由服务 NNProxy主要实现了路由管理和RPC转发
以及鉴权、限流、查询缓存等额外能力
图: NNProxy所在系统上下游
NNProxy 路由规则保护
考虑点:扩展性、运维性
图:路由规则的保存
案例:小文件问题
-
小文件问题(LSOF lots of small files ):大小不到一个HDFS Block 大小的文件过多
- NameNode 瓶颈
- I/O变成小的随机IO,数据访问变慢
- 计算任务启动慢
图:MapReduce的 worker 数量过多容易引起小文件问题
-
解决方案:
- 后台任务合并小文件
- Shuffle Service
数据存储高扩展性
超大集群的长尾问题
延迟的分布和长尾延迟
延迟的分布:
用百分数来表示访问的延迟的统计特征 例如p95延迟为 1ms,代表95%的请求延迟要低于1ms 但后5%的请求延迟会大于1ms
长尾延迟:尾部(p99/p999/p999)的延迟,衡量系统最差的请求的情况。 会显著的要差于平均值
尾部延迟变大
木桶原理
长尾问题的表现-慢节点
慢节点:读取速度过慢,导数客户端阻塞
集群扩大 10倍,问题扩大N(>10)倍
超大集群的可靠性问题
超大集群下的数据可靠性
必然有部分数据全部副本在损坏的机器上,发生数据丢失
Copyset
将DataNode 分为若干个Copyset 选块在 copyset 内部选择
原理:减少了副本放置的组合数,从而降低副本丢失的概率。
缺陷:一个Copyset挂掉,所有的数据丢失
超大集群的不均匀问题
数据迁移工具速览
-
跨NN迁移
- DistCopy
- FastCopy
-
Balancer
总结:
HDFS 作为大数据离线分析场景的核心组件,高可用和高扩展性是架构设计的重中之重。
高可用确保了业务能稳定运行,HDFS 上存储的数据随时可以访问。
高扩展性确保了 HDFS 能存储的数据量能随着资源投入无限扩展下去,业务发展不被基础组件拖累。
字节跳动 HDFS 依然在持续迭代,在元数据扩展性、数据治理与调度、数据生态体系、单机存储引擎、云上存储等方向依然大有可为。