记一次linux tcp和kafka调参

时间:2020-07-11
本文章向大家介绍记一次linux tcp和kafka调参,主要包括记一次linux tcp和kafka调参使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

线上kafka集群事故,很快根据kafka和dmesg linux内核日志定位到表面原因,

[Tue Jun 30 19:22:29 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:31 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:31 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:32 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:32 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:35 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:36 2020] TCP: out of memory -- consider tuning tcp_mem
[Tue Jun 30 19:22:46 2020] TCP: out of memory -- consider tuning tcp_mem

“TCP: out of memory -- consider tuning tcp_mem”,内核报OOM,同时刻kafka也抛OOM异常,整个集群不可用。

这里有2个点待探究,

1. 什么原因导致的 TCP: out of memory

2. 一个broker的OOM为何导致集群不可用。TCP: out of memory现象消失后,kafka为何没从假死中恢复

由于dmesg是内核打印的信息,从github linux内核代码中找到代码位置,https://github.com/torvalds/linux/blob/cb8e59cc87201af93dfbb6c3dccc8fcad72a09c2/include/net/tcp.h#L282

static inline bool tcp_out_of_memory(struct sock *sk)
{
    if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
        sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
        return true;
    return false;
}

异常原因是 sk->sk_wmem_queued > SOCK_MIN_SNDBUF。TCP的发送缓冲区满了,查看其默认tcp_mem配置为:

# sysctl -a |grep tcp_mem

net.ipv4.tcp_mem = 377607 503478 755214。 单位是page,1page = 4096字节(# getconf PAGESIZE  4096)

查看实际的内存使用:

# cat /proc/net/sockstat
sockets: used 2328
TCP: inuse 458 orphan 19 tw 6529 alloc 2115 mem 25693(无法还原故障现场)
UDP: inuse 5 mem 22
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

按照dmesg提示,猜测可以通过调整一个较小的tcp_mem来复现故障。

# vim /etc/sysctl.conf

net.ipv4.tcp_mem = 1 2 2

运行一段时间后,故障复现。kafka集群OOM不可用,同时dmesg报相同的错误信息“TCP: out of memory -- consider tuning tcp_mem”。

所以OOM产生的原因是,tcp_mem缓冲区设置较小,网络拥堵导致sk_wmem_queued消息堆积。暂时的规避措施是调大tcp_mem。

kafka未从故障中恢复过来,可能是因为其Bug导致,可以加一项启动参数"-XX:+ExitOnOutOfMemoryError"让其在OOM时自动退出,同时配置监控和自动拉起机制,保证集群可用性。

参考:

https://blog.tsunanet.net/2011/03/out-of-socket-memory.html, 分析了TCP out of memory可能的原因

https://unix.stackexchange.com/questions/551444/what-is-the-difference-between-sock-sk-wmem-alloc-and-sock-sk-wmem-queued,介绍了sk_wmem_queue是什么,sk_wmem_queue满是TCP OOM的原因

https://github.com/torvalds/linux/blob/cb8e59cc87201af93dfbb6c3dccc8fcad72a09c2/include/net/tcp.h#L282,dmesg异常打印的linux kernel代码位置

原文地址:https://www.cnblogs.com/gm-201705/p/13282541.html