一次系统延迟性优化案例

一次,系统,延迟,优化,案例 · 浏览次数 : 313

小编点评

**系统延迟本质分析:** * CPU 没有及时的运行程序代码导致进程内部网络io,磁盘io,cpu调度达到瓶颈第三方系统调用的第三方系统慢。 * mysql,redis等基础组件调度慢,第三方应用系统调用慢。 * sql报警是在应用程序内部通过对sql操作增加钩子函数,对sql前后执行的位置进行计时,然后sql执行完毕后,对时间进行判断,大于1s则报警。 **分析步骤:** 1. 通过后台的慢查询日志排查sql慢查询。 2. 使用go trace分析程序运行时的动作。 3. 使用go trace分析程序运行时的动作进行3s的采样。 **结果:** * 协程网络等待时间占2秒以上,超过网络io系统调用开始时记录下此时协程的时间。 * 协程从就绪可运行状态到真正被调度耗时了879ms,可见协程调度的压力也是过大的。 * 每次阻塞都会引发协程的重新调度。 **优化建议:** * 减少数据库操作,尽量采用内存存储和高效的查询技术。 * 优化数据库连接配置,减少连接时间。 * 降低网络阻塞操作的数量和持续时间。 * 优化线程池大小,提高处理数据的效率。 * 考虑使用其他技术,例如消息队列或异步执行等,减少阻塞操作。

正文

一次系统延迟性优化案例

服务监控系列文章

服务监控系列视频

延迟的本质

本质是cpu没有及时的运行程序代码。

进程内部

网络io,磁盘io,cpu调度 达到瓶颈

第三方系统

调用的第三方系统慢,mysql,redis等基础组件调度慢, 第三方应用系统调用慢

问题背景

线上隔三差五晚上10点左右总会有sql报警出现,且是同样的sql,我们的sql报警是在应用程序内部通过对sql操作增加钩子函数,对sql前后执行的位置进行计时,然后sql执行完毕后,对时间进行判断,大于1s则报警。
晚上10点正好是我们的业务高峰。部分接口也会在此期间出现超过2s的响应。
image.png

探索过程

排查sql慢查询

通过后台的慢查询日志,没有发现这条慢sql打印出来,且重新执行该sql,执行时间仍然在毫秒内完成,排除掉sql写法本身带来的性能问题。

排查系统各项指标

查看系统cpu,网络带宽Mbps,磁盘iops,Bps,均未到达瓶颈,仅在高峰期有波峰。
image.png

系统是4核系统,唯一达到瓶颈的也就是系统负载达到了5。说明有进程或线程在等待执行。

为什么系统各个硬件指标都不是很高,程序反而慢了呢,cpu为什么没有干更多活来执行更多的指令呢。

考虑程序在执行一个cpu使用率不高的动作,但是这个动作却不是在执行用户代码

一般通过go tool pprof 查看cpu的使用率是查看hot-cpu,也就是cpu真正执行的时间,但是如果要看等待cpu的时间得看off-cpu,go提供了这样的工具(github.com/felixge/fgprof)
image.png

可以看到一个方法在执行时由于查询了数据库,cpu在withLock 和等待数据库返回数据库时耗费了很多等待时间。但是这里只能看出这部分代码等待cpu的时间占所有等待时间的大部分,无法确定程序真正等待的时间。

用go trace分析系统延迟

基于上面分析,为更进一步确定是数据库查询带来的耗时, 采用更加精确化的工具 go trace分析程序运行时的动作。go trace 是golang提供的官方工具。
image.png
进行了3s的采样,其中网络io等待时间就占了2秒多,我的理解程序会在网络io系统调用开始时记录下此时协程的时间,并将协程从p队列拿下来,然后异步等到epoll回调通知,等到文件描述符可读后,将协程重新加入到p队列,重新执行调度。这里的Network wait就是从p队列拿下来到加入到p队列的时间间隔,然后真正执行是要等待Scheduler wait 调度等待时间才会被调度。
这里协程的网络等待时间长,但是不能完全说明是导致系统延迟的原因,因为在keepAlive开始时,一个协程是有可能处理多个网络请求的,所以有可能是多次请求间,读等待时间较长导致。所以继续看下其他指标。
image.png

协程从就绪可运行状态到真正被调度耗时了879ms,可见协程调度的压力也是过大的。

image.png

由于程序阻塞带来的延迟开销也是不小的,达到778ms。
对应于之前off-cpu看到的网络和阻塞开销就是执行数据库操作时的网络请求以及withlock操作,由于阻塞更加剧了协程调度的开销。每次阻塞都会引发协程的重新调度。当然go trace左上角可以点击graph同样能观察得出上述结论。

优化

由于程序的阻塞虽然不是慢查询导致,但是依然是由于数据库操作带来的,所以简单直接的优化就是减少数据库操作,或者更直接点说,在高并发接口下,尽可能减少网络等阻塞操作。
将这部分查询数据提前存到内存里,通过内存直接查询。

