HDFS 高可用和高扩展机制分析 | 青训营笔记

307 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的第9天

1. 元数据高可用

1.1. 高可用的需求

1.1.1. 服务高可用的需求

故障类型

  • 硬件故障
  • 软件故障
  • 人为故障

灾难:数据中心级别不可用

  • 机房断电
  • 机房空调停机
  • 机房间网络故障、拥塞

故障不可避免,灾难时常有发生

而如果HDFS系统不可用

  • 无法核算广告账单,直接引发收入损伤
  • 无法产生数据报表,数据驱动无从谈起
  • 无法进行模型训练,用户体验越来越差

业务停止的损失极大,所以HDFS系统的高可用性就至关重要

1.1.2. 高可用的衡量

image.png

1.1.3. 可用性的年化

image.png

1.1.4. 高可用的形式

服务高可用:

  • 热备份
  • 冷备份

故障恢复操作

  • 人工切换
  • 自动切换

人工的反应、决策时间都更长,高可用需要让系统自动决策

HDFS的设计中,采用了中心化的元数据管理化节点NameNode

NameNode容易成为故障中的单点(single point of failure)

1.2. HDFS主备同步实现

1.2.1. HDFS NameNode高可用架构

组件介绍

  • ActiveNameNode:主节点,提供服务,生产日志
  • StandbyNameNode:备节点,消费日志
  • ZooKeeper:为自动选主提供协调服务
  • BookKeeper:提供日志存储服务
  • ZFKC:NameNode探活,触发主备切换
  • HA Client:提供了自动切换的客户端
  • edit log:操作的日志

围绕三个问题来看高可用

  • 节点状态如何保存
  • 操作日志如何同步
  • 如何做到自动切换

image.png

1.2.2. 理论基础 - 状态机复制和日志

image.png

1.2.3. NameNode 状态持久化

image.png

1.2.4. NameNode 操作日志的生产消费

Active 生产,Standby(可能有多个)消费

物理日志与逻辑日志

日志系统

  • 高可用
  • 高扩展性
  • 高性能
  • 强一致性(有序)

image.png

1.2.5. NameNode 块状态维护

区别

  • Active 即接收,也发起变更
  • Standby 只接收,不发起变更

Content Stale 状态

  • 主备切换后,避免DN的不确定状态

image.png

1.3. HDFS自动主备切换

1.3.1. 分布式协调组件 - ZooKeeper

一般用于提供选主,协调,元数据存储

使用它的组件

  • HDFS 、 YARN 、 HBase
  • Kafka 、 ClickHouse
  • 等等

HA 核心机制:Watch

image.png

1.3.2. 自动主备切换流程 - Server 侧

ZKFailoverController

作为外部组件,驱动HDFS NameNode的主备切换

轮询探活

脑裂问题

Fence 机制

1.3.3. 自动主备切换流程 - Client 侧

核心机制:StandbyException

Client 自动处理

1.4. 日志系统BookKeeper

1.4.1. BookKeeper架构

BookKeeper存储日志

  • 低延时
  • 持久性
  • 强一致性
  • 读写高可用

对比:日志系统和文件系统的复杂度

image.png

1.4.2. Quorum 机制

Quorum 机制:多副本一致性读写

场景:

  • 多副本对象存储,用版本号标识数据新旧

规则

  1. Qr + Qw > Q
  2. Qw > Q / 2

image.png

1.4.3. BookKeeper Quorum

Sloppy Quorum机制

日志场景:顺序追加、只写

Write Quorum:写入副本数 Ack Quorum:响应副本数

image.png

1.4.4. BookKeeper Ensemble

Ensemble 机制

Round-Robin Load Balancer

  • 第一轮:1,2,3
  • 第二轮:2,3,4
  • 第三轮:3,4,1
  • 第四轮:4,1,2

image.png

2. 数据存储高可用

2.1. 单机存储的数据高可用机制

2.1.1. 回到单机存储 - RAID

Redundant Array of Independent Disks

特点

  • 廉价
  • 高性能
  • 大容量
  • 高可用

2.1.2. RAID 方案讲解

RAID 0:条带化

RAID 1:冗余

RAID 3:容错校验

image.png

2.2. HDFS的数据高可用机制

2.2.1. HDFS 多副本

HDFS 版本的RAID 1

优点

  • 读写路径简单
  • 副本修复简单
  • 高可用

image.png

2.2.2. Erasure Coding 原理

HDFS 版本的RAID 2/3

业界常用Reed Solomon算法

