使用 FairCallQueue 提升 NameNode RPC

2021-09-06  本文已影响0人  xudong1991

问题描述

HDFS 集群中,有时会因为 NameNode 的超负荷运行,导致部分用户的请求响应缓慢,甚至得不到响应。

原因分析

这种阻塞情况是由于 Hadoop 的初始设计造成的。

在 HDFS 中,NameNode 作为单独的机器,在其 NameSpace 内部协调 HDFS 的各种操作,这些操作包括获取数据块位置、列出目录、创建文件等等。NameNode 接收各个 HDFS Client 的请求,将这些请求视作 RPC 调用置入 FIFO 队列,供处理线程处理。虽然 FIFO 在先到先服务的情况下足够公平,但如果某个用户执行的 I/O 操作较多,那么相比其他 I/O 操作较少的用户,他将获得更多服务,在这种情况下,FIFO 有失公平性并且会导致其它用户的延迟大大增加。

基于 FIFO 调用队列的 NameNode 请求处理过程如下:


解决方案

如果将 FIFO 队列替换为一种被称为公平队列(FairCallQueue)的新型队列,这种情况将会得到改善。

按照这种新型方法,Fair 队列会根据调用者的调用规模,将其传入的 RPC 请求分配至多个队列中,调度模块会跟踪最新的调用,并为调用量较小的用户分配更高的优先级。

基于 Fair 队列的 NameNode 请求处理过程如下:


Fair 调用队列通过在内部调整 RPC 调用的顺序确保服务质量。
该队列由三个部分组成:

  1. 调度模块(默认为 DecayRpcScheduler),用于提供从 0 至 N 的优先级数字(0 的优先级最高)。
  2. 多级队列(位于 FairCallQueue 内部),保持 RPC 请求在内部按优先级排列。
  3. 多路选择器(默认为 WightedRoundRobinMultiplexer),取出一个 RPC 请求时,为目标队列的选择提供逻辑控制。

在对 Fair 调用队列进行配置后:

  1. 由调度模块决定将新收到的 RPC 请求分配至哪个子队列,当前调度模块为 DecayRpcScheduler,该调度模块会持续对各个用户的调用优先级进行追踪,并周期性调整统计数据。
  2. 由多路选择器决定下一个要处理的 RPC 请求从哪个子队列出队。

相关配置

下表中的 port 代表 RPC 服务端口,对于 NameNode 来说,即为9000

配置项 描述 默认值
ipc.< port >.callqueue.impl 队列的实现类,需要配置为 org.apache.hadoop.ipc.FairCallQueue LinkedBlockingQueue
ipc.< port >.faircallqueue.priority-levels FairCallQueue 中队列的个数,其值必须大于等于1 4
ipc.< port >.identity-provider.impl identity provider 的实现类,用于区别 NameNode 上的多个 RPC 调用,当配置为 UserIdentityProvider 时,identity provider 会基于用户为每个调用分配一个标识 org.apache.hadoop.ipc.UserIdentityProvider
ipc.< port >.faircallqueue.multiplexer.weights 各个队列的权值,决定了多路选择器对各个队列的轮询次数 该值基于队列数量,在默认情况下,从队列0到队列3,其权值依次为为 8、4、2、1,即队列0轮询8次,然后接着队列1轮询4次,接着队列2轮询2次,最后队列3轮询1次,周而复始
ipc.< port >.faircallqueue.decay-scheduler.thresholds 描述各个优先级队列的进入条件,取决于当前用户的调用次数占总的 RPC 调用次数的比例 取决于队列数量,默认情况下队列数为4,从队列3到队列1,进入的阈值为 0.5、0.25、0.15,即:若当前用户调用次数占总调用次数的比例超过0.5,则此次调用进入队列3,若超过0.25,则进入队列2,若超过0.15,则进入队列1,否则,进入队列0(0是最高优先级队列)
ipc.< port >.faircallqueue.decay-scheduler.period-ms 调度器会周期性的对每个用户的调用统计次数进行处理,逐步淘汰老的统计数据,这个配置决定了扫描周期 5000
ipc.< port >.faircallqueue.decay-scheduler.decay-factor 每次扫描时,每个用户的统计调用次数都会衰减一次,这样如果一个用户很久没有产生新的调用,那么若干次以后,他的统计数据就会被清掉,这个配置决定了衰减比例 0.5

具体配置

公平队列在在较新的 Hadoop 版本中已经 ready,只是默认没有启用,如果要启用,其它配置项都可以保持默认,只需要配置上面表格中的第一项就可以了,即在 core-site.xml 中配置以下属性:

  <property>   
    <name>ipc.9000.callqueue.impl</name>    
    <value>org.apache.hadoop.ipc.FairCallQueue</value>   
  </property> 

举例说明

假设全部使用默认配置,则:

  1. RPC 请求入队流程
    调度模块按照当前用户的调用次数占总的 RPC 调用次数的比例,决定将 RPC 请求入到哪个队列:

    1. 若比例超过0.5, 则此次调用进入队列3。
    2. 若超过0.25,则进入队列2。
    3. 若超过0.15,则进入队列1
    4. 否则,进入队列0.
    5. 若目标队列已满(每个队列最大长度都为1000),则顺延至下一优先级队列,若连队列3都满了,那就等待,直到队列3有可用空间为止。
  2. RPC 请求出队流程
    多路选择器按照各个优先级队列的权重,进行轮询,即:

    1. 队列0轮询8次,然后接着队列1轮询4次,接着队列2轮询2次,最后队列3轮询1次,周而复始。
    2. 若目标队列此时为空,则顺延至下一优先级队列取出一个 RPC 请求。
  3. 效果
    按照默认配置,在极端情况下,一个频繁访问的用户的响应速度可以降低到 1/15,NameNode 将腾出更多的处理能力给其它用户,所谓极端情况是指此时用户数足够,其他用户也有适量的 RPC 请求的情况。

上一篇 下一篇

猜你喜欢

热点阅读