【大数据专场 学习资料三】第四届字节跳动青训营

2,386 阅读34分钟

第四届字节跳动青训营讲师非常用心给大家整理了课前、中、后的学习内容,同学们自我评估,选择性查漏补缺,便于大家更好的跟上讲师们的节奏,祝大家学习愉快,多多提问交流~

第一节:Presto 架构原理与优化介绍

概述

本节课程主要分为四个方面:

  1. 介绍大数据与 OLAP 的演进之路,并简单介绍 Presto 的设计理念
  1. 介绍 Presto 的基础概念与原理,加深对Presto基础概念的理解
  1. 对 Presto 的特色和重要机制进行讲解和剖析
  1. 基于实际工作中遇到的case,介绍 Presto 常用的优化工具,以及 Presto 在字节内部的相关优化

课前 (必须)

大数据与 OLAP 基础概念介绍

en.wikipedia.org/wiki/Big_da…

en.wikipedia.org/wiki/Online…

Presto 基础概念-服务

  • Coordinator(负责调度):

    • 解析SQL语句
    • ⽣成执⾏计划
    • 分发执⾏任务给Worker节点执⾏
  • Worker

在一个presto集群中,存在一个coordinator节点和多个worker节点,coordinator节点是管理节点,而worker节点就是工作节点,在每个worker节点上都会存在一个worker服务进程,该服务进程主要进行数据的处理以及task的执行,worker服务进程每隔一定的时间都会向coordinator上的服务发送心跳,接受调度。当客户端提交一个查询的时候,coordinator则会从当前存活的worker列表中选择出适合的worker节点去运行task,而worker在执行每个task的时候又会进一步对当前task读入的每个split进行一系列的操作和处理

  • Discovery Service(将coordinator和woker结合到一起的服务):

    • Worker节点启动后向Discovery Server服务注册
    • Coordinator从Discovery Server获得Worker节点

所有的worker都把自己注册到Discovery Server上,Discovery Server是一个发现服务的service,Discovery Server发现服务之后,coordinator便知道在集群中有多少个worker能够工作,分配工作到worker时便有了根据

Presto基础概念-数据源

  • Connector

Presto通过Connector来支持多数据源,一个Connector代表一种数据源,如Hive Connector代表了对Hive数据源的支持。可以认为Connector是由Presto提供的适配多数据源的统一接口

  • Catalog

针对不同的数据源,Connector和Catalog是一一对应的关系,Catalog包含了schema和data source的映射关系。

Presto基础概念-Query部分

  • Query

基于SQL parser后获得的执行计划

  • Stage

根据是否需要shuffle将Query拆分成不同的subplan,每一个subplan便是一个stage

  • Fragment

基本等价于Stage,属于在不同阶段的称呼,在本门课程可以认为两者等价

  • Task

单个 Worker 节点上的最小资源管理单元: 在一个节点上, 一个 Stage 只有一个 Task, 一个 Query 可能有多个Task

  • Pipeline

Stage 按照 LocalExchange 切分为若干 Operator 集合, 每个 Operator 集合定义一个 Pipeline

  • Driver

Pipeline 的可执行实体 , Pipeline 和 Driver 的关系可类比 程序和进程 ,是最小的执行单元,通过 火山迭代模型执行每一个Operator

  • Split

输入数据描述(数据实体是 Page), 数量上和 Driver 一一对应,不仅代表实际数据源split,也代表了不同stage间传输的数据

  • Operator

最小的物理算子

Presto基础概念-数据传输部分

  • Exchange

表示不同 Stage 间的数据传输,大多数意义下等价于 Shuffle

  • LocalExchange

Stage内的 rehash 操作,常用于提高并行处理数据的能力(Task在presto中只是最小的容器,而不是最小的执行单元)

课中

概述

  1. 什么是大数据

在信息化时代背景下,由于信息交互,信息存储,信息处理能力大幅增加而产生的数据

  1. 什么是OLAP

OLAP (OnLine Analytical Processing) 对业务数据执行多维分析,并提供复杂计算,趋势分析和复杂数据建模的能力。是许多商务智能(BI)应用程序背后的技术。现如今OLAP已经发展为基于数据库通过SQL对外提供分析能力

  1. Presto设计理念

Presto最初是由facebook研发的构建于Hadoop/HDFS系统之上的PB级交互式分析引擎,其具有如下的特点:

  • 多租户任务的管理与调度
  • 多数据源联邦查询
  • 支持内存化计算
  • pipeline式数据处理

基础概念

  1. Presto基础概念主要可以分为哪几类?

    1. 服务相关概念
    2. 数据源相关概念
    3. Query相关概念
    4. 数据传输相关概念

PS:具体可以参考课前基础概念部分的介绍

  1. Presto的通信方式有哪些,Thrift通信的优势

