在某些情况下,我们的RDS会出现CPU性能100%的情况。如下图显示:
问题原因:
一般情况下,系统提交到数据库的查询执行需要大量逻辑读的话,会消耗RDS大量的CPU资源。
用一个简化的模型来描述:
avg_lgc_io:每条查询执行需要的平均逻辑 IO
total_lgc_io:实例 CPU 资源单位时间能够处理的 逻辑IO 总量
total_lgc_io = avg_lgc_io x QPS -- 单位时间 CPU 资源 = 查询执行平均成本 x 单位时间执行的查询数量
根据以上公式,我们列出了两种典型导致RDS CPU占用高的情景。
- 应用负载过高(QPS)
特征:实例的 应用负载(每秒执行的查询次数QPS)高,查询效率较高、此种情况优化余地小。
表现:在RDS的优化建议内没有出现慢SQL,且QPS 和 CPU 使用率曲线变化吻合。
CPU:QPS:
RDS实例诊断报告内没有慢SQL: - 查询效率低(平均逻辑IO过高)
特征:RDS实例的负载(每秒执行的查询次数QPS)并不高;但单语句查询执行效率低、需要扫描大量表中数据、此种情况优化余地较大。
表现:实例诊断报告内存在慢查询,QPS和CPU使用率曲线变化不吻合。
查询效率低,单次查询需要访问大量的数据(平均逻辑IO高),在 QPS 并不高的情况下(例如网站并发不高的情况下),导致实例的 RDS的CPU使用率高。
解决办法:
无论是何种原因导致的CPU使用量过高,请一定参考实例诊断报告。该工具可以最快捷解决一些RDS常见性能问题,尤其建议关注诊断报告的 “SQL优化”、”会话列表”、”慢SQL汇总” 部分。
针对QPS过高的优化方法:
此种情况下,优化SQL的性能作用不会太大,建议从系统构架,实例规格方面入手。
- 升级RDS实例规格,提升系统QPS负载。
- 对于查询数据比较静态、查询重复度高、查询结果集小于 1 MB 的应用,考虑开启查询缓存(Query Cache)。
- 将系统读写分离,增加只读实例,将对数据一致性不敏感的查询转移到只读实例上,分担主实例压力。
- 定期归档历史数据、采用分库分表或者分区的方式减小查询访问的数据量。
- 使用阿里云Memcache或者云Redis产品,将常用的数据放入缓存读取,减轻 RDS 实例压力。
- 尽量优化查询,减少查询的执行成本(逻辑IO,执行需要访问的表数据行数),提高应用可扩展性。
- 使用阿里云DRDS产品,自动进行分库分表,将查询压力分担到多个 RDS 实例上。