第四届字节跳动青训营讲师非常用心给大家整理了课前、中、后的学习内容,同学们自我评估,选择性查漏补缺,便于大家更好的跟上讲师们的节奏,祝大家学习愉快,多多提问交流~
第一节:Presto 架构原理与优化介绍
概述
本节课程主要分为四个方面:
- 介绍大数据与 OLAP 的演进之路,并简单介绍 Presto 的设计理念
- 介绍 Presto 的基础概念与原理,加深对Presto基础概念的理解
- 对 Presto 的特色和重要机制进行讲解和剖析
- 基于实际工作中遇到的case,介绍 Presto 常用的优化工具,以及 Presto 在字节内部的相关优化
课前 (必须)
大数据与 OLAP 基础概念介绍
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中只是最小的容器,而不是最小的执行单元)
课中
概述
- 什么是大数据
在信息化时代背景下,由于信息交互,信息存储,信息处理能力大幅增加而产生的数据
- 什么是OLAP
OLAP (OnLine Analytical Processing) 对业务数据执行多维分析,并提供复杂计算,趋势分析和复杂数据建模的能力。是许多商务智能(BI)应用程序背后的技术。现如今OLAP已经发展为基于数据库通过SQL对外提供分析能力
- Presto设计理念
Presto最初是由facebook研发的构建于Hadoop/HDFS系统之上的PB级交互式分析引擎,其具有如下的特点:
- 多租户任务的管理与调度
- 多数据源联邦查询
- 支持内存化计算
- pipeline式数据处理
基础概念
-
Presto基础概念主要可以分为哪几类?
- 服务相关概念
- 数据源相关概念
- Query相关概念
- 数据传输相关概念
PS:具体可以参考课前基础概念部分的介绍
- Presto的通信方式有哪些,Thrift通信的优势
Http 1.1 vs Thrift
Thrift具有更好的数据编码能力,Http 1.1还不支持头部信息的压缩,Thrift具有更好的数据压缩率
-
Presto Worker的不同状态
- Active
- InActive
- Shutdown
-
Presto架构图
重要机制
-
Presto用户多租户隔离的手段是什么?
- Presto 通过Resource Group对不同的用户创建不同Group从而实现不同租户,不同场景的资源管理
- Presto Resource Group的优缺点
优点:支持通配符的形式,对不同租户,不同提交场景下的用户进行限制
缺点:资源的管理和判断是以当前用户正在运行的SQL资源使用量为基准,对于低频大SQL场景不太适用
-
Presto是从哪几个方面实现了多租户的任务调度
- Stage调度策略
- Task的节点选择策略
- Split调度策略
-
Presto Stage调度的方式有哪些?
- AllAtOnceExecutionPolicy
- PhasedExecutionPolicy
-
Presto 进行 Task 调度时,有哪些调度方式?
- HARD_AFFINITY: 计算、存储 Local 模式,保障计算与存储在同一个节点,减少数据传输
- SOFT_AFFINITY: 基于某些特定算法,如一致性HASH函数,常用于缓存场景,保证相似的 Task 调度到同一个 Worker
- NO_PREFERENCE: 随机选取,常用于普通的纯计算 Task
-
Presto是如何实现Back pressure mechanism的
- 控制split生成流程
- 针对每个Task定时检查, 如果 OutputBuffers 使用率低于 0.5 (下游消费较快, 需要提高生产速度), Split 并发度+1
- 控制Operator执行速度
- "sink.max-buffer-size" 写入buffer的大小控制
- "exchange.max-buffer-size" 读取buffer的大小控制
- Buffer 达到最大值时Operator会进入阻塞状态
- Presto多数据源支持的优点与缺点
优点:支持多数据源的联邦查询
- 缺点:针对不同数据源,还存在许多问题需要解决
-
- 谓词下推
- 每个数据源都需要单独的一套catalog管理
- 如何针对数据源进行分片操作
性能优化实战
-
常用的性能分析工具
- Grafana
- Arthas
- Flame Figure(火焰图)
- java指令:jstack等指令
-
Arthas在presto常用哪些命令
- watch:监控每个函数入参、返回参数、异常等信息
- trace:统计函数内每一步的执行时间
- 通过火焰图如何分析性能瓶颈
火焰图用于分析热点代码占用大量cpu,从而导致服务性能下降的情况。如下图,自底向上为调用关系。上层宽度越宽表示当前函数cpu耗时越久,我们关注最宽的函数调用。
课后
- 能否区分task、pipline、split、driver等worker侧的概念
- 本节课讲授的Presto重要机制有哪些?
- 能否完整的描述一遍Presto多租户调度中的相关流程?
- Pipeline化数据处理是否等价于流式计算?
- 能否实现可中断的正则表达式,性能与普通正则表达式相比如何?
参考文档
- Google File System论文
static.googleusercontent.com/media/resea…
- Google MapReduce 论文
static.googleusercontent.com/media/resea…
- Presto: SQL on Everything 论文
- Presto 应用场景简介
- Presto Local 部署介绍
- Presto 基础概念
- Configuration 构建耗时问题
- Presto Connector实现原理
zhuanlan.zhihu.com/p/143115558
- Presto多级缓存介绍
- Presto : The Definitive Guide
- arthas官方使用文档
- 如何看懂火焰图
cloud.tencent.com/developer/a…
- grafana简介
第二节: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作为通用存储场景,有哪些优缺点?
- 以各大云厂商相关产品为切入点,大数据存储领域发展有哪些趋势?
探索学习
- 进一步了解可观测性工程
-
进一步了解大数据生态一些开源系统,理解它们要解决的问题
- 调度系统AirFlow
- ETL系统 Airbyte
- 数据开发 dbt
- 元数据系统 Apache Altas, LinkedIn DataHub
- 如果想进一步阅读HDFS的源码,可以把源码导入到IDE(例如Intellij IDEA),以基本的读写操作为线索,比如一个hdfs put 命令,按图索骥摸索出实现这个命令的代码。
第三节:HDFS 高可用与高扩展性机制分析
概述
本节课程主要分为四个方面
- HDFS 元数据服务的高可用
- HDFS 数据存储高可用
- HDFS 元数据服务的高扩展性
- 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
课中
课件结构
-
元数据高可用(P6~23)
- 1.1 高可用的需求
- 1.2 HDFS 的高可用架构
- 1.3 自动主备切换
- 1.4 高可用日志系统 BookKeeper 简介
-
数据高可用(P24~34)
- 2.1 单机存储的数据高可用机制
- 2.2 HDFS 的数据高可用机制
- 2.3 考虑网络架构的数据高可用
- 2.4 案例:字节跳动的 HDFS 多机房实践
-
元数据扩展性(P36~45)
- 3.1 元数据扩展性的挑战
- 3.2 社区解决方案
- 3.3 Proxy 方案介绍
- 3.4 案例:小文件问题
-
数据扩展性(P46-P59)
-
4.1 超大集群的长尾问题
-
4.2 超大集群的可靠性问题
-
4.3 超大集群的不均匀问题
- 案例:数据分布不均导致慢节点问题
-
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 来描述状态的新旧。
- 高可用:多个副本确保了高可用(后文会再次介绍多副本高可用)。
- 高性能:不用等所有副本写入成功,降低了的长尾延迟(后文会再次介绍长尾延迟)。
- 参考:Quorum 协议
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 上。
- 条带化:原本块对应文件内连续的一大段数据。条带化后,连续的数据按条带(远小于整个块的单位)间隔交错的分布在不同的块中。
- Reed Solomon 算法:参考 Reed-solomon codes
- 成本更低:多副本方案需要冗余存储整个块,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
- ByteDance 自研的 HDFS 代理层,于 2016 年开源,项目地址: github.com/bytedance/n…
- 主要提供了路由管理、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、磁盘、网络的利用率越高,成本更低。
- 集群需要为数据腾挪预留的空间、带宽更少,降低了成本。
-
可靠性
- 全速运行的机器和空置的机器,以及一会全速运行一会空置的机器,可靠性表现都有不同。负载均衡可以降低机器故障的发生。
- 同一批机器容易一起故障,数据腾挪快,机器下线快,可以提升可靠性。
- 负载均衡性影响因素:多个复杂因素共同影响负载均衡性
- 不同节点上的业务量的平衡
- 数据放置策略
- 数据搬迁工具的能力
- 系统环境
集群的不均衡情况
-
节点容量不均:机器上的数据量不均衡。
- 原因可能是各种复杂情况导致,归根结底是混沌现象。
-
数据新旧不均:机器上的数据新旧不均匀。
- 例如:新上线的机器,不做任何数据均衡的情况下,只会有新写入的数据。而一般新数据更容易被读取,更为「热」。
-
访问类型不均:机器上的数据访问类型不均。
- 例如:机器学习训练需要反复读取数据,小 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 发起副本迁移的命令,批量执行副本迁移。
- 场景:大规模数据平衡、机器上下线。
课后
- 达到 99.99% 可用性的服务,一年中的不可用时间是多久?
- 北京和上海的网络延迟下限是多少?
- 什么是 ZKFC,它和哪几个组件交互?
- 什么是高可用集群中的 fence 机制?
- HDFS NameNode 如何选择数据放置的 DataNode 时,需要考虑的因素有哪些?
- 什么是路径的最长匹配?和字符串的最长匹配有什么区别?举例说明
- 小文件过多会对 NameNode 和 DataNode 造成什么影响?
- 慢节点的成因可能有什么?
- 对比完全随机放置和 copyset 放置的特点。
- 新节点上线就是扩容完成了么?还需要做什么工作?
参考文献
高可用与分布式
- 《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》