zoukankan      html  css  js  c++  java
  • 记一次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代码位置

  • 相关阅读:
    Git 操作
    SVN
    一维数组
    常见的数学方法
    常用事件
    function函数
    while;do while; for循环
    JS中的变量提升
    关于js的单双引号嵌套问题
    db.collection is not a function
  • 原文地址:https://www.cnblogs.com/gm-201705/p/13282541.html
Copyright © 2011-2022 走看看