image.png

2.2.3. Erasure Coding

HDFS 版本的RAID 2

和多副本比较

  • 读写速度快
  • 成本
  • 修复速度
  • 读写路径的实现

image.png

2.3. 考虑网络架构的数据高可用

2.3.1. 网络架构

机架(Rack):放服务器的架子

TOR(Top of Rack):机架顶部的交换机

数据中心(Data Center):集中部署服务器的场所

image.png

2.3.2. 副本放置策略 - 机架感知

一个TOR故障导致整个机架不可用 vs 降低跨rack流量

trade-off:一个本地、一个远端

image.png

2.4. 案例:字节跳动的HDFS多机房容灾方案介绍

2.4.1. 案例:字节跳动的HDFS多机房容灾实践

字节跳动的HDFS 集群,从单机房演进到双机房,再从双机房演进到更多的机房

多机房解决的问题

  • 容量问题
  • 容灾问题

HDFS 双机房放置的设计

  • 写入时,每个数据块在两个机房至少各有一个副本,数据实时写入到两个机房
  • 读取时,优先读取本地的副本,避免了大量的跨机房读取

image.png

2.4.2. 多机房容灾实践

多机房部署的组件

  • Zookeeper
  • BookKeeper
  • NameNode
  • DataNode

容灾期间的策略

  • 容灾时期,限制跨机房写入
  • 容灾时期,限制跨机房副本复制

3. 元数据高扩展性

3.1. 元数据扩展性挑战

3.1.1. 元数据节点扩展性的挑战

HDFS NameNode是个集中式服务,部署在单个机器上,内存和磁盘的容量、CPU的计算能力都不能无限扩展

scale up vs scale out

  • 扩容单个服务器的能力
  • 部署多个服务器来服务

挑战

  • 名字空间分裂
  • DataNode 汇报
  • 目录树结构本身复杂

image.png

3.1.2. 常见的Scale Out方案

KV 模型的系统可以使用partition

  • Redis
  • Kafka
  • MySQL(分库分表)

三种数据路由方式

  • 服务端测
  • 路由层
  • 客户端侧

image.png

3.2. 社区的解决方案

3.2.1. 社区解决方案 - BlockPool

解决DN同时服务器多组NN的问题

文件服务分层

  • Namespace
  • Block Storage

用blockpool来区分DN的服务

  • 数据块存储
  • 心跳和块上报

image.png

3.2.2. 社区解决方案 - viewfs

Federation架构:将多个不同集群组合起来,对外表现像一个集群一样

viewfs通过在client-side的配置,指定不同的目录访问不同的NameNode

局限性:运维复杂

image.png

3.3. 字节跳动的NNProxy 方案

3.3.1. 字节跳动的NNProxy

NNProxy是ByteDance自研的HDFS代理层,提供了路由服务

NNProxy主要实现了路由管理和RPC转发

  • 以及鉴权、限流、查询缓存等额外能力

image.png

3.3.2. NNProxy 路由规则保存

image.png

3.3.3. NNProxy路由转发实现

路径最长匹配规则

  • /
  • /home
  • /user/bob
  • /user/tiger/warehouse
  • /user/tiger/dump

image.png

3.4. 案例:小文件问题

小文件问题(LSOF,lots of small files):大小不到一个HDFS Block大小的文件过多

  • NameNode瓶颈
  • I/O变小,数据访问变慢
  • 计算任务启动慢

MapReduce的worker数量过多容易引起小文件问题

解决方案

  • 后台任务合并小文件
  • Shuffle Service

image.png

4. 数据存储高扩展性

4.1. 超大集群的长尾问题

4.1.1. 延迟的分布和长尾延迟

image.png

4.1.2. 尾部延迟放大

木桶原理

  • 尾部延迟放大
    • 访问的服务变多,尾部的请求就会越发的慢

image.png

4.1.3. 长尾问题的表现 - 慢节点

image.png

4.2. 超大集群的可靠性问题

4.2.1. 超大集群下的数据可靠性

image.png

4.4.2. Copyset

image.png

4.3. 超大集群的不均匀问题

4.3.1. 超大集群的负载均衡和数据迁移

image.png

4.3.2. 数据写入不均

image.png

4.3.3. DN冷热不均

image.png

4.3.4. 负载均衡和数据迁移的典型场景

image.png

4.4. 数据迁移工具速览

4.4.1. 数据迁移工具 - 跨NN迁移

image.png

4.4.2. 数据迁移工具 - Balencer

image.png