Http 1.1 vs Thrift

Thrift具有更好的数据编码能力,Http 1.1还不支持头部信息的压缩,Thrift具有更好的数据压缩率

  1. Presto Worker的不同状态

    1. Active
    2. InActive
    3. Shutdown
  2. Presto架构图

重要机制

  1. Presto用户多租户隔离的手段是什么?

    1.   Presto 通过Resource Group对不同的用户创建不同Group从而实现不同租户,不同场景的资源管理
  1. Presto Resource Group的优缺点

优点:支持通配符的形式,对不同租户,不同提交场景下的用户进行限制

缺点:资源的管理和判断是以当前用户正在运行的SQL资源使用量为基准,对于低频大SQL场景不太适用

  1. Presto是从哪几个方面实现了多租户的任务调度

    1. Stage调度策略
    2. Task的节点选择策略
    3. Split调度策略
  2. Presto Stage调度的方式有哪些?

    1. AllAtOnceExecutionPolicy
    2. PhasedExecutionPolicy
  3. Presto 进行 Task 调度时,有哪些调度方式?

    1. HARD_AFFINITY: 计算、存储 Local 模式,保障计算与存储在同一个节点,减少数据传输
    2. SOFT_AFFINITY: 基于某些特定算法,如一致性HASH函数,常用于缓存场景,保证相似的 Task 调度到同一个 Worker
    3. NO_PREFERENCE: 随机选取,常用于普通的纯计算 Task
  4. Presto是如何实现Back pressure mechanism的

    1. 控制split生成流程
    2.   针对每个Task定时检查, 如果 OutputBuffers 使用率低于 0.5 (下游消费较快, 需要提高生产速度), Split 并发度+1
    3. 控制Operator执行速度
    4.   "sink.max-buffer-size" 写入buffer的大小控制
    5.   "exchange.max-buffer-size" 读取buffer的大小控制
    6.   Buffer 达到最大值时Operator会进入阻塞状态
  1. Presto多数据源支持的优点与缺点

优点:支持多数据源的联邦查询

  • 缺点:针对不同数据源,还存在许多问题需要解决
    • 谓词下推
    • 每个数据源都需要单独的一套catalog管理
    • 如何针对数据源进行分片操作

性能优化实战

  1. 常用的性能分析工具

    1. Grafana
    2. Arthas
    3. Flame Figure(火焰图)
    4. java指令:jstack等指令
  1. Arthas在presto常用哪些命令

    1. watch:监控每个函数入参、返回参数、异常等信息
    2. trace:统计函数内每一步的执行时间
  1. 通过火焰图如何分析性能瓶颈

火焰图用于分析热点代码占用大量cpu,从而导致服务性能下降的情况。如下图,自底向上为调用关系。上层宽度越宽表示当前函数cpu耗时越久,我们关注最宽的函数调用。

课后

  1. 能否区分task、pipline、split、driver等worker侧的概念
  1. 本节课讲授的Presto重要机制有哪些?
  1. 能否完整的描述一遍Presto多租户调度中的相关流程?
  1. Pipeline化数据处理是否等价于流式计算?
  1. 能否实现可中断的正则表达式,性能与普通正则表达式相比如何?

参考文档

  1. Google File System论文

static.googleusercontent.com/media/resea…

  1. Google MapReduce 论文

static.googleusercontent.com/media/resea…

  1. Presto: SQL on Everything 论文

www.jianshu.com/p/de0a1de9f…

  1. Presto 应用场景简介

prestodb.io/overview.ht…

  1. Presto Local 部署介绍

prestodb.io/docs/curren…

  1. Presto 基础概念

prestodb.io/docs/curren…

  1. Configuration 构建耗时问题

github.com/prestodb/pr…

  1. Presto Connector实现原理

zhuanlan.zhihu.com/p/143115558

  1. Presto多级缓存介绍

prestodb.io/blog/2021/0…

  1. Presto : The Definitive Guide

www.starburst.io/wp-content/…

  1. arthas官方使用文档

arthas.aliyun.com/doc/

  1. 如何看懂火焰图

cloud.tencent.com/developer/a…

  1. grafana简介

en.wikipedia.org/wiki/Grafan…

第二节:HDFS原理与应用

概述

本课程将以Apache HDFS为蓝本,重点介绍HDFS的原理和应用场景,帮助同学加深对大规模数据分布式存储系统的理解。本课程将包括三个方面

  • HDFS架构原理
  • HDFS关键设计
  • HDFS应用场景

通过本课程,我们希望同学们能够有以下收获:

  • 了解HDFS的使用场景,尤其是在大数据场景中的常规应用,同时也了解HDFS在其它场景的一些应用,加深对存储系统应用场景的理解。
  • 了解HDFS的设计与实现,包括基本功能、运维体系等,对生产环境里分布式存储系统体系化建设有进一步认知。
  • 抽象总结一个分布式存储系统涉及的基本概念和设计问题

