
# 优化HDFS NameNode RPC的服务质量
#### 操作场景
如果多个Hadoop集群由于NameNode超负荷运行并失去响应而发生故障，这种阻塞现象是由于Hadoop的初始设计造成的。在Hadoop中，NameNode作为单独的机器，在其namespace内协调HDFS的各种操作，这些操作包括获取数据块位置、列出目录及创建文件。NameNode接受HDFS的操作，将其视作RPC调用并置入FIFO调用队列，供读取线程处理。虽然FIFO在先到先服务的情况下足够公平，但如果用户执行的I/O操作较多，相比I/O操作较少的用户，将获得更多的服务。在这种情况下，FIFO有失公平并且会导致延迟增加。
图1基于FIFO调用队列的NameNode请求处理   
![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0265788158.png "点击放大")
如果将FIFO队列替换为一种被称作FairCallQueue的新型队列，这种情况就能够得到改善。按照这种方法，FAIR队列会根据调用者的调用规模将传入的RPC调用分配至多个队列中。调度模块会跟踪最新的调用，并为调用量较小的用户分配更高的优先级。
图2基于FAIRCallQueue的NameNode请求处理   
![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0265788159.png "点击放大")
#### 约束与限制
本章节适用于MRS 3.x及后续版本。
#### 操作步骤
- **FairCallQueue通过在内部调整RPC调用的顺序确保服务质量。**
  该队列由以下三部分组成：
  - 调度模块（DecayRpcScheduler）用于提供从0至N的优先值数字（0的优先级最高）。
  
  - 多级队列（位于FairCallQueue内部）保持调用在内部按优先级排列。
  
  - 多路转换器（提供有WeightedRoundRobinMultiplexer）为队列选择提供逻辑控制。
   
  在对FairCallQueue进行配置后，由控制模块决定将收到的调用分配至哪个子队列。当前调度模块为DecayRpcScheduler，该模块仅持续对各类调用的优先级数字进行追踪，并周期性地对这些数字进行减小处理。
  配置步骤如下：
  1. 登录FusionInsight Manager。 登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
     
  
  2. 选择"集群 \> 服务 \> HDFS \> 配置 \> 全部配置"。
  
  3. 搜索以下参数名称，并根据需要修改参数值。
     表1Fair调用队列参数 
     | 参数                            | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | 默认值                                      |
     |:---|:---|:---|
     | ipc.*\<port\>*.callqueue.impl | 队列的实现类。 取值范围： - java.util.concurrent.LinkedBlockingQueue：使用FIFO的顺序处理需求。  - org.apache.hadoop.ipc.FairCallQueue：可通过该方法启用QoS特性。  - org.apache.hadoop.ipc.PriorityCallQueue：如果使用从NameNode，设置为该值时，则会更高效地处理msync请求，提高从NameNode的处理能力。   | java.util.concurrent.LinkedBlockingQueue |
        
     
  
  4. 保存修改的配置。保存完成后请重新启动配置过期的服务或实例以使配置生效。
   

- **RPC Backoff**
  Backoff是FairCallQueue的功能之一，要求客户端在一段时间后重试操作（如创建，删除，打开文件等）。当Backoff发生时，RPC服务器将发生RetriableException异常。FairCallQueue在以下两种情况时进行Backoff。
  - 当队列已满，即队列中有许多客户端调用时。
  
  - 当队列的响应时间大于配置的阈值（由参数"ipc.\<port\>.decay-scheduler.backoff.responsetime.thresholds"决定）时。
  
  
  配置步骤如下：
  1. 登录FusionInsight Manager。 登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
     
  
  2. 选择"集群 \> 服务 \> HDFS \> 配置 \> 全部配置"。
  
  3. 搜索以下参数名称，并根据需要修改参数值。\<port\>表示在NameNode上配置的RPC端口。
     表2RPC Backoff配置 
     | 参数                                                             | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 默认值                     |
     |:---|:---|:---|
     | ipc.*\<port\>*.backoff.enable                                  | 是否启用Backoff功能。Backoff是FairCallQueue的功能之一，要求客户端在一段时间后重试操作（如创建，删除，打开文件等）。 - true：启用。操作失败后，系统根据配置的Backoff响应时间进行重试。  - false：不启用。操作失败后系统立即重试，不进行延迟。   当前，如果应用程序中包含较多的用户调用，假设没有达到操作系统的连接限制，则RPC请求将处于阻塞状态。或者，当RPC或NameNode在重负载时，可以基于某些策略将一些明确定义的异常抛回给客户端，客户端将理解这种异常并进行指数回退，以此作为类RetryInvocationHandler的另一个实现。                                                                                                                                               | false                   |
     | ipc.*\<port\>*.decay-scheduler.backoff.responsetime.enable     | 是否开启根据队列平均响应时间启用Backoff。 - true：启用。当队列平均响应时间超过预设阈值（通过"ipc.*\<port\>*.decay-scheduler.backoff.responsetime.thresholds"参数决定）时，系统会触发Backoff。  - false：不启用。                                                                                                                                                                                                                                                                              | false                   |
     | ipc.*\<port\>*.decay-scheduler.backoff.responsetime.thresholds | 配置每个队列的响应时间阈值。单位：毫秒。 - 通过为不同优先级设置差异化阈值，确保高优先级请求优先获得资源，同时避免低优先级请求因短暂延迟导致系统过载。  - 响应时间阈值必须与优先级数目（ipc.\<port\> .faircallqueue.priority-levels）相匹配。 "ipc.\<port\> .faircallqueue.priority-levels"参数可以在"客户端安装目录/HDFS/hadoop/etc/hadoop/hdfs-site.xml"中查看，默认值为"4"，表示4个优先级（level0\~level3，level0为最高优先级）。    例如：level0匹配10000ms，表示高优先级的请求在响应时间超过10s即触发Backoff。 | 10000,20000,30000,40000 |
        
     
  
  4. 保存修改的配置。保存完成后请重新启动配置过期的服务或实例以使配置生效。
   
 
