https://www.youtube.com/watch?v=TI3nyrgrSsk&list=PLSeI7hpg1UEeghysjmOWZjohZDEpN78he&index=9
http://raykie.cn:5244/博客云盘/来自分享/拉勾教育 101套开发课程/后端&架构/5_高性能MySQL实战/文档/[55] 第06讲:如何突破单库性能瓶颈?.md
我们来看看对数据库所在的服务器是如何进行优化的,服务器是数据库的宿主,其性能直接影响了数据库的性能,所以服务器的优化也是数据库优化的第一步。
数据库服务器通常是从 CPU、内存、磁盘三个角度进行硬件优化的,网络方面取决于实际负载,建议使用万兆网络。
首先讲下从 CPU 角度进行优化。
MySQL 对于 CPU 的运行需求各个版本均有不同,在 MySQL 5.1 版本以前对多核支持弱,近乎单核。MySQL 5.1 版本可以利用 4 核,MySQL 5.5 版本可以利用到 24 核,MySQL 5.6 版本可利用到 64 核,MySQL 5.6 版本后多核支持加强,可以支持到 128 核甚至更多。
对于 MySQL 而言,由于每个连接对应一个线程,每个并发 Query 只能使用一个核,即 MySQL 在执行单个 SQL 语句的时候底层只能用到一个 CPU 核,所以要想提升 SQL 执行效率,单个 SQL 执行尽可能快。在考虑 CPU 的时候,我们应该优先选择高主频 CPU 来加速单条 SQL 语句的执行效率。
由于 MySQL 每个并发 Query 只能使用一个核,MySQL 引入了 Thread Pool 功能来提升性能。Thread Pool 最开始是由 MariaDB 引入,Percona 在其基础上引入了优先级队列,官方后续引进。
通过参数 thread_handling 可以查看线程池模型,主要有 one-connection-per-thread 和 one-thread-per-connection 两类,建议使用 one-thread-per-connection。
在 5.6 版本之前 MySQL 连接处理的方式是 one-connection-per-thread,对于每一个数据库连接 MySQL Server 都会创建一个独立的线程服务(建立连接:CPU 划分一定的 thread stack 后进行用户身份认证,建立上下文信息,请求处理后关闭连接,释放资源),处理请求后销毁线程。
初期 Thread Pool 虽然可以事先创建一批线程并复用,但是无法解决高连接数的问题。one-connection-per-thread 方式随着连接数暴增同样会退化为单线程并创建更多的服务线程,高并发线程和高连接数意味着内存消耗加剧,进而出现由于上下文切换、资源争用、CPU 和内存负载高而导致服务出现抖动。
而采用 one-thread-per-connection 的方式是一个线程对应一个连接,在其 Thread Pool 的实现方式中,线程处理的最小单位是 statement(SQL 语句),一个线程可以处理多个连接的请求。这样,在保证充分利用硬件资源情况下(合理设置线程池大小),可以避免瞬间连接数暴增导致的服务器抖动。