成果

image.png

可以看到对比之前情况,除开22点峰值,已经没有超过2s的响应了,但是22点峰值时还是会有,原因是我们线上的机器同时部署了多台服务,由于其他服务的影响导致,所以后续可能还会继续做优化,将其他服务的处理接口能力提升上去,或者更好的做好隔离。

结论

go trace 是个很好的分析系统延迟的工具。
对高并发接口的设计最好减少网络以及其他阻塞操作,流量上去后,这些阻塞很可能带来系统延迟。

与一次系统延迟性优化案例相似的内容:

一次系统延迟性优化案例

一次系统延迟性优化案例 服务监控系列文章 服务监控系列视频 延迟的本质 本质是cpu没有及时的运行程序代码。 进程内部 网络io,磁盘io,cpu调度 达到瓶颈 第三方系统 调用的第三方系统慢,mysql,redis等基础组件调度慢, 第三方应用系统调用慢 问题背景 线上隔三差五晚上10点左右总会有

[转帖]NGINX官方文档[译]:HTTP负载均衡

负载均衡是一种优化资源利用率、提升最大吞吐量、减少延迟、提高系统容错率的常用技术。 要使用Nginx对一组服务器的HTTP流量进行负载均衡,首先需要使用upstream定义一组后端服务器(配置于http字段中),然后使用server对upstream组中的服务进行配置(同样配置于http字段中,注意

[转帖]架构修炼-10:高并发设计

一、如何衡量高并发的系统性能 1.吞吐量Throughput: 2.响应延迟Response Delay: 二、性能优化目标 1.缩短响应时间 2.提高系统并发数(提升吞吐量) 3.系统处理合理状态(机器利用率) 随着系统压力增加(X坐标:在线业务人数), Y坐标:绿色机器利用率,紫色并发数,蓝色:

[转帖]Kafka 性能优化与问题深究

Kafka 性能优化与问题深究 一.Kafka深入探究 1.1 kafka整体介绍 1. 1.1 Kafka 如何做到高吞吐、低延迟的呢? Kafka是一个分布式高吞吐量的消息系统,这里提下 Kafka 写数据的大致方式:先写操作系统的页缓存(Page Cache),然后由操作系统自行决定何时刷到磁

DeepSpeed框架:1-大纲和资料梳理

DeepSpeed是一个深度学习优化软件套件,使分布式训练和推理变得简单、高效和有效。它可以做些什么呢?训练/推理具有数十亿或数万亿参数的密集或稀疏模型;实现出色的系统吞吐量并有效扩展到数千个GPU;在资源受限的GPU系统上进行训练/推理;实现前所未有的低延迟和高吞吐量的推理;以低成本实现极限压缩,

[转帖]Java游戏服务器调优实践

https://www.jianshu.com/p/344f8141b63e landon资深网络游戏服务器架构师 系统性能定义 Throughput 吞吐量,也就是每秒钟可以处理的请求数,任务数 Latency 系统延迟,也就是系统在处理一个请求或一个任务时的延迟 二者关系 Throughput越

[转帖]Java游戏服务器调优实践

https://www.jianshu.com/p/344f8141b63e Java Profiling Practice landon资深网络游戏服务器架构师 系统性能定义 Throughput 吞吐量,也就是每秒钟可以处理的请求数,任务数 Latency 系统延迟,也就是系统在处理一个请求或一

一种异步延迟队列的实现方式

目前系统中有很多需要用到延时处理的功能:支付超时取消、排队超时、短信、微信等提醒延迟发送、token刷新、会员卡过期等等。通过延时处理,极大的节省系统的资源,不必轮询数据库处理任务。 目前大部分功能通过定时任务完成,定时任务还分使用quartz及xxljob两种类型轮询时间短,每秒执行一次,对数据库造成一定的压力,并且会有1秒的误差。轮询时间久,如30分钟一次,03:01插入一条数据,正常3:3

深入了解 GPU 互联技术——NVLINK

随着人工智能和图形处理需求的不断增长,多 GPU 并行计算已成为一种趋势。对于多 GPU 系统而言,一个关键的挑战是如何实现 GPU 之间的高速数据传输和协同工作。然而,传统的 PCIe 总线由于带宽限制和延迟问题,已无法满足 GPU 之间通信的需求。为了解决这个问题,NVIDIA 于 2018 年

vivo数据中心网络链路质量监测的探索实践

网络质量监测中心是一个用于数据中心网络延迟测量和分析的大型系统。通过部署在服务器上的Agent发起5次ICMP Ping以获取端到端之间的网络延迟和丢包率并推送到存储与分析模块进行聚合和分析与存储。控制器负责分发PingList并通过数据中心内部消息通道将PingList下发至每台服务器上的Agent,而PingList就是每个Agent需要发起Ping的目标服务器列表。