课前

课前部分主要罗列课程中涉及到的概念术语,尽管这门课程不要求同学们有大数据或存储系统项目经验,但是对于本小节提到的概念如果不熟悉,可以提前预习查阅相关资料,简单了解相关术语的意思,以便提高听课效果。

基础知识

  • 操作系统
  • 文件系统
  • POSIX文件系统
  • Linux
  • Python

大数据术语

  • Hadoop
  • Spark
  • Flink
  • Kafka
  • OLAP/OLTP
  • Data warehouse: 数据仓库
  • AWS S3 / 阿里云OSS
  • HDFS
  • HBase

分布式存储

  • High Availability: 高可用
  • Throughput: 吞吐量
  • Scale Out: 水平扩展
  • Scale Up:纵向扩展
  • Fault-Tolerance: 容错
  • Erasure Coding/EC: 纠删码

课中

引言

  • 认识Hadoop技术体系,理解“计算+存储”的程序应用逻辑

    • 存储层:HDFS
    • 调度层:YARN
    • 计算框架:MapReduce。值得注意的是另外一个同属于Apache基金会的开源计算框架Apache Spark,当前业界的使用已经远超于MapReduce,尽管它不属于Hadoop项目,但是和Hadoop也有紧密关系。
  • 文件系统:单机文件系统非常普遍,从Windows NTFS到Linux的Ext4等,分布式文件系统是单机文件的延伸,概念术语是相通的,比如目录、文件、目录树等。

    • 单机文件系统:常见的如Windows NTFS,Linux的Ext4,虽然不同的操作系统和实现,但是本质都是一样的,解决相同的问题。
    • 分布式文件系统:本质上扩展、延伸了单机文件系统,提供了大容量、高可靠、低成本等功能特性;实现上一般也更为复杂。
  • 分布式存储系统,了解分布式存储系统的分类,理解不同存储系统的使用场景。直观的区别是用户使用方式,本质是针对不同的使用场景提供高效合理的系统。

    • 对象存储:例如AWS的S3,阿里云的OSS,开源的Minio。
    • 块存储:例如AWS的EBS,开源社区也有Ceph等。
    • 文件系统:HDFS、GlusterFS、CubeFS等
    • 数据库:KV数据库比如Cassandra,关系型数据库如TiDB、OceanBase等
  • HDFS功能特性:需要注意HDFS尽管是一个文件系统,但是它没有完整实现POSIX文件系统规范。
  • HDFS演示环境:展示一个完整的HDFS服务的部署结构和基本的基本的交互方式,通过简单的交互读写操作开始了解学习HDFS。

    • 节点类型:ZooKeeper/JournalNode/NameNode/DataNode
    • HDFS 命令行交互
    • HDFS Web UI

架构原理

  • 分布式存储系统的基本概念,这些概念基本上每个分布式存储系统都会涉及到。

    • 容错能力
    • 一致性模型
    • 可扩展性
    • 节点体系模式
    • 数据放置策略
    • 单机存储引擎
  • HDFS组件

    • Client/SDK:读写操作的发起点,HDFS很多读写逻辑都是在SDK中实现的。
    • NameNode:元数据节点,是HDFS的中枢节点,也是服务的入口。
    • DataNode:数据节点,存放实际用户数据。

关键设计

  • NameNode目录树设计,重点理解EditLog的设计,可类比关系型数据库中的Transaction Log概念。

    • 仅在内存中修改:fsimage
    • 需要立即保存到硬盘:EditLog
  • NameNode数据放置:数据分散在各个节点上,如何定位找到它们?

    • 文件和数据块的映射关系
    • 数据块的放置分布策略
  • DataNode设计:数据如何落盘存放?

    • 数据块路径
    • 启动扫盘获得本机文件块列表
  • Client读写链路的异常处理

    • Server端异常
    • Client端异常
    • 慢节点
  • 控制面建设:保障系统稳定运行

    • HouseKeeping组件:比如Balancer,Mover等, 这些组件不运行不会马上影响读写操作,但是长时间会积累系统性问题,例如读写不均衡导致IO热点等。
    • 可观测性设施:比如系统指标监控设施等,帮助快速发现定位问题。
    • 运维体系建设:从最基本的命令行手工操作,脚本自动化再到完善的运维平台。

应用场景

  • 大数据技术中的应用

    • HDFS在大数据技术体系中的角色

    • 演示:PySpark读取分析HDFS上的文件

      • 数据如何产生
      • 数据如何读取
      • 数据如何保存
    • ETL:数据如何产生、传输

    • OLAP:如何高效地读取分析数据

  • 存储底座

    • HBase
    • 机器学习
    • 通用场景

课后

思考题

  • 为什么需要存在这么多不同的分布式存储系统?
  • 在实际运行过程中,HDFS可能会有哪些异常场景?
  • HDFS诞生于2006年,依照当时的硬件条件设计,以今天的硬件水平来看,哪些设计可以改进?
  • DataNode的启动扫盘设计存在哪些问题?可以如何优化
  • 什么是分布式系统的“脑裂”?
  • HouseKeeping组件的设计需要注意哪些点?
  • HDFS作为通用存储场景,有哪些优缺点?
  • 以各大云厂商相关产品为切入点,大数据存储领域发展有哪些趋势?

探索学习

  • 进一步了解可观测性工程
  • 如果想进一步阅读HDFS的源码,可以把源码导入到IDE(例如Intellij IDEA),以基本的读写操作为线索,比如一个hdfs put 命令,按图索骥摸索出实现这个命令的代码。

第三节:HDFS 高可用与高扩展性机制分析

概述

本节课程主要分为四个方面

  1. HDFS 元数据服务的高可用
  1. HDFS 数据存储高可用
  1. HDFS 元数据服务的高扩展性
  1. HDFS 数据存储的高扩展性

课前

基础知识

  • 文件目录树 Directory Tree
  • 路径前缀匹配
  • Quorum

高可用

  • 复制状态机 Replicated State Machine
  • 操作日志 Op Log / Edit Log
  • RTO 与 RPO
  • 物理日志与逻辑日志
  • 同步复制、半同步复制
  • 心跳
  • 脑裂
  • fence
  • 副本 replica
  • 数据中心网络架构
  • 机架 rack
  • TOR 交换机
  • 数据中心 data center

扩展性

  • 分片 shard
  • 分区 partition
  • 邦联架构 federation
  • 路由 route
  • block pool
  • 代理 proxy
  • 负载均衡 load balance
  • 数据分级 data classification
  • 冷/热数据 hot/cold data
  • 数据搬迁 migration
  • 慢节点
  • 长尾 long tail

课中

课件结构

  1. 元数据高可用(P6~23)

    1. 1.1 高可用的需求
    2. 1.2 HDFS 的高可用架构
    3. 1.3 自动主备切换
    4. 1.4 高可用日志系统 BookKeeper 简介
  1. 数据高可用(P24~34)

    1. 2.1 单机存储的数据高可用机制
    2. 2.2 HDFS 的数据高可用机制
    3. 2.3 考虑网络架构的数据高可用
    4. 2.4 案例:字节跳动的 HDFS 多机房实践
  1. 元数据扩展性(P36~45)

    1. 3.1 元数据扩展性的挑战
    2. 3.2 社区解决方案
    3. 3.3 Proxy 方案介绍
    4. 3.4 案例:小文件问题
  1. 数据扩展性(P46-P59)

    1. 4.1 超大集群的长尾问题

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

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

      • 案例:数据分布不均导致慢节点问题
    4. 4.4 数据迁移工具速览

HDFS 回顾

HDFS 的架构

  • HDFS 的主要服务端主要组件是 NameNode 和 DataNode,两者通过定时心跳通信。
  • NameNode(NN)负责维护目录树、文件和块的关系、各个块的副本放置位置等元信息。
  • DataNode(DN)负责维护数据副本,执行 NameNode 下发的副本迁移、副本删除等操作。
  • HDFS Client 属于是胖客户端(fat/rich client),客户端中实现了数据读写的容错等较为复杂的逻辑。

HDFS 的读写路径

  • 数据读取:Client 从 NN 上获取到文件信息和块的位置(getFileInfo+getBlockLocation),从对应 DN 上读取数据。当一个 DN 读取失败时,会去尝试块的其他 DN。
  • 数据写入:Client 要求 NN 创建文件(create),并依次获得不同的 DN 来写入数据块(addBlock)。Client 通过链式写入来同时写入数据到多个 DN。在整个写入完成后,会让 NN 关闭文件(complete)。

元数据高可用

高可用:系统在困境(adversity,比如硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并能达到期望的性能水准)

容灾:在相隔较远的异地,建立两套或多套功能相同的系统,互相之间可以进行健康状态监视和功能切换,当一处系统因意外(如火灾、地震等)停止工作时,整个应用系统可以切换到另一处,使得该系统功能可以继续正常工作。

故障度量的指标

  • MTTR(Mean Time To Repair):平均修复时间,系统能多快恢复。
  • MTTF(Mean Time To Failure):平均失效时间,运行到故障间的时间,一般用于不可修复的系统(制造业)。
  • MTBF(Mean Time Between Failures):平均无故障时间,两次故障间的间隔,一般用于可修复的系统(软件)。

全年不可用时间:系统运行一整年的不可用时间的目标。

