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

125 阅读10分钟

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

一、元数据高可用。

1.服务高可用的需求:
  • 故障类型:
    • 硬件故障
    • 软件故障
    • 人为故障
  • 灾难:数据中心级别不可用
    • 机房断电
    • 机房空调停机
    • 机房间网络故障、拥塞

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

而如果HDFS 系统不可用。

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

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

1.2高可用的衡量:

  • 服务可用指标:
    • MTTR
    • MTTF
    • MTBF

bb00bdf30b657b4d559acd917906766.jpg 1.3可用性的年化:

可用性:

b51f7ea8adce357a90872af9d303d68.jpg 全年不可用时间:

  • 可用性 99.9%,全年8.76 小时不可用
  • 可用性 99.99%,全年52.6分钟不可用
  • 可用性 99.999%,全年5.26分钟不可用

1.4高可用的形式:

  • 服务高可用:
    • 热备份
    • 冷备份
  • 故障恢复操作:
    • 人工切换
    • 自动切换

人工的反应、决策时间都更长,高可用需要让系统自动决策。HDFS 的设计中,采用了中心化的元数据管理节点NameNode.NameNode 容易成为故障中的单点(single point of failure).

2.1HDFS NameNode 高可用架构

  • 组件介绍:
    • ActiveNamenode:主节点,提供服务,生产日志
    • StandbyNamenode:备节点,消费日志
    • ZooKeeper:为自动选主提供统一协调服务
    • BookKeeper:提供日志存储服务
    • ZKFC:NameNode探活、触发主备切换
    • HA Client:提供了自动切换的客户端
    • edit log:操作的日志
  • 围统三个问题来看高可用:
    • 节点状态如何更新
    • 操作日志如何同步
    • 如何做到自动切换

6b3e9e73f8f9303e732ff43e9c6fe36.jpg 2.2基础理论-状态机复制和日志。

状态机复制是实现容错的常规方法。

组件:

  • 状态机以及其副本
  • 变更日志
  • 共识协议

状态机的基本模型: 78f46ec11810afb102ba1f22f18e84d.jpg 2.4 NameNode 操作日志的生产消费:

目录树和文件信息的更新

Active 生产 Standby消费

物理日志与逻辑日志

  • 日志系统:
    • 高可用
    • 高扩展性
    • 高性能
    • 强一致(有序)

1057380daff0ca6135bdc59cf6cf855.jpg 2.5 NameNode 块状态维护:

  • 回顾
    • DataNode Heartbeat
    • DataNode Block Report
  • 区别
    • Active 即接收,也发起变更(发起相应处理)
    • Standby 只接收,不发起变更
  • Content Stale 状态
    • 主备切换后,避免DN的不确定状态

a99dca3b16918fa1c040705012c6d12.jpg 3.1 分布式协调组件-ZooKeeper

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

  • 使用它的组件:
    • HDFS、 YARN. HBase
    • Kafka. ClickHouse
    • 等等
  • HA核心机制:Watch

53a181ff7b99a0118b3a0f06cfb8bf1.jpg 3.2自动主备切换流程 - Server 侧

ZKFailoverController

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

轮询探活

脑裂问题

Fence 机制

6b3e9e73f8f9303e732ff43e9c6fe36.jpg 3.3 自动主备切换流程 - Client 侧

核心机制:StandbyException(存一组DataNode地址)

Client自动处理

6b3e9e73f8f9303e732ff43e9c6fe36.jpg 4.1 BookKeeper架构

  • BookKeeper存储日志
    • 低延时
    • 持久性
    • 强一致性
    • 读写高可用

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

41f00a03968f3c468f4ad7f7a5fc4b9.jpg 4.2 Quorum 机制

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

  • 场景:
    • 多副本对象存储,用版本号标识数据新旧
  • 规则:
    • 1.Q.+Qw >Q
    • 2.Qw >Q/2

思考:日志场景比对象保存更简单

f7e05d7249f570b14447c7f2cbf473b.jpg 4.3 BookKeeper Quorum

Sloppy Quorum 机制

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

  • Wnte Quorum:写入副本数
  • Ack Quorum:响应副本数

ed7587053409efbf1b4d85ee39dabbc.jpg 4.4 BookKeeper Ensemble

