HDFSRPC通信框架参数详解

写在前面

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

参数列表

参数 默认值 描述
ipc.server.read.connection-queue.size 100 reader
ipc.server.read.threadpool.size 1 reader
ipc.server.listen.queue.size 128 Listener:backlog
ipc.server.tcpnodelay true Listener
ipc.maximum.data.length 64 1024 1024 Connection:rpc data len
dfs.namenode.handler.count 10 handler nn requests from clients
dfs.namenode.service.handler.count 10 handler nn requests from DataNodes
dfs.namenode.lifeline.handler.count 10 handler nn lifeline requests
dfs.datanode.handler.count 10 handler 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为集群服务器数量。其他都是集群内部的请求处理,没有特殊情况,使用默认值即可。

未经允许禁止转载~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