MySQL数据库在优化分为MySQL应用级别优化和服务器系统优化两部分,数据库服务器系统优化部分主要从CPU、内存、硬盘、文件系统、资源限制、OS内核参数、磁盘IO调度策略等几个方面进行优化。
- CPU
OS选择64位的系统。
高并发的场景,cpu数量比频率重要。
CPU密集型的场景和复杂sql则频率越高越好。
- 内存大小选择
采用主板能使用的最高频率的内存。
内存尽可能大。
- 服务器磁盘IO优先选择。
PCIe > SSD > Raid > 机械硬盘 > 网络存储(SAN)
- 文件系统对性能影响
ext3、ext4、xfs(性能更高)都具备日志功能,对数据安全性较好。选择 xfs,设置noatime,nodiratime
#data=writeback(Innodb最好的选择)|ordered|journal #noatime 参数禁止记录最近一次访问时间戳,提高磁盘 IO 的效率、提升文件系统的性能。 #nodiratime,目录访问时间 /dev/sda5 /data xfs defaults,noatime,nodiratime 1 2
- 资源限制(/etc/security/limit.conf)
limits.conf 文件实际是 Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so 的配置文件,而且只针对于单个会话。修改打开文件数的限制。
vim /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 # 控制打开文件数量的限制,加到文件末尾就可以 # * 表示对所有用户有效 # soft 指的是当前系统生效的设置 # hard 表明系统中所能设定的最大值 # nofile 表示所限制的资源是打开文件的最大数目 # 65535 就是限制的数量 # 结论:把可打开的文件数量增加到了65535个以保证可以打开足够多的文件句柄 # 注意:这个文件的修改需要重启系统才可以生效
- OS内核相关参数调优(/etc/sysctl.conf)
网络相关参数
#网络性能设置 net.core.somaxconn = 65535 # listen挂起请求的最大数量,默认128 。 net.core.netdev_max_backlog = 65535 # 接受数据的速率。 net.ipv4.tcp_max_syn_backlog = 65536 # 进入SYN的最大请求队列,超过时会被丢弃。默认是1024 # 加快tcp链接的回收 net.ipv4.tcp_fin_timeout = 10 # tcp连接处理等待时间 net.ipv4.tcp_tw_reuse = 1 # 1是开启重用,允许讲TIME_AIT sockets重新用于新的TCP连接,默认是0关闭 net.ipv4.tcp_tw_recycle = 1 # TCP失败重传次数,默认是15,减少次数可释放内核资源。 # tcp链接接收和发送,缓冲区大小的默认值和最大值 net.core.wmem_default = 87380 # 发送缓存区大小的缺省值 net.core.wmem_max = 16777216 # 发送缓冲区大小的最大值 net.core.rmem_default = 87380 # 接受套接字缓冲区大小的缺省值(以字节为单位) net.core.rmem_max = 16777216 # 最大接收缓冲区大小的最大值 # 失效链接所占用的tcp占用资源的数量,加快资源回收的效率 net.ipv4.tcp_keepalive_time = 120 # 在TCP保活打开的情况下,最后一次数据交换到TCP发送第一个保活探测包的间隔,即允许的持续空闲时长,或者说每次正常发送心跳的周期,默认值为7200s(2h)。 net.ipv4.tcp_keepalive_intvl = 30 # 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包的发送频率,默认值为75s。 net.ipv4.tcp_keepalive_probes = 3 # 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认值为9(次)
内存相关参数
# Linux内核参数中最重要的参数之一,用于定义单个共享内存段的最大值 # 注意:1这个参数应该设置的足够大,以便能在一个共享内存段下容纳下整个的 Innodb 缓冲池的大小 # 注意:2这个值的大小对于64位linux系统,可取的最大值为物理内存值-1byte,建议值为大于物理内存的一半,一般取值大于 Innodb 缓着冲池的大小即可,可以取物理内存-1byte kernel.shmmax = 4294967295 # 这个参数当内存不足时会对性能产生比较明显的影响 # Linux系统内存交换区: # 在 Linux 系统安装时都会有一个特殊的磁盘分区,称之为系统交换分区 # 如果我们使用free-m在系统中查看可以看到类似下面的内容其中swap就是交换分区 # 当操作系统因为没有足够的内存时,就会将一些虚拟内存写到磁盘的交换区中,这样就会发生内存交换 # 在MySQL服务器上是否要使用交换分区有一些争议: # 在MySQL服务所在的 Linux系统上完全禁用交换分区,不使用交换分区,速度更快带来的风险: # 1、降低操作系统的性能。 # 2、容易造成內存溢岀,崩溃,或都被操作系统kill掉。 # 结论: 在 MySQL服务器上保留交换区还是很必要的,但是要控制何时使用交换分区。 vm swampiness = 0 # 就是告诉LinuX内核除非虚拟内存完全满了,否则不要使用交换区。
- 磁盘调度策略(/sys/block/devname/queue/scheduler)
磁盘IO调度策略可通过配置文件(/sys/block/devname/queue/scheduler)调整,IO调度策略一般有btrfs cfq、noop、deadline 三种:
IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调度器也被叫做电梯,(elevator)而相应的算法也就被叫做电梯算法。Linux中IO调度的电梯算法通过内核参数elevator来指定,主要有以下几种:
-
- noop(NoOperation)
- deadline
- AS(Anticipatory scheduler)
- CFQ(Complete Fairness Queueing)
1)noop(电梯式调度策略)
在Linux2.4或更早的版本的调度程序,那时只有这一种I/O调度算法。 NOOP实现了一个简单的FIFO队列,它像电梯的工作主法一样对I/O请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求之后,以此来保证请求同一介质. NOOP倾向饿死读而利于写。 NOOP对于闪存设备,RAM,嵌入式系统是最好的选择。 电梯算法饿死读请求的解释: 因为写请求比读请求更容易。 写请求通过文件系统cache,不需要等一次写完成,就可以开始下一次写操作,写请求通过合并,堆积到I/O队列中。 读请求需要等到它前面所有的读操作完成,才能进行下一次读操作。在读操作之间有几毫秒时间,而写请求在这之间就到来,饿死了后面的读请求。
2)deadline(截止时间调度策略)
通过时间以及硬盘区域进行分类,这个分类和合并要求类似于noop的调度程序。 Deadline确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限。这样就防止了写操作因为不能被读取而饿死的现象。 Deadline对数据库环境(ORACLERAC,MYSQL等)是最好的选择。
3)AS (预料I/O调度程序)
AS(Anticipatory scheduler )本质上与Deadline一样,但在最后一次读操作后,要等待6ms,才能继续进行对其它I/O请求进行调度。 可以从应用程序中预订一个新的读请求,改进读操作的执行,但以一些写操作为代价。 它会在每个6ms中插入新的I/O操作,而会将一些小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量。 AS适合于写入较多的环境,比如文件服务器。 AS对数据库环境表现很差。
4)CFQ(完全公平排队I/O调度程序)
在最新的内核版本和发行版中,都选择CFQ(Complete Fairness Queueing)做为默认的I/O调度器,对于通用的服务器也是最好的选择。 CFQ试图均匀地分布对I/O带宽的访问,避免进程被饿死并实现较低的延迟,是deadline和as调度器的折中。 CFQ对于多媒体应用(video,audio)和桌面系统是最好的选择。 CFQ赋予I/O请求一个优先级,而I/O优先级请求独立于进程优先级,高优先级的进程的读写不能自动地继承高的I/O优先级。 CFQ为每个进程/线程,单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度, 以此来保证每个进程都能被很好的分配到I/O带宽。I/O调度器每次执行一个进程的4次请求。
5) 修改调度策略
#修改为 deadline 策略 echo deadline > /sys/block/sda/queue/scheduler