备份方式

  • 冷备份:备份服务的数据,可以和数据归档相结合。在主服务故障时,利用备份的数据重启。
  • 热备份:主服务和备服务同时运行,在主服务故障时,随时可以切换到备服务。

切换方式:

  • 人工切换:在故障发生时,运维人员接收报警后,手动执行服务切主操作。一般较慢,难以满足全年不可用时间的目标。
  • 自动切换:通过探活组件、分布式共识协议等手段,系统能自动发现主服务的故障,并切换到备份不符。

单点故障 SPOF:指系统中一旦失效,就会让整个系统无法运作的组件。

状态机复制模型:实现容错服务的一种常规方法,主要通过复制服务器,并协调客户端和这些服务器镜像间的交互来达到目标。这个方法也同时提供了理解和设计复制管理协议的一套基本框架。

  • 状态机:一个状态机从“初始”状态开始,每一个输入都被传入转换函数和输出函数,以生成一个新的状态和输出。在新的输入被接收到前,状态保持不变,而输出同时被传输给恰当的接受者。
  • 状态机复制:确定性的状态机具有「处理确定的输入后,状态唯一确定」的特性。状态机复制利用这个特性实现多个相同的状态机副本的同步更新。
  • 变更日志:触发状态机更新的变更操作,具有全局确定的顺序。
  • 共识协议:确保每个副本都能收到相同的日志的共识协议,常见的有 Paxos、Raft、ZAB。

HDFS高可用架构

  • Active NameNode:提供服务的 NameNode 主节点,生产 editlog。
  • Standby NameNode:不提供服务,起备份作用的 NameNode 备节点,消费 editlog
  • editlog:用户变更操作的记录,具有全局顺序,是 HDFS 的变更日志。
  • ZooKeeper:开源的分布式协调组件,主要功能有节点注册、主节点选举、元数据存储。
  • BookKeeper:开源的日志存储组件,存储 editlog
  • ZKFC:和 ZK、NN 通信,进行 NN 探活和自动主备切换。
  • HA Client:处理 StandbyException,在主备节点间挑选到提供服务的主节点。

NameNode 状态持久化

  • FSImage 文件:较大的状态记录文件,是某一时刻 NN 全部需要持久化的数据的记录。大小一般在 GB 级别。
  • EditLog 文件:是某段时间发生的变更日志的存储文件。大小一般在 KB~MB 级别。
  • checkpoint 机制:将旧的 FSImage 和 EditLog 合并生成新的 FSImage 的流程,在完成后旧的数据可以被清理以释放空间。

物理日志:存储了物理单元(一般是磁盘的 page)变更的日志形式。

逻辑日志:存储了逻辑变更(例如 rename /a to /b)的日志形式。

HDFS 主备切换

  • DataNode 心跳与块汇报需要同时向 active NN 和 standby NN 上报,让两者可以同时维护块信息。但只有 active NN 会下发 DN 的副本操作命令。
  • content stale 状态:在发生主备切换后,新 active NN 会标记所有 DN 为 content stale 状态,代表该 DN 上的副本是不确定的,某些操作不能执行。直到一个 DN 完成一次全量块上报,新 active NN 才标记它退出了 content stale 状态。

    • 例子,多余块的删除:NN 发现某个块的副本数过多,会挑选其中一个 DN 来删除数据。在主备切换后,新 active NN 不知道旧 active NN 挑选了哪个副本进行删除,就可能触发多个 DN 的副本删除,极端情况下导致数据丢失。content stale 状态的引入解决了这个问题。
  • 脑裂问题:因为网络隔离、进程夯住(例如 Java GC)等原因,旧的 active NN 没有完成下主,新的 active NN 就已经上主,此时会存在双主。client 的请求发给两者都可能成功,但不能保证一致性(两个 NN 状态不再同步)和持久化(只能保留一个 NN 状态)。
  • fence 机制:在新 active NN 上主并正式处理请求之前,先要确保旧 active NN 已经退出主节点的状态。一般做法是先用 RPC 状态检测,发现超时或失败则调用系统命令杀死旧 active NN 的进程。

自动主备切换

  • ZooKeeper 是广泛使用的选主组件,它通过 ZAB 协议保证了多个 ZK Server 的状态一致,提供了自身的强一致和高可用。
  • ZooKeeper 的访问单位是 znode,并且可以确保 znode 创建的原子性和互斥性(CreateIfNotExist)。client 可以创建临时 znode,临时 znode 在 client 心跳过期后自动被删除。
  • ZK 提供了 Watch 机制,允许多个 client 一起监听一个 znode 的状态变更,并在状态变化时收到一条消息回调(callback)。
  • 基于临时 znode 和 Watch 机制,多个客户端可以完成自动的主选举。
  • ZKFailoverController:一般和 NN 部署在一起的进程,负责定时查询 NN 存活和状态、进行 ZK 侧主备选举、执行调用 NN 接口执行集群的主备状态切换、执行 fence 等能力。
  • Hadoop 将集群主备选举的能力和 NN 的服务放在了不同的进程中,而更先进的系统一般会内置在服务进程中。

