原则:性能调整在距离工作执行的地方越近越好

应用程序基础

需要了解应用程序的以下方面(以ES举例)

  1. 功能。分布式查询引擎
  2. 操作。查询、写入等等
  3. 配置。_cluster/settings和elasticseach.yml包含很多配置
  4. 指标。bulk time、QPS、线程池…
  5. 日志。系统日志、慢查询写入日志、gc日志
  6. 版本。7.9.1,新版本可能有性能提升的feature
  7. bugs。暂无
  8. 社区。中文和英文社区

常见的优化

需要找到常用的代码路径。应用的代码可能上百万行,随机找地方优化的效率太低。可以通过栈跟踪方法找到。java程序栈跟踪通常使用Async_profiler或Jprofiler

提高性能的常用方法

  1. 增加IO尺寸。每次IO都有固定开销(寻道时间),执行1次128KB的写入比执行128次1KB的写入效率更高。ES提供了异步的translog fsync策略,来增加IO尺寸
  2. 缓存。ES的查询就有多个查询缓存,例如request cache, filter cache
  3. 缓冲区。为提高写入性能,数据在写入下一层级前会先放到缓冲区中,这增加了IO大小。ES的refresh间隔可配置策略就是这个原理。
  4. epoll。轮询是在循环中等待时间状态的变化,存在CPU开销高昂、事件发生和下一次检查的延时较高的问题。epoll没有这样的性能负担。ES使用了netty框架处理网络请求,netty是基于reactor模型的
  5. 并行。利用多处理器加快处理速度。ES的shard查询执行就是并发的,并且在ESQL中并行的线程数增大了,支持segment级并行查询。
  6. 非阻塞IO。Netty使用了NIO
  7. 处理器绑定。线程在单一CPU执行能够提高内存本地性,减少内存IO,但可能会导致资源利用率下降。

垃圾回收的问题

  1. CPU成本
  2. stop-the-world导致的延迟

方法和分析

线程状态

  1. on CPU。使用CPU执行
  2. off CPU
    1. 睡眠
    2. 等待CPU
    3. 匿名换页
    4. 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

参考

《性能之巅》