NameNode性能优化

可选方法

  1. namenode的RPC可以细分为3类,使用独立的服务来处理请求,可以提高吞吐;
    • clientRpc,用来处理hdfs client的请求,部分请求如果耗时较长,可能会阻塞其他服务的请求,造成一些不良影响;
    • serviceRpc,hdfs服务之间的RPC请求,通过修改配置 dfs.namenode.servicerpc-address 开启,可以将后台服务之间的RPC请求隔离开;
    • lifelineRpc,一个可选的服务,主要用来解决datanode、namenode之间的心跳延迟问题(lifeline protocol成本更低,无需跟其他请求抢锁,独立的服务单独处理请求更加快速);
  2. 关注namenode的内存使用情况
    • namenode基本配置要求1G内存,每增加100万个block,增加1G内存;
    • 根据jstack $NAMENODE_PID统计分析耗时,关注GC是否需要优化;
  3. 添加Observer角色
    • hdfs上的文件,大多数场景是一次写入,多次读取;
    • 在active namenode流量特别大的情况下,可以考虑部署observer角色、开启dfs.namenode.state.context.enabled,将namenode请求进行分流,降低active节点的压力;
    • 使用observer会增加数据一致性维护的难度,比如以下场景
      1. 有两个hdfs client A、B,A写入新的文件,然后通知B去读取;
      2. 如果observer落后active节点的版本比较多,那么B访问observer得到的response是文件不存在(实际已写入);

hdfs-site.xml相关配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<property>
<name>dfs.namenode.servicerpc-address</name>
<value>vm-16-2-rockylinux:8040</value>
<description>隔离client、services之间的RPC请求</description>
</property>

<property>
<name>dfs.namenode.lifeline.rpc-address</name>
<value>vm-16-2-rockylinux:8050</value>
<description>开启lifeline RPC服务,降低heartbeat message成本</description>
</property>

<property>
<name>dfs.heartbeat.interval</name>
<value>3s</value>
<description>heartbeat message间隔</description>
</property>

<property>
<name>dfs.namenode.handler.count</name>
<value>10</value>
<description>request handler线程,内部实现是阻塞的,QPS较高的时候适当提高线程数可以提高吞吐</description>
</property>

lifeline protocol解决的问题

  1. datanode会定时向namenode发送heartbeat message,配置dfs.heartbeat.interval默认是3秒;
  2. 在比较大的集群,特定情况下,heartbeat message的成本可能比较高
    1. 所有的namenode rpc threads都在忙于处理hdfs client operations,那么heartbeat message会排队阻塞;这种情况一般比较好解决
      • 修改dfs.namenode.servicerpc-address,隔离service、client的请求来缓解;
      • 增大dfs.datanode.handler.count或者dfs.namenode.service.handler.count,增加处理线程缓解问题;
    2. 如果一个hdfs client,长时间维持namesystem的写锁,那么所有的heartbeat message会被阻塞(等待读锁);
      • 类似的,如果一个块报告的请求长时间拿着namesystem的写锁,也会阻塞heartbeat message
  3. 以上各种情况,可能产生的负面问题如下
    1. namenode会延迟更新datanode的last contact time;
    2. 持续一段时间后,心跳延迟的datanode会被错误标记为stale状态,应用会避免访问这些节点(资源浪费);
    3. 持续较长时间后,心跳延迟的datanode会被错误标记为dead状态,在一些极端的情况下,会造成大量不必要的rereplication流量;
  4. JIRA #HDFS-9239 DataNode Lifeline Protocol: an alternative protocol for reporting DataNode liveness