Skip to content

Instantly share code, notes, and snippets.

@jschwinger233
Last active March 19, 2020 17:26
Show Gist options
  • Save jschwinger233/dfe812bc701308433f68abf6a51f68f9 to your computer and use it in GitHub Desktop.
Save jschwinger233/dfe812bc701308433f68abf6a51f68f9 to your computer and use it in GitHub Desktop.
app performance problem in container

协助排查了一次容器内进程的性能问题

症状: 平台上容器内的 redis cluster 进程用 redis-benchmark 测试能稳定复现 spike, 但是同宿主机上的 redis 没有问题

  1. 首先怀疑 SDN, 因为没问题的 redis 是 host 网络. 理论上这很难查, 但是在部署了一个 SDN 网络的 redis 后发现依然没有问题, 我比较有把握不是网络问题, 不过也不是特别确定, 因为 redis cluster 的节点跨主机, 说不清楚会发生什么.
  2. 建立最小可复现问题的现场. 我们应该从几乎一模一样的环境(相同的容器里)重建一个拥有相同节点, 相同配置, 相同数据, 只是监听不同端口的集群, 理论上这个集群应该是能复现问题的.
  3. 然后一点点缩小问题的范围, 看到那一步就突然不能复现
    1. 摘掉所有的 slave nodes
    2. 把进程放到宿主机裸跑
    3. 把集群放到同一个宿主机
    4. 用 host 网络
  4. 结果发现把进程放到宿主机裸跑就没问题, 接下来继续缩小范围:
    1. 放到同一个 network ns 下运行
    2. 放到同一个 mount ns 下
    3. 放到同一个 cgroup 下
    4. 其他 ns
  5. 令人吃惊的是裸跑进程放到和有问题的进程同一 net ns 下居然没有复现问题, 彻底排除了 SDN 的问题, 继续查下去发现居然是 cgroup 的限制导致了性能问题.
  6. 一边 strace -fTp$PID -etrace=read,write 一边 benchmark 一边 tshark, 发现 spike 的 exchange 在时间上吻合一个长达 12ms 的 write 调用, 去看 cgroup 里的 cpu.throttled_*, 发现 throttled_time 和 spike 吻合地非常好, 就是 12ms.
  7. 最后创建容器, 设置 CPUQuota=0, 不再复现, 实锤是 cgroup cpu.cfs_quota_us 导致被 throttle 使得非阻塞的 write 调用耗时很长.
  8. 内核下的问题我就不会查了, 溜了.

当然我只是辅助, 体力活都是波神做的, 第一次见识 eBPF/bcc 这种雷神之锤, 臣服, 想学.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment