美文网首页
高网络时延情况下提升HDFS IO速度

高网络时延情况下提升HDFS IO速度

作者: xudong1991 | 来源:发表于2021-09-07 09:16 被阅读0次

    背景

    有时候,Hadoop 的计算集群和存储集群之间,可能会有非常大的网络延迟(例如异地部署的情况),会影响 HDFS IO 效率。具体而言:

    1. 网络时延很高,相对于本地访问,可能增加10倍以上。
    2. 网络带宽并不紧张,没有打满。

    很自然的,在这种情况下,可以通过多线程并发读/写的方式,更加充分的使用网络带宽,从而加快业务 IO 完成速度,目前主要有下面几种方案。

    HDFS EC 方案(推荐)

    优势

    对于这个需求,EC 基本上可以说量身定制,以提高带宽占用为代价,使用并发读写的方式加快客户端的读写速度,这本身就是 EC 擅长的。以默认的 6+3 策略为例:

    1. 客户端写入时,相对于3副本的单线程写,EC 是9倍并发写,在高网络时延、低带宽使用的情况下,可以大幅度提升写入速度。
    2. 客户端读取时,相对于3副本的单线程读,EC 是6倍并发读,同样能大幅度提升读取速度。
    3. HDFS EC 可以做实时 EC,也可以做离线 EC,具体的策略可以精确配置到目录级别。

    可能存在的问题

    1. EC 会失去计算和存储的本地性
      实际上异地访问本来就没有本地性,因此非问题。

    2. 由于客户端使用多线程并发读写,会比较显著的提升集群整体的带宽占用,特别是客户端机器的带宽占用。
      这正是我们的目的,因此非问题。

    3. 目前,HDFS EC 不支持客户端的 append、hflush、hsync 操作,具体即:

      1. 对 EC 文件 append 会抛异常,导致业务失败(目前有社区 patch 在推进解决)。
      2. 对 EC 文件 hflush()、hsync() 为空操作,直接返回。
    4. 由于上述第三点限制,并非所有业务都能使用实时 EC,此时只能使用离线 EC,具体即:

      1. 需要明确业务是否会使用 append 追加写入方式,如果会,则该业务的目标目录不能配置 EC,一般情况下,很少有业务会使用追加写。
      2. 需要明确业务是否对 hflush、hsync 等有强需求,如果有,则该业务的目录不能配置 EC,一般情况下,很少有业务会对此有强需求。 hflush() 和 hsync() 的主要用途是在业务进程意外崩溃的情况下,确保 hflush()、hsync() 之前的数据已固化,但在实际使用过程中,如果业务进程异常崩溃,则它正在写入的文件无法确保完整性,此时正常的流程应该是让业务重跑,重新生成正确的文件。
    5. 如果业务使用离线 EC,那么此时的问题是:

      1. 离线 EC 需要等待数据变冷之后,再将副本文件转换为 EC 文件,在此之前,客户端仍然只能用副本方式读写。
      2. 离线 EC 完成后,客户端可以使用 EC 方式读取数据,此时才能享受到加速效果。
      3. 离线 EC 完成后,生成的 EC 文件不支持 append 追加写入。
    6. 总结

      1. EC 基本可以认为是为此场景量身定制,完全满足需求。
      2. 有 append 和 hflush()、hsync() 需求的业务,只能使用离线 EC. 业务一般情况下不会对 hflush()、hsync()有强需求,因此需要重点关注 append。

    附:分别从清远、深圳、重庆,通过副本方式、EC方式访问清远 HDFS 集群对比:

    可以看到:

    1. 同机房的读写速度肯定是最高的,这个确定无疑。
    2. 从重庆访问清远 HDFS 集群时,相比从深圳访问,其 IO 速度大概只有 1/3 -1/2。
    3. 客户端和集群之间的网络延迟较高时,EC 的 IO 速度大概是副本的 4-5倍(三副本对比 6+3 EC,前提是带宽够用,没有打满)。
    4. 综上所述,异地 EC 读写的速度可以基本可以打平本地副本读写速度。

    类 distcp 方案(即:在文件级别实现并发 put/get,不太推荐)

    模仿 distcp,在文件级别并发执行 put/get,举例:针对100个文件,启动10个线程负责 put/get,每个线程平均负责10个文件,相比于单线程,速度可以有10倍提高。

    优势

    1. 不需要额外启用 EC,distcp 对 EC 文件和副本文件都可用。
    2. 并发强度可以灵活配置。

    劣势

    1. 只能以命令行的方式提供,供管理员手动执行。如果业务直接调用 FileSystem API,则无效,此时依然只能使用老的单线程写入、读取。
    2. 有一定的编码工作量。

    重构 HDFS 客户端方案(即:在 HDFS 流水线级别实现并发读写,直接否决)

    纵观业界的存储方案,无论是 Ceph,Ozone 等等,无一例外是使用 master 副本 + slave 副本 的方式来保证数据的强一致性,基本没有像 HDFS 这样使用流水线机制的,原因也很简单:流水线机制实在过于复杂,实现难度、错误处理与恢复复杂度、后续维护难度等都太大,社区对这部分代码的修改一直都是持非常谨慎的态度,现在如果要对流水线机制动刀的话,风险太大,承受不起。

    如果要强行去做这件事情,那么,几个重大的修改点是:

    1. 客户端和 DN 之间,不能再像现在这样,只使用一个 socket 来传输数据,而是需要同时使用多个 socket 并行传输,例如每个 socket 传输一个 HDFS packet。需要注意的是,如果只是多线程使用一个 socket,那没有任何意义,因为在这种高网络时延的条件下,无论是单线程还是多线程,都会在瞬间打满客户端的 socket 发送缓存,然后陷入等待,所以必须同时使用多个 socket 并行传输数据。

    2. 使用多个 socket 并行传输数据时,需要考虑到多个 packet 的乱序和重排,以及某个 packet 丢失之后的处理等等,类似于迅雷的多线程并发下载技术。

    相关文章

      网友评论

          本文标题:高网络时延情况下提升HDFS IO速度

          本文链接:https://www.haomeiwen.com/subject/bxeewltx.html