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

4
我正在阅读《Kafka权威指南》,第35页(网络部分)提到:
第一个调整是更改为每个套接字分配的发送和接收缓冲区的默认和最大内存量。这将显着提高大型传输的性能。每个套接字的发送和接收缓冲区默认大小的相关参数是net.core.wmem_default和net.core.rmem_default。 除了套接字设置之外,必须单独设置TCP套接字的发送和接收缓冲区大小,使用net.ipv4.tcp_wmem和net.ipv4.tcp_rmem参数。
为什么我们应该同时设置net.core.wmem和net.ipv4.tcp_wmem?
1个回答

11
简短回答: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中的注释。那里有很多有价值的信息。

希望这可以帮助到您。


哇,太棒了!非常感谢!! - esavier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接