Ensemble 机制

Round-Robin Load Balancer

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

优势:数据均衡

74bc5b5f9f092b31aea7e7a020c5e9f.jpg

二、数据存储高可用。

1.1回到单机存储-RAID

Redundant Array of Independent Disks

图:提供RAID 功能的NAS 设备

特点:

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

ff330f780049ace2ce41940e3070209.jpg 1.2 RAID 方案讲解

  • RAID 0:条带化
  • RAID 1:冗余
  • RAID 3:容错校验

a9bbd995ea5d15bf723fc07f1549394.jpg 2.1 HDFS 多副本

HDFS 版本的RAID 1

图:Hadoop的多副本放置

优点:

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

562840572068b750379142777068513.jpg 2.2 Erasure Coding 原理

HDFS 版本的RAID 2/3

业界常用Reed Solomon算法图: Reed Solomon 算法原理

d43ceb912c3a09d5b1cd13139770cd4.jpg 2.3 HDFS Erasure Coding

HDFS 版本的RAID 2

图:直接保存的EC和Stripe(条带化)后保存的EC

和多副本比较:

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

33da0e803fe6bf0de13b73aea3c19c9.jpg 3.1 初识网络架构

  • Server:一台服务器
  • 机架(Rack):放服务器的架子。
  • TOR(Top of Rack):机架顶部的交换机。
  • POD(Point of Delivery):数据中心中的一个物理区域
  • 数据中心(Data Center):集中部署服务器的场所

3.2 副本放置策略-机架感知

一个TOR 故障导致整个机架不可用

VS

降低跨rack流量

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

图:HDFS的多机架放置

1b9feaea394505ee676c16f3da4bbbe.jpg 4.1 案例:字节跳动的 HDFS 多机房实践

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

  • 多机房解决的问题
    • 容量问题
    • 容灾问题
  • HDFS 双机房放置的设计
    • 写入时,每个数据块在两个机房至少各有一个副本,数据实时写入到两个机房。
    • 读取时,优先读本地的副本,避免了大量的跨机房读取。

12e794bd3d2e2495465caeeee38b15f.jpg 4.2 多机房容灾实践

多机房部署的组件:

  • ZooKeeper
  • BookKeeper
  • NameNode
  • DataNode

容灾期间的策略:

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

三、元数据高扩展性。

1.1元数据节点扩展性挑战:

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

scale up vs. scale out

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

挑战

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

ef6e265ea5cdb2ad48be40820267c42.jpg 1.2常见的 Scale Out 方案:

KV模型的系统可以使用 partition

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

右图:三种数据路由方式

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

b637b139e31ce2a6b11ff8bc8b1bf1f.jpg 2.1 社区解决方案-BlockPool

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

  • 同一个block id在不同的NN上出现

文件服务分层:

  • Namespace
  • Block Storage

用blockpool来区分DN的服务

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

6aaa17575688f0820332f65953f137b.jpg 2.2 社区解决方案-viewfs

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

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

局限性:运维复杂

b3d33422782aec9450e460a30af1970.jpg 3.1 字节跳动的 NNProxy

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

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

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

右图: NNProxy所在系统上下游

00e35763a100f1c3bc89bcbfa0a362e.jpg 3.2 NNProxy 路由规则保护

回顾:三种数据路由方式

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

考虑点:扩展性、运维性

图:路由规则的保存

d6909f8fc0917563145fd56aeab846d.jpg 3.3 NNProxy 路由转发实现

路径最长匹配规则,可以进一步划分目录树

3fc81e67baee040d6e3fdb8d4664be8.jpg 4.案例:小文件问题

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

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

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

解决方案:

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

e9d0e04ae39cb1eb48c80e059ae56b9.jpg

四、存储数据高扩展性。

1.1延迟的分布和长尾延迟。

延迟的分布:

  • 用百分数来表示访问的延迟的统计特征
  • 例如p95延迟为 1ms,代表95%的请求延迟要低于1ms 但后5%的请求延迟会大于1ms

长尾延迟:尾部(p99/p999/p999)的延迟,衡量系统最差的请求的情况。 会显著的要差于平均值。

1.2尾部延迟变大

