如何调整linux网络缓冲区大小

时间:2017-11-17 11:50:59

标签: linux sockets kernel

我正在阅读第35页(网络部分)中的“Kafka The Definitive Guide”,它说:

  

...第一个调整是更改默认和最大金额   为每个套接字分配的发送和接收缓冲区的内存。这将显着提高大型转移的性能。每个套接字的发送和接收缓冲区默认大小的相关参数是net.core.wmem_default和   net.core.rmem_default ......   除套接字设置外,还必须使用net.ipv4.tcp_wmem和net.ipv4.tcp_rmem参数单独设置TCP套接字的发送和接收缓冲区大小

为什么要设置net.core.wmem和net.ipv4.tcp_wmem?

1 个答案:

答案 0 :(得分:5)

简短回答 - r / wmem_default用于设置静态套接字缓冲区大小,而tcp_r / wmem用于控制TCP发送/接收窗口大小和缓冲区动态

更多详情: 通过跟踪r / wmem_default和tcp_r / wmem(内核4.14)的用法,我们可以看到r / wmem_default仅用于sock_init_data():

void sock_init_data(struct socket *sock, struct sock *sk)
{
        sk_init_common(sk);
        ...
        sk->sk_rcvbuf           =       sysctl_rmem_default;
        sk->sk_sndbuf           =       sysctl_wmem_default;

这会初始化套接字的缓冲区以发送和接收数据包,稍后可能会在set_sockopt中重写:

int sock_setsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, unsigned int optlen)
{
        struct sock *sk = sock->sk;
        ...
        sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
        ...
        sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);

在这些函数中可以找到tcp_rmem的用法:tcp_output.c中的tcp_select_initial_window()和tcp_input.c中的__tcp_grow_window(),tcp_fixup_rcvbuf(),tcp_clamp_window()和tcp_rcv_space_adjust()。在所有用法中,该值用于动态地控制接收窗口和/或套接字的接收缓冲区,这意味着它将考虑当前流量和系统参数。 对tcp_wmem的类似搜索表明它仅用于tcp_init_sock()(tcp.c)和tcp_sndbuf_expand()(tcp_input.c)中套接字发送缓冲区的动态更改。

因此,当您希望内核更好地调整流量时,最重要的值是tcp_r / wmem。套接字的大小通常被用户覆盖,默认值并不重要。对于精确的调整操作,请尝试读取tcp_input.c中标记为" tuning"的注释。那里有很多有价值的信息。

希望这有帮助。