systemtap查看udp rcvbuf满导致丢包

折腾了老半天,被atomic_t坑惨啦,匿名结构体必须要用cast转换类型,然后再访问成员,用来排查udp buffer满,导致丢失日志的场景

#!/usr/bin/env stap

probe kernel.statement("udp_queue_rcv_skb@net/ipv4/udp.c:1569")
{
    printf("rmem_alloc:%d rcv_buf:%d drops:%d\n", @cast(&$sk->sk_backlog->rmem_alloc, "atomic_t", "kernel<linux/types.h>")->counter,  $sk->sk_rcvbuf, @cast(&$sk->sk_drops, "atomic_t", "kernel<linux/types.h>")->counter)
}

 

发表在 debug, 好玩的linux | 留下评论

systemtap查看socket 信息

通过systemtap查看socket信息的脚本,跟踪在sendmsg跟recvmsg,示例中只有sndbuf跟rcvbuf,实际上可以拓展到任意的结构体成员,比较方便

#! /usr/bin/env stap
%{
#include <linux/version.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <linux/tcp.h>
#include <net/inet_sock.h>
#include <net/ip.h>
#include <linux/skbuff.h>
%}

probe kernel.statement ("sock_sendmsg"),
      kernel.statement ("sock_recvmsg")
{
  printf ("%s:%d<->%s:%d\n", ip_ntop($sock->sk->__sk_common->skc_daddr), ntohs(@cast($sock->sk, "struct inet_sock")->inet_sport), ip_ntop($sock->sk->__sk_common->skc_rcv_saddr), ntohs($sock->sk->__sk_common->skc_dport) )
  printf ("%s(%d) %s : sock_flags:%d sndbuf:%d rcvbuf:%d\n",
    execname(), pid(), probefunc(), $sock->flags, $sock->sk->sk_sndbuf, $sock->sk->sk_rcvbuf)
}

 

 

发表在 好玩的linux | 留下评论

systemtap查看free_skb的场景

目前的dropwatch仅能查看丢包发生在哪个环节,不能看到丢包的内容,于是七拼八凑,拼了一个脚本,可以看到ip层的信息了,哈哈哈,tcp层的还是要做解析,不过如果不是tcp包的话,还要做一些判断逻辑,所以,先看到ip层信息就可以了。脚本如下:

#! /usr/bin/env stap
%{
#include <linux/version.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <net/ip.h>
#include <linux/skbuff.h>
%}


# Note when we turn the monitor on and off
probe begin { printf("Monitoring for dropped packets\n") }
probe end { printf("Stopping dropped packet monitor\n") }

probe kernel.statement("kfree_skb") {
        iphdr = __get_skb_iphdr($skb)
        family = %{ AF_INET %}
        saddr = format_ipaddr(__ip_skb_saddr(iphdr), %{ AF_INET %})
        daddr = format_ipaddr(__ip_skb_daddr(iphdr), %{ AF_INET %})
        protocol = __ip_skb_proto(iphdr)
  printf("%s->%s\n",saddr,daddr)
}

发现ping包最后都会走到kfree_skb的逻辑去。所以拿kfree_skb衡量丢包不太准确啊

后续:dropwatch跟这个脚本跟踪的都是kfree_skb函数被调用的时机,但是其实这个函数也是正常包被释放的时候会被调用的,所以,这个根本不是衡量丢包的,请注意

发表在 好玩的linux | 留下评论

糟糕网络场景下bbr对带宽影响

最近网络界最火的莫过于google开放出来的bbr算法,未能免俗,跟风测试一把

通过网络上最容易出现的两个场景,丢包跟延迟增大,测试不同场景下bbr跟普通内核的带宽性能对比,安装bbr内核可以参考:https://teddysun.com/489.html,这里不再详述

模拟网络丢包跟延时用如下两条命令:

tc qdisc add dev bond0 root netem loss 1%
tc qdisc add dev bond0 root netem delay 100ms

测试场景是两台万兆服务器,centos7系统,内核版本对比原始默认3.10版本跟4.9bbr版本,带宽单位均为Mbps

测试数据如下:

丢包数据:

丢包率(%) 普通内核 BBR内核
0.01 8470
0.05 5170
0.1 3750
0.2 2300
0.4 1000
1 381 9240
2 91 8920
4 15 7100
8 6 2370
16 251

延迟数据:

延迟(ms) 普通内核 BBR内核
1 8530 5500
10 5000 6440
100 568 612
200 243 109
400 88 27
1000 2 4

 

测试结果可见,bbr对丢包的改善非常显著,丢包在5%内,基本带宽都可以接受,但是默认的算法下,丢包增大,导致的带宽下降非常严重!

关于延迟,两者基本接近,看来跟延迟相关的还是窗口影响占决定因素啊

发表在 未分类 | 留下评论

RTT与tcp窗口对带宽的影响

前几天业务的同学吐槽我们机房到某云厂商的数据库实例传输速度太慢,但是我们机房到这个云厂商的云主机实例传输速度又很快。期间抓包多次,跟正常的包对比,最终发现,这个问题,是RTT跟TCP窗口共同影响决定的,受限与物理环境的约束,我们机房到这个数据库实例的RTT会达到30ms,这意味着在1s内,两边的数据交互只能到33次,如果按照每一个包确认过后才可以发下一个包的方式的话,1s只能发33个包,每个包1500B大小的话,这个带宽只能到50KB/s=400Kbits/s,这个带宽,相信都不能忍吧,咱毕竟不是00年有ADSL就吼开心的时代了。

如果提升这个速度呢?tcp的窗口就需要用到了,窗口的意思就是发送端一次可以发送多个包,但是具体能发送多少呢?这要接受端通知发送端窗口大小来协商,如果窗口等于一个包大小,那么情况就是1s只能发33个包,如果窗口是10000个包大小,那么1s就能发送330000个包,算下,这个带宽已经可以到83Mbits,是不是提升很大呢?

综上所述,高延时的场景下,发送端跟接受端的窗口大小,是对传输速度有致命影响的,在高延时的场景下,如果想获得高的带宽,一定要调整发送端跟接受端的窗口大小,这样才能充分的利用带宽。

如果有想测试高延时的场景的同学,可以用如下的命令设置主机的延时:

tc  qdisc  add  dev  eth0  root  netem  delay  30ms

效果很明显,ping下即可看到效果,测试带宽用iperf就足够了。

 

发表在 好玩的linux | 留下评论