这是我参与「第四届青训营」笔记创作活动的第8天,学习内容为《HDFS高扩展性机制》,内容包括 元数据高扩展性、数据存储高扩展性。
思维导图如下:
元数据高扩展性
元数据扩展性挑战
- HDFS NN是集中式服务,部署在单个机器上,内存和磁盘容量、CPU的计算能力都不能无限扩展;
- 解决:scale up、scale out。前者是扩容单个服务器提升能力,后者是部署多个服务器来服务(分布式),业界采用后者;
- scale out 挑战:
- 名字空间分裂
- DataNode汇报
- 目录树结构本身复杂
- 常见scale out方案
- kv模型可以使用partition
- 三种数据路由方式:服务侧端、路由层、客户端侧
社区的解决方案
BlockPool
- 同一个block id 在不同的NN上出现,解决DN同时服务多组NN的问题,即多个NN可能生成同一个block id,DN无法区别;
- 将文件服务分层:
- Namespace:存放目录树结构,一个文件对应哪些块,块的id;
- Block Stroage:块在哪个DN上,DN集群对不同的NN提供不同的标识符
- 用blockpool来区分DN的服务:数据块存储、心跳和块上报
viewfs
- 路由信息保存在client侧,指定不同目录访问不同的NameNode;
- Federation架构:对外表现像一个集群,难点在于跨多个集群的请求。
字节跳动的NNProxy方案
- 主要实现路由管理和RPC转发;
- 路由规则保存
- 路由信息保存在路由层
- Proxy本身不存储路由信息,而是存在存储节点上
- 每次将不同路由信息存储在zookeeper上,proxy定期更新信息,并根据信息进行转发
- 路由转发实现
- 路径最长匹配规则,可以进一步划分目录树(路径匹配最长,对应的namenode)
- 思考:单个NN不会遇到瓶颈吗、跨集群rename
小文件问题
- 小文件:大小不到一个HDFS Block大小的文件;
- 问题:
- NN瓶颈
- I/O变成小的随机IO,数据访问变慢
- 计算任务启动慢
- MapReduce的Worker数量过多容易引起小文件问题
- 解决方案:
- 后台任务合并小文件
- Shuffle Service
数据存储高扩展性
超大集群的长尾问题
- 长尾延迟:尾部的延迟(p99/p999),衡量系统最差的请求的情况,显著差于平均值;
- 尾部延迟放大:访问的服务变多,尾部的请求就会越发的慢(一个请求可能等效访问多个服务,有一个很慢,整个流程就慢);
- 如何变慢:固定延迟阈值;固定延迟百分位;
- 长尾问题的表现--慢节点:
- 读取速度过慢,导致客户端阻塞;
- 慢节点的发生难以避免和预测;
- 离线任务也会遇到长尾问题;
- 集群扩大10倍,问题扩大N(>10)倍.
超大集群的可靠性问题
- 条件:
- 有一部分机器损坏来不及修理
- 副本放置策略完全随机
- DN的容量足够大
- 解决:Copyset
- 将DataNode分为若干个Copyset选块在copyset内部选择
- 减少了副本放置的组合数,降低副本丢失概率;
- 缺陷:如果一个copyset挂了,所有数据丢失;数据修复速度受影响,被限制在相应的copyset修复;
- 数据丢失量和故障发生概率控制在一定量级
超大集群的不均匀分布问题
- 负载均衡:避免热点(避免单个节点访问过高,慢节点问题)、可靠性(数据均衡,copyset)、降低成本
- 数据写入/读取不均匀
- 节点容量不均匀
- 数据新旧不均匀
- 访问类型不均匀
- 其他:异构机器、资源不均
- 需要数据迁移的典型场景:DN上线、DN下线、机房间均衡、日常打散
数据迁移工具
- 跨NN迁移:
- DistCopy:通过 MapReduce 任务来并行迁移数据,需要拷贝数据和元数据,网络流量较大,速度较慢;
- FastCopy:元数据直接在 NN 集群间拷贝,而数据则在 DN 上的不同 blockpool(对应到 NN 集群)进行 hardlink,不用数据复制,迁移速度要大大优于 DistCopy。
- Balancer工具:代替 NN 向 DN 发起副本迁移的命令,批量执行副本迁移,平衡各个DataNode容量。
总结:HDFS作为大数据离线分析场景的核心组件,其高扩展性确保了HDFS能存储的数据量随着资源投入无限扩展下去,业务发展不被基础组件拖累。