公众号|松花皮蛋的黑板报|性能分析与优化
松花皮蛋的黑板报
  • 分享在京东工作的技术感悟,还有JAVA技术和业内最佳实践,大部分都是务实的、能看懂的、可复现的

扫一扫
关注公众号

性能分析与优化

博客首页文章列表 松花皮蛋me 2020-02-17 12:26

、CPU的常见性能问题表现

  • 1、中断。各个核上的中断不均衡,导致CPU超载或者空闲。
  • 2、CPU超载。多核之间的负载没有平均好、CPU做了很多无用功、应用程序本身的设计需要优化。
  • 3、CPU空闲。指令里太多内存数据操作、太多的分支预测错误。

CPU的性能检测工具:top\uptime\pidstat\vmstat\Perf工具


二、内存的性能指标

内存的性能指标:缓存命中率、缓存一致性、内存延迟、内存的使用大小及碎片、内存的分配和回收速度、内存带宽

多处理器使用内存:将访问相同的多个线程放在相同的处理器上,有时也需要强制去绑定到某个节点或者CPU核上

工具:内存检测工具free、Linux vmstat、Linux下的/proc文件系统

三、存储的性能指标


存储的性能指标:IOPS、访问延迟、吞吐率

IOPS影响因素:读取和写入的比例、其中顺序读写以及随机读写的比例、读写的大小、线程数量及读写队列深度等。

工具:fio、IOMeter、IOZone、Bonnie++、iostat


四、网络的性能指标

对于网络性能要求,简单来说就是能联通、响应快、带宽高;并且在部署大流量服务时,可以优化服务器的部署,来尽量减少外部网络流量;也可以使用CDN来加速数据传输。

工具:Netperf、Iperf、Netstat、Ss、Traceroute

注:当网络数据传输慢时,我们可以先观察发送缓存区(SendQ)和接收缓存区(RecvQ)的堆积情况,快速确定应归咎的组件范围和场景。


、三个”要”的原则

  • 1、要优先查最大的性能瓶颈。帕累托法则;
  • 2、性能分析要确诊性能问题的根因。考虑优化工作的投入产出比例;
  • 3、性能优化要考虑各种情况。要有一个整体的意识和判断,反复权衡利弊和取舍来做最终决定,避免某个方案在特殊情况下,导致其他严重问题;

六、三个”不要”的原则

  • 1、不要做过度的、反常态的的优化。根据产品的性能要求来做决策,避免增加系统复杂成本;
  • 2、不要过早做不成熟的优化。判断一个产品的成熟度,成熟则建议优化;
  • 3、不要做表面的肤浅优化。对一个程序和服务有全局的把握,理解底层运行机制,自动调整,少用手动优化,避免后续优化的无尽烦恼;

七、如何找到最大的性能瓶颈点

  • 1、列出可能的性能瓶颈;
  • 2、每个瓶颈有哪些资源有可能短缺;
  • 3、每个瓶颈的每种资源是如何与其他模块进行交互的,对整体系统性能是如何影响的,如何测量;

八、性能优化方法论

  • 1、不访问不必要的数据——减少交易线上不必要的环节,减少故障点和维护点;
  • 2、就近加载/缓存为王——减少不必要的访问;
  • 3、故障隔离——不要因为一个系统瓶颈压垮整个交易平台;
  • 4、具备良好的扩展能力——合理的利用资源、提高处理效率和避免单点故障;
  • 5、对交易链进行优化提高吞吐量——异步/减少串行、合理拆分(垂直/水平拆分)、规则前置;
  • 6、带着优化的意识写代码;

九、性能优化思路

  • 1、了解现状确定清晰的性能目标,并按优先级排列。
  • 2、利用科学的测试工具对应用程序进行测试,并记录。
  • 3、分拆组件:Web层、业务层、持久化层、客户端展现时间、以及网络传输时间,分别进行调优。
  • 4、进行有系统的科学调优。

十、科学调优方法

  • 1、遵循一定的程序进行调优。问题-找出瓶颈-假设造成瓶颈的因素-测试假设是否成立-修改应用-再次测试性能。
  • 2、确实影响性能的因素,是应用程序、算法、CPU、内存、IO问题还是硬件资源不足。
  • 3、找出主要的瓶颈。首先解决其中最容易的,再重复测试。
  • 4、一次修改一个瓶颈,不要对不需要的地方进行调优。
  • 5、提高CPU性能。采用更快的代码、更好的算法,减少短期生存的对象。
  • 6、提供内存性能。减少或者减小长期生存的对象。
  • 7、提高IO性能。重新设计应用,减少IO的交互。
  • 8、缓存为王。适度缓存做到最大化发挥数据库缓存、应用端缓存、客户端缓存的作用。

十一、性能优化策略

  • 1、时空转换,空间换时间或者时间换空间。包括优化数据结构或者数据格式、想方设法压缩数据、把一些数据存储到外部然后需要时再取回来、使用CDN内容分发网络技术对数据和服务进行多份拷贝、集群和服务间进行负载均衡。
  • 2、预先和延后处理。比如文件系统预读、指令预读、写时复制COW等。
  • 3、并行和异步操作。
  • 4、缓存数据。比如连接池、线程池、使用中间结果缓存优化递归代码。
  • 5、批量合并处理。比如合并对数据库的读写操作、合并网络请求。
  • 6、更先进的算法和数据结构。

十二、案例一

如何降低LLC(最后一级CPU缓存)的不命中率?减少对CPU速度和内存带宽的影响。

  • 1、缩小数据结构,让数据变得紧凑
  • 2、用软件方式来预取数据。(硬件预读预测对连续性的内存访问特别有效)
  • 3、让每个元素单独占用一个缓存行,去除伪共享缓存。(当多线程修改看似互相独立的变量时,如果这些变更共享同一个缓存行,就会在无意中影响彼此的性能)

十三、案例二

如何优化程序、OS和存储系统的交互?

由于操作系统的各种机制的原因,包括页面写入稳定、页面缓存写回、日记文件系统提交等,JVM可能在GC日志期间,被长时间阻塞。比如操作系统执行页面回收时(或者Linux尝试将常规页面重新聚合成THP大页面时),需要进行页面扫描,以检查已分配的页面的活动性,默认是后台扫描,不过当内存使用非常大时,就会启动前台页面回收,由进程自己执行,此时应用程序会停止运行。(系统处在内存压力之下,操作系统会有很多和外部存储的页面交换活动)。

  • 1、修改JVM,比如预分配JVM的堆空间(AlwaysPreTouch)、保护JVM的堆空间不被唤出到外部存储(微调cgroup)、动态调整THP大页面
  • 2、减少后台IO
  • 3、将GC日记记录与其他IO分开

十四、案例三

高性能场景应用建设-大促备战

十五、在生产环境中进行容量测试

  • 1、要使用实时流量以确保准确性
  • 2、尽量不影响生产流量,这就需要实时的监测和反馈模块
  • 3、可以定制重定向等行为规则;对不同的服务和不同的场景的测试,各种性能指标和阈值都会不同
  • 4、能自动终止测试,并把测试环境复位,尽量减少人工干预
  • 5、支持基于日历和事件的自动触发和调度