性能优化总结
Posted 守拙的厨子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了性能优化总结相关的知识,希望对你有一定的参考价值。
性能的定义
吞吐量 每秒钟可以处理的请求数 —> throughout越大,延迟会越大. 系统太繁忙,所以响应速度自然会降低
系统延迟 系统在处理一个请求或者任务时候的延迟 —> 系统延迟越低,能支持的吞吐就越高
服务可用性 在流量高峰时候,性能问题往往会表现为服务可用性下降,所以性能优化也可以包括提高服务可用性. 为了提高服务可用性,对异常请求重复调用是一个常用的做法,但是这会提高响应时间并降低系统吞吐量
性能关注的一些指标项
响应时间 rt
吞吐量 tps/qps
现在QPS,TPS的概念有点混淆,泛指系统单位时间的处理能力
这两个概念是衡量性能很明确的指标,我们用它来泛指单位时间系统的处理能力资源
cpu, 线程, 内存占用, 磁盘io等
响应时间的组成模型
响应时间是程序(进程、线程)在资源(CPU)运行的一个体现。所以,资源和程序运行的载体会影响这个结果
java线程模型
注意java线程的状态流转
1、线程/进程是操作系统调度的关键资源。
2、理解器运行机制有利于知道一个请求中的运算是消耗在什么节点。CPU只是一个点,其他资源也是会影响线程的执行。
3、多线程情况下,线程不一定是满转的,遇到共享资源争用的时候,会造成阻塞。
最优的线程数量
对于最优线程数量, 这是一个老生常谈的问题. 但是一般有如下定义:
尽可能保持应用对资源的最大化使用, 也就是说我们要尽量压榨机器资源。
当线程数较少的时,有压力情况下,可能造成线程资源不足,请求需要等待线程释放后才能处理
当线程数较多的时,线程自身也是需要消耗内存资源的,导致资源的浪费
线程较多的时候对于线程的调度和争用也会影响性能。 主要是第一方面, 线程的上下文切换, 会消耗一定资源; 第二方面, 若涉及到多线程之间的资源竞争, 比如锁资源
一般的原则是:
对于计算密集型应用, 线程数应当少一些, 比如不超过cpu核数/线程数.
对于io密集型应用, 线程数应该适当的多一些, 但是不应该超过cpu核心数的2倍.
一个多资源的程序中:
对资源的争用表现为对瓶颈资源的争用,性能情况会受制于瓶颈资源
如何理解瓶颈的概念, 举个简单的例子,比如应用层开启20个业务线程处理业务,
物理机器有6核心cpu, 业务的一个环节是写数据库. 数据库连接池的数量设置为4.
则实际的处理情况是,20个请求进入后, cpu计算阶段一次最多处理6个请求(假定时间为5ms),
其他14个请求会进行排队. 当请求达到数据库层面后, 一次又只能处理4个请求(假定时间为5ms),
其他2个请求需要排队,则其实在处理一次请求的时间周期(10ms)内, 实际上可以处理的请求数只有4个.
从上面的例子来看, 开启20个业务线程, 是一种资源浪费, 业务线程数量开启6个足矣
一个可用的qps公式
最优线程公式
1、 最优线程数量=线程总时间/瓶颈资源时间 * 瓶颈资源并行数(上面的例子中, 10/5 * 4 = 8)
2、 一个线程1S可以处理的请求数(1000/线程总时间, 上例中: 1000ms/10ms = 100)
3、 所以得到qps计算公式: qps= 最优线程数量 * (1000/线程总时间)
由上面可以知道, 瓶颈资源, 是计算公式的关键. 所以需要找出影响系统性能的环节
如何识别资源瓶颈 —> 压力测试
是要进行稳定压测
还是要进行瓶颈压测等等
压测环境的组成
瓶颈的定位方法
隔离法, 替换法.
优化方向/方式的思考
负载均衡, 一头牛拉不动, 多头牛来拉
七层or四层负载均衡并行处理
fork/join(多进程/ 多线程并发处理)
Mapreduce异步化
分布式系统交互异步: 消息中间件io模型
异步io
同步非阻塞io(io多路复用)算法及代码实现方式优化
lock free (无锁化的设计, redis的单线程模型; 乐观锁; Threadlocal; CAS; 可重入代码;)
线程调优 (线程数量; 互斥同步资源的使用)
内存分配优化(减少对象大小; 大对象对jvm gc的影响; 减少大量内存的拷贝)
异步化 (改同步调用为异步调用)
代码实现优化, 去除冗余代码Cache (多层级的缓存, 典型的空间换时间的策略)
客户端缓存
cdn
中间件缓存(nginx)
应用层级缓存(encache)
集中式缓存(memcache, redis)
内核/文件系统缓存
数据库缓冲池缓冲
IO缓冲(内核io buffer)
任务写缓冲(采用任务队列)网络调优
单个进程连接数限制(tcp链接, 会占用文件描述符和内存, 每个客户端socket会有buffer空间, 对于java socket服务端, 单个进程上的连接数太多,会占用较多堆内存, 从而对gc造成影响)数据库优化
数据库拆分: 读写分离/分库分表
小事务, 最终一致性
数据库服务器优化(日志配置, 缓冲池大小配置)
数据库应用优化(查询过程优化, 索引…)应用的服务化拆分(SOA)
以上是关于性能优化总结的主要内容,如果未能解决你的问题,请参考以下文章