HDFSRPC通信框架参数详解

写在前面

请先阅读HDFSRPC通信框架详解,对整体框架先有一定的了解。

参数列表

参数默认值描述
ipc.server.read.connection-queue.size100reader
ipc.server.read.threadpool.size1reader
ipc.server.listen.queue.size128Listener:backlog
ipc.server.tcpnodelaytrueListener
ipc.maximum.data.length64 * 1024 * 1024Connection:rpc data len
dfs.namenode.handler.count10handler nn requests from clients
dfs.namenode.service.handler.count10handler nn requests from DataNodes
dfs.namenode.lifeline.handler.count10handler nn lifeline requests
dfs.datanode.handler.count10handler dn

ipc.server.read.connection-queue.size

reader的处理连接数,默认是100。使用BlockingQueue实现。

final private BlockingQueue<Connection> pendingConnections;

public void addConnection(Connection conn) throws InterruptedException {
    pendingConnections.put(conn);
    readSelector.wakeup();
  }

使用addConnection加入队列,队列满了此方法会阻塞。

ipc.server.read.threadpool.size

reader的线程数,默认为1。reader主要用于连接头,连接上下文的处理,还是要花费一定的时间的,特别在使用Kerberos的时候。reader多线程处理会比较合理,所以笔者认为这个默认值不太合理,设置为不小于1会比较合理。

ipc.server.listen.queue.size

默认值为128,属于listener。本参数虽然叫queuesize,单实际上不是listenr的数量或者listener的队列长度,而是来源于ServerSocket的bind(SocketAddress endpoint, int backlog) 方法中的backlog。listener源码为

private int backlogLength = Config.getInt(
      CommonConfigurationKeysPublic.IPC_SERVER_LISTEN_QUEUE_SIZE_KEY,
      CommonConfigurationKeysPublic.IPC_SERVER_LISTEN_QUEUE_SIZE_DEFAULT);

public Listener(String bindAddress, int port, int readThreads) throws IOException {
    ...
    acceptChannel.socket().bind(address, backlogLength);
    ...
}

backlog参数为如果server.accept()没有及时接收,系统会把socket缓存起来,代表这个缓存队列的大小。如果队列已满,新连接会被拒接。

void doAccept(SelectionKey key) throws InterruptedException, IOException,  OutOfMemoryError {
    ServerSocketChannel server = (ServerSocketChannel) key.channel();
    SocketChannel channel;
    while ((channel = server.accept()) != null) {

      channel.configureBlocking(false);
      channel.socket().setTcpNoDelay(tcpNoDelay);
      channel.socket().setKeepAlive(true);
      
      Reader reader = getReader();
      Connection c = Server.connectionManager.register(channel);
      // If the connectionManager can't take it, close the connection.
      if (c == null) {
        if (channel.isOpen()) {
          IOUtils.cleanup(null, channel);
        }
        Server.connectionManager.droppedConnections.getAndIncrement();
        continue;
      }
      key.attach(c);  // so closeCurrentConnection can get the object
      reader.addConnection(c);
    }
  }

看doAccept方法,Connection接收到了以后会放入connectionManager,如果connectionManager的队列满了(ipc.server.max.connections)会直接关闭连接,ipc.server.max.connections默认值为0,代表没有上限。reader.addConnection代表连接会放入reader的pendingConnections,pendingConnections为BlockingQueue,满了会阻塞,默认值为100。所以默认值情况下,可以处理100+128个连接,超过了以后会被拒绝。如果ipc.server.max.connections设置为50,此值会直接失效,因为连接超过50以后,会直接关闭连接。

ipc.server.tcpnodelay

连接的TcpNoDelay属性,默认为true。

channel.configureBlocking(false);
channel.socket().setTcpNoDelay(tcpNoDelay);
channel.socket().setKeepAlive(true);

对应的就是TCP_NODELAY,本质上设置是否使用Nagle 算法,缓存数据合并发送。建议使用默认值true,关闭Nagle 算法。

ipc.maximum.data.length

请求的数据最大长度,默认是64MB。

this.maxDataLength = Config.getInt(CommonConfigurationKeys.IPC_MAXIMUM_DATA_LENGTH,
        CommonConfigurationKeys.IPC_MAXIMUM_DATA_LENGTH_DEFAULT);

private void checkDataLength(int dataLength) throws IOException {
    if (dataLength < 0) {
      String error = "Unexpected data length " + dataLength +
                     "!! from " + getHostAddress();
      LOG.warn(error);
      throw new IOException(error);
    } else if (dataLength > maxDataLength) {
      String error = "Requested data length " + dataLength +
            " is longer than maximum configured RPC length " + 
          maxDataLength + ".  RPC came from " + getHostAddress();
      LOG.warn(error);
      throw new IOException(error);
    }
  }

如果长度超过最大长度,server不会返回任何数据,会直接关闭连接。

handler.count

handler的数量,默认为10。有4个参数,分别为dfs.namenode.handler.count,dfs.namenode.service.handler.count,dfs.namenode.lifeline.handler.count,dfs.datanode.handler.count 。handler是用于实际处理rpc请求的,比如createfile,mkdir等。这些操作都是要花费一定的时间,而且随着存储文件数,存储集群的变大,理论上会变慢。所以handler.count可以设置的大一点。当然建议dfs.namenode.handler.count设置大一点就行,dfs.namenode.handler.count主要用于处理客户端请求,网上建议设置为20logN,N为集群服务器数量。其他都是集群内部的请求处理,没有特殊情况,使用默认值即可。

  • 26
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zfpigpig

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值