针对cup瓶颈的问题分析了很多,相应的分析工具也介绍了不少,但理解了各种指标的含义后,会发现他们之间是有一定关联性的。顺着关联是可以很快找到瓶颈所在。找到瓶颈下一步就是进行优化。

方法论

可以从下面三个问题出发来判断性能优化是否有效

  1. 如何判断性能优化的有效性?
  2. 性能问题通常不是独立问的,如果同时发生先优化哪一个?
  3. 提升性能的方法并不唯一的,当有多钟选择时,改选哪一种?

如果你能轻松的回答这三个问题就可以开始优化了

细化三个问题

  1. 如何评估性能效果
    1. 确定性能的量化指标
      • cpu使用率
      • 应用程序吞吐量
      • 客户端请求的延迟

        建议不要局限在单一纬度上来定指标 应用程序纬度:吞吐量和请求延迟 系统资源纬度:cpu使用率

    2. 测试优化前的性能指标

      注意:

      1. 尽量避免性能测试工具干扰应用程序的性能,防止交叉污染
      2. 避免外部环境的变化影响性能指标的评估
    3. 测试优化后的性能指标
  2. 多个性能问题同时存在,要怎么选?
    • 二八原则:80%的问题都是由20%的代码导致的,只要找到20%就可以了,并不是所有的性能问题都值得优化
      1. 如果资源达到瓶颈,比如cpu使用率到了100%,那么首先优化一定是系统资源使用问题。优化后再考虑其他问题。
      2. 针对不同类型的指标,首先优化那些由瓶颈导致的,性能指标变化幅度最大的问题,比如产生瓶颈后,用户cpu使用率升高了10%,而系统cpu使用率却升高了50%,这个时候首先应该优化cpu使用率。
  3. 多种优化方法时,如何选择?
    • 性能优化并非没有成本 当你优化一个指标,有可能另一个指标却上升了。
    • 比如网络优化中的DPDK(Data Plane Development Kit)提升网络的处理能力。它需要独占一个cpu以及一定数量的内存大页,CPU核数较少是并不适合用这种优化。

      几大优化方向

      * CPU优化
      
    • 应用程序优化:排除所有不必要的工作,只保留核心的逻辑。比如减少循环层次,减少递归,减少动态内存分配等等
      • 编译器优化:gcc
      • 算法优化:减少算法复杂度
      • 异步处理:轮训改为事件通知
      • 多线程代替多进程:减少上下文切换
      • 善用缓存:减少磁盘操作,直接使用缓存
    • 系统优化:
      • cpu绑定:把进程绑定到一个或者多个cpu上,可以提高cpu缓存命中率,减少跨cpu调度带来的上下文切换
      • cpu独占:类似绑定,独占cpu
      • 优先级调整:减低非核心业务的应用优先级
      • 为进程设置资源限制:使用linux cgroups 来设置进程的cpu使用上线。
      • NUMA(Non-Uniform Memory Access)优化:支持NUMA的cup,会被划分为多个node,每个都有自己的本地内存地址。
      • 中断负载均衡:开启irqbalance服务或者配置smp_affinity,把中断处理自动负载均衡到多个cpu

        注意: 避免过早优化

        1. 优化带来复杂性的提升,降低可维护性。
        2. 需求是动态变化的,要针对当前情况进行优化,是个动态的过程。