高可用日志系统 BookKeeper

  • 高可靠:数据写入多个存储节点,数据写入就不会丢失。
  • 高可用:日志存储本身是高可用的。因为日志流比文件系统本身的结构更为简单,日志系统高可用的实现也更为简单。
  • 强一致:日志系统是追加写入的形式,Client 和日志系统的元数据可以明确目前已经成功的写入日志的序号(entry-id)。
  • 可扩展:整个集群的读写能力可以随着添加存储节点 Bookie 而扩展。

Quorum 协议:基于鸽巢原理,在多个副本间确保高可用、高性能的多副本变更协议

  • 多副本间一般通过 version-id 来描述状态的新旧。
  • 高可用:多个副本确保了高可用(后文会再次介绍多副本高可用)。
  • 高性能:不用等所有副本写入成功,降低了的长尾延迟(后文会再次介绍长尾延迟)。

BookKeeper Quorum 协议:基于 Quorum 的多数派思想来提供高可用、高性能写入的日志写入

  • 日志写入是追加,不是状态变更,只需要确认目前的 entry-id,相对更简单。
  • Write Quorum:一次写入需要写入到的存储节点数。
  • Ack Quorum:一次写入需要收到的响应数,小于 write quorum。
  • 高性能:不用等所有副本写入成功,降低了的长尾延迟(后文会再次介绍长尾延迟)。
  • Ensemble:通过轮询(Round-Robin)来确认 write quorum 实际对应的存储节点实例,可以比较简单的完成副本放置和扩展。

数据高可用

RAID:将多个廉价、不可靠、低性能、容量小的磁盘组装在一起,提供高可靠、高性能、大容量逻辑磁盘服务的一组磁盘列阵方案。

  • RAID 0 :将数据分块后按条带化的形式分别存储在多个磁盘上,提供大容量、高性能。
  • RAID 1:将数据副本存储在多个磁盘上,提供高可靠。
  • RAID 3:在数据分块存储的基础上,将数据的校验码存储在独立的磁盘上,提供高可靠、高性能。
  • 其他可以参考 RAID

多副本方案:将数据块存储在多个 DN 上

Erasure Coding 方案:将数据分段,通过特殊的编码方式存储额外的校验块,并条带化的组成块,存储在 DN 上。

  • 条带化:原本块对应文件内连续的一大段数据。条带化后,连续的数据按条带(远小于整个块的单位)间隔交错的分布在不同的块中。
  • 成本更低:多副本方案需要冗余存储整个块,EC 方案需要冗余存储的数据一般更少。

数据中心架构

  • 机架/机柜:将几个服务器统一供电、提供对外网络的固定的物理设备。
  • TOR top of rack:机架顶部(或底部)的交换机,负责机架内服务器和数据中心的其他服务器的网络通信。
  • 机房和数据中心都是指大量服务器集中放置的场所。

    • 机房:强调的基础设施建设,例如物理承重、空调、防水、消防。
    • 数据中心:强调机房的业务属性。
  • 网络拓扑:按数据中心->机架->机器的顺序,描述进程在网络空间中所处的位置。
  • 跨机房专线:由网络服务商提供,连接机房的专用网络。

    • 稳定性和安全性好于公网。
    • 相比于数据中心内网络,吞吐更为有限、延迟更高、成本更高。

故障域

  • 故障域是基础设施中可能发生故障的区域或组件。每一个域都有自己的风险和挑战,由个别几个因素决定整个故障域的服务能力,需要进行架构。
  • 机架感知:以 TOR 为关键点,机架是一个故障域。数据副本全部放置在一个机架中,当相应 TOR 故障时数据就无法访问。
  • 机房感知:以机房的基础设施(空调、电力)和跨机房专线为关键点,它们发生故障时整个机房会发生故障,导致不可用。

多机房容灾:服务和数据需要存放在多个机房,并配合合理的架构。使得发生机房故障时依然可以提供服务。

元数据扩展性

扩展性方案

  • scale up:通过单机的 CPU、内存、磁盘、网卡能力的提升来提升系统服务能力,受到机器成本和物理定律的限制。
  • scale out:通过让多台机器组成集群,共同对外提供服务来提升系统服务能力。一般也称为高扩展、水平扩展。

partition 方法

  • 水平分区和垂直分区:水平分区指按 key 来将数据划分到不同的存储上;垂直分区指将一份数据的不同部分拆开存储,用 key 关联起来。partition 一般都水平分区,又称 shard。
  • 常用于 KV 模型,通过 hash 或者分段的手段,将不同类型 key 的访问、存储能力分配到不同的服务器上,实现了 scale out。
  • 重点:不同单元之间不能有关联和依赖,不然访问就难以在一个节点内完成。例如 MySQL 的分库分表方案,难以应对复杂跨库 join。

