深度优化Hadoop DataNode读写性能

发布于:2024-05-21 ⋅ 阅读:(164) ⋅ 点赞:(0)

需要深入研究Hadoop集群的存储节点并做相应的优化,减少新机型带来的性能压力。NameNode的优化可以参考(深度优化Hadoop NameNode读写性能

1. 现状分析

为了解决上述提到的问题,需要分析Hadoop DataNode(后面简称DN)内核运行原理。我们知道DN主要用于接收用户的数据写入,并与NameNode(后面简称NN)节点定期通信,拿到执行命令。现网HA场景下,其基本的架构如下:

  1. BPServiceActor会根据集群NN的配置而实例化多个,集群有3个NN则会实例化出三个NN

  2. BPServiceActor主要用于从NN处获取Command(对数据的增删改查,迁移等等),上报心跳、IBR(增量块汇报)以及FBR(全量块汇报)

  3. FsDataSet接口负责承接用户请求,并将对应的读写等操作落实到具体的volume上来,并对DN本省维护的一些块信息做更新操作(块大小,时间戳,完成状态等)

用户client创建文件时,会从NN上拿取待写入的DN信息。client拿到信息之后,会直接连接DN节点发起写请求,DN会根据volume的负载(一般是当前volume已使用空间),

选择负载较低的磁盘写入。写入完毕之后,会触发IBR发送给NN。当我们增加单机volume个数时,会带来如下问题挑战:

  1. FsDataSet使用全局锁控制volume读写,增加volume个数无疑会增加锁竞争,且会拖慢并行写入的吞吐,降低单机的性能

  2. volume增多之后,IBR以及FBR也会相应的增加,这对NN和DN通讯也会带来更大的压力

  3. 机器磁盘故障时,影响的数据量级比之前增加很多,需要做到快速恢复

尤其对于全局锁的使用,会给dn的读写造成比较大的影响,我们jstack追踪了一下dn的线程,可以看到线程之间blocking关系图如下,数据接收和写入线程均受到全局锁的影响:

2. 方案思考

2.1. 拆锁

针对全局锁的问题,可以考虑做拆锁方案,减少FsDataSet读写数据时引起的锁竞争与锁等待。从结构上来看,FsDataSet划分数据有两个层面上的聚合,第一个是BlockPool级别,第二个是Volume级别。对于federation集群来说,一个集群会

有>1的BlockPool。对于非federation集群来说,一个集群只有一个BlockPool。BlockPool本身会包含着多volume,结构划分如下:

对于这样的结构划分,很自然地,也会考虑拆解为BlockPool级别的(父)锁以及Volume级别的(子)锁。按照场景我们来确定一下不同的加锁规则:

  1. 对于一个volume内的数据读写操作,我们需要对该操作加volume级别的读写锁和BlockPool级别的读锁(优化的关键,一个volume内的数据读写,本质上没有改变BlockPool级别的元数据逻辑,因此只需要加读锁)

  2. 对于多个volume间的数据读写操作,例如dn内部的数据迁移,则需要加BlockPool级别的写锁,此时则不能加volume级别的锁

  3. 对于BlockPool级别的元数据变更,例如BlockPool清理,BlockPool添加等,这个属于BlockPool级别改动,需要加BlockPool级别的写锁。部分场景下需要加dn进程级别的全局锁

细粒度的拆锁,可以缓解竞争锁带来的额外耗时,特别是高密度场景下的dn节点,volume越多,原版本带来的锁问题越大。通过拆锁,可以实现吞吐随磁盘增加而线性增加,为用户提供更加稳定的访问。

社区版本提过类似的思想:[HDFS-15382] Split one FsDatasetImpl lock to volume grain locks. - ASF JIRA,但在branch-3版本上并未做实现,社区draft版本可能存在未解决的死锁的问题。天穹Hadoop基于这种设计理念,在hadoop-3.2版本中实现了拆锁逻辑。运行稳定之后会反馈给社区

2.2. 配置优化

高密度机型下,单机上报的block数也会超长。因此跟namenode相关交互配置,也需要做一些调整。

配置项目

推荐值

备注

dfs.blockreport.incremental.intervalMsec

300

IBR延迟批量上报,写单dn的数据量会随着volume增加而加大,增加此项,可减少namenoode rpc请求压力

ipc.server.listen.queue.size

2048

提升DN backlog配置参数,防止dn因并发连接过多导致SYNC丢包问题

dfs.blockreport.initialDelay

600

block report推迟上报的加盐参数(random delay取值范围),防止出现dn同时上报blockreport,引起block report storm

dfs.namenode.full.block.report.lease.length.ms

1800000

block report租约过期时间,此租约功能主要为了解决block report storm而出现。单机block增多,需要的租约时间时间也需要相应增大

dfs.namenode.replication.max-streams

500

高优复制流上限配置,用于降低单盘故障影响时间

dfs.namenode.replication.max-streams-hard-limit

1000

整体复制流上限配置,用于降低单盘故障影响时间

dfs.namenode.replication.work.multiplier.per.iteration

5

立即下发的待复制block数=存活的dn数x此配置值,用于降低单盘故障影响时间

3. 优化效果

发起1TB teragen高IO写入测试
1. 使用现网机型(4TB * 12磁盘,block配置为128MB),有30%左右的性能提升

2. 使用高密度机型(12TB * 36),因手上client测试机器有限,单block改为1MB来模拟并发场景,有47%左右的性能提升

通过上面的测试,也可感知到,磁盘负载越高,并发创建越多,优化性能越明显。锁的耗时主要来源于两个方面,第一个是频繁的锁申请,第二个是锁内存在的磁盘读写。并发越高,磁盘IO越高,锁耗时占比也就越高,拆锁带来的收益也越大。后面我们将发起系列测试验证新版本的稳定性和性能提升效果

4. 后续

拆锁带来的问题主要有两个,一个是死锁问题,另外一个就是并发修改问题。前者可能引起dn进入假死状态,后者可能会导致元数据混乱问题,因此,需要提前做一些操作预防和发现此类问题。针对死锁问题,需要引入锁检查,当某线程长时间持有锁时,需要有相应的日志落地。此版本也需要充分测试后,才能到现网环境中做升级。