对于全栈而言,数据库技能不可或缺,关系型数据库或者nosql,内存型数据库或者偏磁盘存储的数据库,对象存储的数据库或者图数据库……林林总总,但是第一必备技能还应该是MySQL。从LAMP的兴起,到Mariadb的出现,甚至PG的到来,熟练的MySQL技能都是大有用武之地的。
MySQL数据库技术的方方面面也是很多,这里只涉及必备的性能调优,推崇从下向上的性能调优,主要包括运行环境,配置参数,SQL性能,和系统架构设计调优。
运行环境调优
这里是Linux的天下,MySQL 运行环境的调优往往和Linux的内核调优一并完成。当然了,对云服务RDS 也有一定的参考作用。
调整Linux默认的IO调度算法.
IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调度器也被叫做电梯 (elevator),而相应的算法也就被叫做电梯算法.而Linux中IO调度的电梯算法有好几种,一个叫做as(Anticipatory),一个叫做 cfq(Complete Fairness Queueing),一个叫做deadline,还有一个叫做noop(No Operation).
IO对数据库的影响较大,linux默认的IO调度算法为cfq,需要修改为deadline,如果是SSD或者PCIe-SSD设备,需要修改为noop,可以使用下面两种修改方式。
1、在线动态修改,重启失效。
echo “deadline” > /sys/block/sda/queue/scheduler
2、修改/etc/grub.conf,永久生效。
修改/etc/grub.conf配置文件,在kernel那行增加一个配置,例如:
elevator=deadline
主要关注elevator这个参数,设置内核的话需要重启系统才能生效。
禁用numa特性
新一代架构的NUMA不适合跑数据库,NUMA是为了内存利用率的提高,但反而可能导致一CPU的内存尚有剩余,另外一个却不够用了,发生swap的问题,因此一般建议关闭或修改NUMA的调度。
numa=off
2、修改/etc/init.d/mysql或mysqld_safe脚本,设置启动mysqld进程时的NUMA调度机制,如 numactl –interleave=all 。
修改swappiness设置
swappiness是linux的一个内核参数,用来控制物理内存交换出去的策略.它允许一个百分比的值,最小的为0,最大的为100,改值默认是60.这个设置值到底有什么影响呢?
vm.swappiness设置为0表示尽量少使用swap,100表示尽量将inactive的内存页交换到swap里或者释放cache。inactive内存的意思是程序映射着,但是”长时间”不用的内存。我们可以利用vmstat查看系统里面有多少inactive的内存。
# vmstat -a 1
这个值推荐设置为1,设置方法如下,在/etc/sysctl.conf文件中增加一行。
vm.swappiness = 1
扩大文件描述符
这个是经常修改的参数,高并发的程序都会修改.
ulimit -n 51200
2、修改配置文件,永久生效。
在/etc/security/limits.conf配置文件中增加
* hardnofile 51200 * softnofile 51200
面向session的进程文件描述符的修改稍有不同,在云上的修改也略有差异,可以参见一样的“open too many files”
优化文件系统挂载参数。
对于文件系统,如无特殊要求,最好采用ext4.
文件系统挂载参数是在/etc/fstab文件中修改,重启时候生效。
noatime表示不记录访问时间,nodiratime不记录目录的访问时间。
barrier=0,表示关闭barrier功能.
barrier的主要目的是为了保证磁盘写数据的安全性,但是会降低性能。如果有BBU之类的电池备份电源保证控制卡不瞬间掉电,那么这个功能就可以放心大胆的关闭。
配置参数调优
my.cnf中的配置参数调优取决于业务,负载或硬件,在慢内存和快磁盘、高并发和写密集型负载情况下,都需要特殊的调整。
基本配置
query_cache_size
query cache是一个众所周知的瓶颈,甚至在并发并不多时也如此。 最 好是一开始就停用,设置query_cache_size = 0,并利用其他方法加速查询:优化索引、增加拷贝分散负载或者启用额外的缓存(比如memcache或redis)。如果已经启用了query cache并且还没有发现任何问题,query cache可能有用。如果想停用它,那就得小心了。
innodb_buffer_pool_size
缓冲池是数据和索引缓存的地方:这个值越大越好,这能保证你在大多数的读取操作时使用的是内存而不是硬盘。典型的值是5-6GB(8GB内存),20-25GB(32GB内存),100-120GB(128GB内存)。
innodb_log_file_size
redo日志被用于确保写操作快速而可靠并且在崩溃时恢复。从MySQL 5.5之后,崩溃恢复的性能的到了很大提升,可以同时拥有较高的写入性能和崩溃恢复性能。在MySQL 5.6里可以被提高到4GB以上。如果应用程序需要频繁的写入数据,可以一开始就把它这是成4G。
max_connections
max_connection值被设高了(例如1000或更高)之后一个主要缺陷是当服务器运行1000个或更高的活动事务时会变的没有响应。在应用程序里使用连接池或