federation 架构

  • 使得多个集群像一个集群一样提供服务的架构方法,提供了统一的服务视图,提高了服务的扩展性。
  • 文件系统的目录树比 kv 模型更复杂,划分更困难。
  • 邦联架构的难点一般在于跨多个集群的请求,例如 HDFS 的 rename 操作就可能跨多个集群。

blockpool

  • 将文件系统分为文件层和块存储层,对于块存储层,DN 集群对不同的 NN 提供不同的标识符,称为 block pool。
  • 解决了多个 NN 可能生成同一个 block id,DN 无法区分的问题。

viewfs

  • 邦联架构的一种实现,通过客户端配置决定某个路径的访问要发送给哪个 NN 集群。
  • 缺点:客户端配置难以更新、本身配置方式存在设计(例如,只能在同一级目录区分;已经划分的子树不能再划分)。

NNProxy

  • 主要提供了路由管理、RPC 转发,额外提供了鉴权、限流、查询缓存等能力。
  • 开源社区有类似的方案 Router Based Federation,主要实现了路由管理和转发。

小文件问题

  • HDFS 设计上是面向大文件的,小于一个 HDFS Block 的文件称为小文件。
  • 元数据问题:多个小文件相对于一个大文件,使用了更多元数据服务的内存空间。
  • 数据访问问题:多个小文件相对于一个大文件,I/O 更加的随机,无法顺序扫描磁盘。
  • 计算任务启动慢:计算任务在启动时,一般会获得所有文件的地址来进行 MapReduce 的任务分配,小文件会使得这一流程变长。
  • 典型的 MR 流程中,中间数据的文件数和数据量与 mapper*reducer 的数量成线性,而为了扩展性,一般 mapper 和 reducer 的数量和数据量成线性。于是,中间数据的文件数和数据量与原始的数据量成平方关系。
  • 小文件合并任务:计算框架的数据访问模式确定,可以直接将小文件合并成大文件而任务读取不受影响。通过后台运行任务来合并小文件,可以有效缓解小文件问题。通过 MapReduce/Spark 框架,可以利用起大量的机器来进行小文件合并任务。
  • Shuffle service:shuffle 流程的中间文件数是平方级的,shuffle service 将 shuffle 的中间数据存储在独立的服务上,通过聚合后再写成 HDFS 文件,可以有效地缓解中间数据的小文件问题。

数据扩展性

长尾

  • 二八定律:在任何一组东西中,最重要的只占其中一小部分,约 20%,其余 80% 尽管是多数,却是次要的。
  • 长尾:占绝大多数的,重要性低的东西就被称为长尾。

百分位延迟

  • 将所有请求的响应速度从快到慢排序,取其中某百分位的请求的延迟时间。
  • 例如 pct99 代表排在 99% 的请求的延迟。相对于平均值,能更好的衡量长尾的情况。

尾部延迟放大

  • 木桶原理:并行执行的任务的耗时取决于最慢的一个子任务。
  • 尾部延迟放大:一个请求或任务需要访问多个数据节点,只要其中有一个慢,则整个请求或任务的响应就会变慢。
  • 固定延迟阈值,访问的集群越大, 高于该延迟的请求占比越高。
  • 固定延迟百分位,访问的集群越大,延迟越差。

长尾问题

  • 尾部延迟放大+集群规模变大,使得大集群中,尾部延迟对于整个服务的质量极为重要。
  • 慢节点问题:网络不会直接断联,而是不能在预期的时间内返回。会导致最终请求不符合预期,而多副本机制无法直接应对这种问题。
  • 高负载:单个节点处理的请求超过了其服务能力,会引发请求排队,导致响应速度慢。是常见的一个慢节点原因。

数据可靠性

  • 超大集群下,一定有部分机器是损坏的,来不及修理的。
  • 随机的副本放置策略,所有的放置组合都会出现。而 DN 容量够大,足够
  • 三副本,单个 DN 视角:容量一百万,机器数量一万。那么另外两个副本的排列组合有一亿种,容量比放置方案大约百分之一。
  • 三副本,全局视角:一万台机器,每台一百万副本,损坏 1%(100 台)。根据排列组合原理,大约有 1009998/(1000099999998)(100000010000)=9704 个坏块
  • callback 一下,叠加长尾问题。每个任务都要访问大量的块,只要一个块丢失就整个任务收到影响。导致任务层面的丢块频发,服务质量变差。

copyset

  • 降低副本放置的组合数,降低副本丢失的发生概率。
  • 修复速度:DN 机器故障时,只能从少量的一些其他 DN 上拷贝数据修复副本。

