MySQL优化问题

MySQL需要优化的地方?

SQL 和 索引

慢查询日志slow_query_log,设置超时时间, 记录慢查询sql,然后通过 explain 分析执行计划,制定优化措施。

应用上的优化:

连接池 中间件;

增加cache缓存层,存储热点数据,如 redis,但又有缓存数据一致性问题、缓存穿透、缓存雪崩、redis其他的功能;

  1. 缓存穿透(Cache Penetration): 缓存穿透指的是在缓存中无法找到所需数据,进而导致请求直接访问后端存储系统(如数据库)。这通常发生在恶意请求或者不存在的数据被频繁请求的情况下。由于缓存无法命中这些请求,导致大量无效的请求直接访问后端系统,从而增加了后端的负载压力。

    防止缓存穿透的常见方法是使用布隆过滤器等机制来过滤掉不存在的数据请求,或者在缓存层使用空值缓存,即将对不存在数据的请求也缓存一段时间,以避免对后端存储系统的频繁访问。

  2. 缓存雪崩(Cache Avalanche): 缓存雪崩指的是缓存中大量的缓存条目在相同的时间窗口内失效,导致大量的请求直接访问后端系统。通常,这是由于缓存中的多个条目具有相同的过期时间,当这些条目同时失效时,所有相关请求都会落到后端系统上,造成系统过载和性能下降。

为了防止缓存雪崩,可以采用以下策略之一:

  • 设置合理的缓存过期时间,将过期时间分散开,避免所有缓存同时失效。
  • 使用多级缓存架构,如分布式缓存,将请求分散到不同的缓存节点上。
  • 引入热点数据的热加载机制,提前主动加载热门数据,避免大量请求同时访问。
  1. 缓存击穿(Cache Miss): 缓存击穿指的是针对一个特定的缓存键(key)发起大量的请求,当该缓存键失效时,大量的请求同时涌入后端系统。与缓存雪崩不同的是,缓存击穿只涉及到特定的缓存键,而不是所有的缓存

为了防止缓存击穿,可以采用以下策略之一:

  • 使用互斥锁或分布式锁,在第一个请求失效时,只允许一个请求去加载数据到缓存中,其他请求等待或访问缓存中的旧数据。
  • 在缓存中设置短期的自动过期时间,以避免在大量请求同时涌入时直接落到后端系统。

MySQL server的优化

参数设置:ubuntu 20.04 的配置文件/etc/mysql/mysql.conf.d/mysqld.cnf

关闭自适应哈希索引、 innodb_log_buffer、innodb_buffer_pool_size

MySQL查询缓存

MySQL的查询缓存是把 select 查询语句上一次的查询结果记录下来放在缓存当中,下一次再查询相同内容的时候,直接从缓存中取出来就可以了,不用再进行一遍真正的SQL查询。但是当两个 select 查询中间出现insertupdatedelete语句的时候,查询缓存就会被清空。查询缓存适用更新不频繁的表,因为当表更新频繁的话,查询缓存也总是被清空,过多的查询缓存的数据添加和删除,就会影响MySQL的执行效率,还不如每次都从磁盘上查来得快(缓存指的就是一块内存,内存I/O比磁盘I/O快很多)。

总之查询缓存适合于查询多,修改少的情况

可以在MySQL上通过以下命令,来查看查询缓存的设置:

mysql> show variables like '%query_cache%';

+------------------------------+---------+

| Variable_name        | Value  |

+------------------------------+---------+

| have_query_cache       | YES   |

| query_cache_limit      | 1048576 |

| query_cache_min_res_unit   | 4096  |

| query_cache_size       | 1048576 |

| query_cache_type       | OFF   |

| query_cache_wlock_invalidate | OFF   |

+------------------------------+---------+

可以通过set命令设置上面的缓存参数开启MySQL查询缓存功能,也可以找到MySQL的配置文件修改query_cache_type参数为1就可以了,然后重启MySQL Server就可以使用了,如下:

query_cache_type=1

query_cache_size=10

然后重启MySQL Server即可

MySQL线程缓存:thread_cache_size

可以在配置文件结尾行添加。

线程池就是在业务使用之前,先创建一组固定数量的线程,等待事件发生,当有SQL请求到达MySQL Server的时候,在线程池中取一个线程来执行该SQL请求就可以了,执行完成后,不销毁线程,而是把线程再归还到线程池中,等待下一次任务的处理(MySQL会根据连接量,自动加大线程池的数量)

并发连接数量和超时时间: max_connections

MySQL超时时间:wait_timeout

即对于超时未通信的连接,进行主动关闭操作

你可能感兴趣的:(MySQL,mysql,缓存,redis)