MySQL-26丨MySQL整体优化

Posted by jiefang on November 1, 2019

MySQL整体优化

硬件相关优化

  • CPU 相关
    • 关闭 CPU 节能,设定为最大性能模式。

      考虑到在高并发之前没有任何连接的情况,机器可能会处于节电模式,高并发场景来临时可能导致处理不过来新的请求。

    • 配置合理的 CPU 核数和选择合适的 CPU 主频。

      CPU 核数越多,支持的并发也越高;
      CPU 主频越高,处理任务的速度越快。

  • 内存相关 内存对 MySQL 数据库影响是非常大的。InnoDB 使用 InnoDB buffer pool 缓存数据、索引等内容,从而加快访问速度。因此 MySQL 运行的物理机上,内存配置也是比较重要的。

  • 磁盘相关
    • 使用 SSD(固态硬盘) 或者 Pcle SSD 设备;
    • 尽可能选择 RAID 10;

      原因是 RAID 10 是先镜像在分区数据,将所有的硬盘分为两组,看作 RAID 0 的最低组合,然后将两组各自看做 RAID 1 运作。
      RAID 10 有着不错的读取速度,而且拥有比 RAID 0 更高的数据保护性。

    • 设置阵列写策略为 Write Back。

      有阵列卡时,建议设置阵列写策略为 Write Back(简称:WB),WB 是指 RAID 控制器能够将写入的数据放入自身的缓存中,并把他们安排到后面再执行。
      其优点是:不需要每次写入都等物理磁盘实际写入才完成,因此大大提升了写入速度。

系统层面优化

  • 调整 I/O 调度算法
    MySQL 运行的物理机上,I/O 调度算法建议使用:deadline/noop,尽量不使用 CFQ。

    原因是 CFQ 把 I/O 请求按照进程分别放入进程对应的队列中。CFQ 的公平是针对进程而言,每一个提交 I/O 请求的进程都会有自己的 I/O 队列,以时间算法为前提,轮转调动队列,默认从当前队列中取出 4 个请求处理,然后处理下一个队列的 4 个请求,确保每个进程享有的 I/O 资源是均衡的。因此高并发场景,CFQ 很可能会导致 I/O 的响应缓慢。

  • 文件系统选择

    优先选用 xfs 或 ext4,坚决不用 ext3。 原因是: ext3 在 fsck 时需要耗费大量时间,文件越多,时间越长 。

  • 调整内核参数
    1
    
    vm.swappiness ≤ 10
    

    降低使用 swap 的概率,但是尽量不要设置为 0,可能引起 OOM。

    1
    
    vm.dirty_ratio ≤ 5
    

    这个参数指定了当文件系统缓存脏页数量达到系统内存百分之多少时(如10%),系统不得不开始处理缓存脏页(因为此时脏页数量已经比较多,为了避免数据丢失需要将一定脏页刷入外存);在此过程中很多应用进程可能会因为系统转而处理文件 IO 而阻塞。

    1
    
    vm.dirty_background_ratio ≤ 10
    

    避免因为 IO 压力瞬间飙升导致内核进程卡死,操作系统 hung 住。这个参数指定了当文件系统缓存脏页数量达到系统内存百分之多少时,就会触发 pdflush/flush/kdmflush 等后台回写进程运行,将一定缓存的脏页异步地刷入外存。

MySQL 层优化

  • 参数优化

在启动 MySQL 之前,一些参数合理的设置,可以大大提升 MySQL 的性能。

1
innodb_buffer_pool_size

该参数控制 InnoDB 缓存表和索引数据的内存区域大小。对性能影响非常大,建议设置为机器内存的 50-80%。

1
innodb_flush_log_at_trx_commit

InnoDB 的 redo 日志刷新方式,对 InnoDB 的影响会很大。

1
sync_binlog

控制累积多少个事务后才将二进制日志 fsync 到磁盘。

1
innodb_file_per_table

开启独立表空间。

1
max_connection

最大连接数。不能设置的过小,防止客户端连接失败;也不能设置的过大,防止数据库内存资源过多消耗。

1
long_query_time

慢查询时间阀值。

1
2
query_cache_type
query_cache_size

建议这两个参数都设置为 0,不使用查询缓存。

  • MySQL 设计优化
    • 使用 InnoDB 存储引擎,不建议使用 MyISAM 存储引擎;
    • 预估表数据量和访问量,如果数据量或者访问量比较大,则需要提前考虑分库分表;
    • 指定合适的数据库规范,在设计表、执行 SQL 语句时按照数据库规范来进行。