负载均衡的意义

  • 避免热点

    • 机器热点会叠加长尾问题,少数的不均衡的热点会影响大量的任务。
  • 成本:

    • 数据越均衡,CPU、磁盘、网络的利用率越高,成本更低。
    • 集群需要为数据腾挪预留的空间、带宽更少,降低了成本。
  • 可靠性

    • 全速运行的机器和空置的机器,以及一会全速运行一会空置的机器,可靠性表现都有不同。负载均衡可以降低机器故障的发生。
    • 同一批机器容易一起故障,数据腾挪快,机器下线快,可以提升可靠性。
  1. 负载均衡性影响因素:多个复杂因素共同影响负载均衡性
  • 不同节点上的业务量的平衡
  • 数据放置策略
  • 数据搬迁工具的能力
  • 系统环境

集群的不均衡情况

  • 节点容量不均:机器上的数据量不均衡。

    • 原因可能是各种复杂情况导致,归根结底是混沌现象。
  • 数据新旧不均:机器上的数据新旧不均匀。

    • 例如:新上线的机器,不做任何数据均衡的情况下,只会有新写入的数据。而一般新数据更容易被读取,更为「热」。
  • 访问类型不均:机器上的数据访问类型不均。

    • 例如:机器学习训练需要反复读取数据,小 I/O 更多。而大数据场景一般只扫描一次,大 I/O 为主。这两种模式的读写比不同,I/O pattern 不同,就来带访问冷热的不同。
  • 异构机器:有的机器配置高、有的机器配置低,不考虑异构情况的话配置高的机器会闲置,配置低的机器会过热。
  • 资源不均:机器上的访问请求吞吐、IOPS 不均衡,导致最终机器冷热不均、负载不均。一般由于容量不均、新旧不均、模式不均导致

需要数据迁移的典型场景

  • DN 上线:新上线的机器没有任何数据,而且只会有新数据写入。需要迁移其他 DN 的旧数据到新 DN 上,使得负载和数据冷热均衡。
  • DN 下线:需要下线的机器,需要提前将数据迁移走再停止服务,避免数据丢失的风险。
  • 机房间均衡:因为资源供应、新机房上线等外部条件,机房规划、业务分布等内部条件,不同机房的资源量和资源利用率都是不均衡的。需要结合供应和业务,全局性的进行资源均衡。
  • 日常打散:作为日常任务运行,不断地从高负载、高容量的机器上搬迁数据到低负载、低容量的机器上,使得整个集群的负载均衡起来。

数据迁移工具

  • 目的:将数据从一部分节点搬迁到另一部分节点。
  • 要求:高吞吐、不能影响前台的服务。

带元数据迁移的迁移工具

  • 痛点:涉及到元数据操作,需要停止用户的写入。
  • DistCopy 工具

    • 通过 MapReduce 任务来并行迁移数据,需要拷贝数据和元数据。
    • 网络流量较大,速度较慢。
  • FastCopy 工具

    • 基于 hardlink 和 blockpool 的原理
    • 元数据直接在 NN 集群间拷贝,而数据则在 DN 上的不同 blockpool(对应到 NN 集群)进行 hardlink,不用数据复制。
    • 迁移速度要大大优于 DistCopy。

数据迁移工具

  • Balancer 工具

    • 代替 NN 向 DN 发起副本迁移的命令,批量执行副本迁移。
    • 场景:大规模数据平衡、机器上下线。

课后

  1. 达到 99.99% 可用性的服务,一年中的不可用时间是多久?
  1. 北京和上海的网络延迟下限是多少?
  1. 什么是 ZKFC,它和哪几个组件交互?
  1. 什么是高可用集群中的 fence 机制?
  1. HDFS NameNode 如何选择数据放置的 DataNode 时,需要考虑的因素有哪些?
  1. 什么是路径的最长匹配?和字符串的最长匹配有什么区别?举例说明
  1. 小文件过多会对 NameNode 和 DataNode 造成什么影响?
  1. 慢节点的成因可能有什么?
  1. 对比完全随机放置和 copyset 放置的特点。
  1. 新节点上线就是扩容完成了么?还需要做什么工作?

参考文献

高可用与分布式

  • 《Design Data-Intensive Applications》
  • 《A Performance Evaluation and Examination of Open-Source Erasure Coding Libraries For Storage》

元数据扩展

小文件问题

  • 《MapReduce: Simplified Data Processing on Large Clusters》
  • 《Magnet: Push-based Shuffle Service for Large-scale Data Processing》
  • 《Dealing with Small Files Problem in Hadoop Distributed File System》
  • 《Sailfish: A Framework For Large Scale Data Processing》

扩展性

  • 《The Tail at Scale》
  • 《Copysets: Reducing the Frequency of Data Loss in Cloud Storage》