原则:性能调整在距离工作执行的地方越近越好
应用程序基础
需要了解应用程序的以下方面(以ES举例)
- 功能。分布式查询引擎
- 操作。查询、写入等等
- 配置。_cluster/settings和elasticseach.yml包含很多配置
- 指标。bulk time、QPS、线程池…
- 日志。系统日志、慢查询写入日志、gc日志
- 版本。7.9.1,新版本可能有性能提升的feature
- bugs。暂无
- 社区。中文和英文社区
常见的优化
需要找到常用的代码路径。应用的代码可能上百万行,随机找地方优化的效率太低。可以通过栈跟踪方法找到。java程序栈跟踪通常使用Async_profiler或Jprofiler
提高性能的常用方法
- 增加IO尺寸。每次IO都有固定开销(寻道时间),执行1次128KB的写入比执行128次1KB的写入效率更高。ES提供了异步的translog fsync策略,来增加IO尺寸
- 缓存。ES的查询就有多个查询缓存,例如request cache, filter cache
- 缓冲区。为提高写入性能,数据在写入下一层级前会先放到缓冲区中,这增加了IO大小。ES的refresh间隔可配置策略就是这个原理。
- epoll。轮询是在循环中等待时间状态的变化,存在CPU开销高昂、事件发生和下一次检查的延时较高的问题。epoll没有这样的性能负担。ES使用了netty框架处理网络请求,netty是基于reactor模型的
- 并行。利用多处理器加快处理速度。ES的shard查询执行就是并发的,并且在ESQL中并行的线程数增大了,支持segment级并行查询。
- 非阻塞IO。Netty使用了NIO
- 处理器绑定。线程在单一CPU执行能够提高内存本地性,减少内存IO,但可能会导致资源利用率下降。
垃圾回收的问题
- CPU成本
- stop-the-world导致的延迟
方法和分析
线程状态
- on CPU。使用CPU执行
- off CPU
- 睡眠
- 锁
- 等待CPU
- 匿名换页
- IO
CPU剖析方法
等待CPU调度所花时间:sched stat\perf sched
匿名换页时间:delay accounting特性
其他的可以使用:jprofiler
USE方法
对于软件资源也可以使用USE方法查看成为瓶颈的软件资源。可以对软件资源的使用率、饱和度和错误进行考量。ES的线程池基础信息就是很好的例子,包含了线程池的active线程数(对应使用率);排队线程数量(对应饱和度);拒绝的请求数(对应错误)。
node_name name active queue rejected yg-data-rt-es0174 write 16 108 0 yg-data-rt-es0017 write 0 0 0 yg-data-rt-es0048 write 0 0 0 yg-data-rt-es0024 write 0 0 0
参考
《性能之巅》