木桶原理:

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

如何变慢:

  • 固定延迟阈值
  • 固定延迟百分位

b3560b227dcd160dab6d00f26aa4317.jpg (尾部延迟被放大,整个服务器被Backend 6 拖累)

1.3长尾问题的表现-慢节点

慢节点:读取速度过慢,导数客户端阻塞。

慢节点的发生难以避免和预测:

  • 共享资源、后台维护活动、请求多级排队、功率限制
  • 固定的损耗:机器损坏率
  • 混沌现象

离线任务也会遇到长尾问题:

  • 全部任务完成时间取决于最慢的任务什么时候完成
  • 集群规模变大 任务的数据量变大。
  • 只要任何数据块的读取受到长尾影响,整个任务就会因此停滞。

集群扩大 10倍,问题扩大N(>10)倍

e6824519c1d7fed93230e0649ec52e8.jpg 2.1超大集群下的数据可靠性

  • 条件一:超大集群下,有一部分机器是损坏来不及修理的。
  • 条件二:副本放置策略完全随机。
  • 条件三:DN的容量足够大。

推论:必然有部分数据全部副本在损坏的机器上,发生数据丢失。

估算:三副本,10000台机器,每台一百万副本。

  • 有多少种放置的组合数?
  • 损坏100台机器,会有多少副本丢失?

叠加长尾问题,容易导致整个任务无法执行下去。

29ec6ed81492c0cd5878a5515dfe398.jpg 2.2 Copyset

将DataNode 分为若干个Copyset 选块在 copyset 内部选择

原理:减少了副本放置的组合数,从而降低副本丢失的概率。

缺陷:一个Copyset挂掉,所有的数据丢失。

715fff1dc7dda0e6b9a3693cbe07b08.jpg

269303e8ffe581e3a83f38c74dfc2a9.jpg 3.1超大集群的负载均衡和数据迁移

负载均衡的意义:

  • 避免热点
  • 降低成本
  • 可靠性

3.2数据写入不均

数据的不均匀:

  • 节点容量不均匀
  • 数据新旧不均匀
  • 访问类型不均匀

资源负载不均匀

9b54929a6182783b83fea3d8bba5e29.jpg 图:DN的写入量不均匀

3.3数据读取不均

数据的不均匀:

  • 节点容量不均匀
  • 数据新旧不均匀
  • 访问类型不均匀

资源负载不均匀

82b1e6f14e03109253900f9c2674dda.jpg 图:DN的访问不均匀

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

238ee27e1ca0c082e63cc7505f3032d.jpg 4.1数据迁移工具-跨NN迁移

DistCopy

  • 基于MapReduce 通过一个个任务,将数据从一个NameNode拷贝到另一个 NameNode
  • 需要拷贝数据,流量较大,速度较慢。

FastCopy

  • 开源社区的无需拷贝数据的快速元数据迁移方案
  • 前提条件:新旧集群的DN列表吻合
  • 对于元数据,直接复制目录树的结构和块信息。
  • 对于数据块,直接要求DataNode 从源 BlockPool hardlink 到目标BlookPool,没有数据拷贝。
  • hardlink :直接让两个路径指向同一块数据。

6b388c44fbe283044354f0914a3a097.jpg 4.2数据迁移工具-Balancer

工具向DataNode 发起迁移命令平衡各个DataNode的容量。

场景:

  • 单机房使用、多机房使用
  • 限流措施

评价标准:

  • 稳定性成本
  • 可运维性
  • 执行效率

2d5f0ddd17d98ec4ddbcb988eafd84f.jpg

总结

经过本次课的学习,我了解了HDFS的Federation机制,HDFS Federation 使用了多个独立的 NameNode/namespace 来使得 HDFS 的命名服务能够水平扩展。在 HDFS Federation 中的 NameNode 之间是联盟关系,他们之间相互独立且不需要相互协调。 HDFS Federation 中的NameNode提供了提供了命名空间和块管理功能。HDFS Federation 中的datanode 被所有的 NameNode 用作公共存储块的地方。每一个 datanode 都会向所在集群中所有的Namenode 注册,并且会周期性的发送心跳和块信息报告,同时处理来自 Namenode 的指令。