Die meisten Umgebungen, in denen MySQL derzeit ausgeführt wird, laufen unter Linux. Hier finden Sie einige allgemeine und einfache Strategien zur Optimierung von MySQL auf dem Linux-Betriebssystem. Diese Methoden tragen alle dazu bei, die MySQL-Leistung zu verbessern.
Hören Sie auf zu chatten und kommen Sie auf den Punkt.
1. CPU
Beginnen wir mit der CPU.
Wenn Sie sorgfältig prüfen, gibt es auf einigen Servern ein interessantes Phänomen: Wenn Sie /proc/cpuinfo eingeben, werden Sie feststellen, dass die CPU-Frequenz von der Nennfrequenz abweicht:
#cat /proc/cpuinfo processor : 5 model name : Intel(R) Xeon(R) CPU E5-2620 0 @2.00GHz ... cpu MHz : 1200.000
Das ist Die Intel E5-2620-CPU ist eine 2,00G * 24-CPU. Wir haben jedoch festgestellt, dass die Frequenz der fünften CPU 1,2G beträgt.
Was ist der Grund dafür?
Diese basieren tatsächlich auf der neuesten CPU-Technologie: dem Energiesparmodus. Das Betriebssystem arbeitet mit der CPU-Hardware zusammen, um Strom zu sparen und die Temperatur zu senken. Das ist ein Segen für Umweltschützer und den Kampf gegen die globale Erwärmung, aber für MySQL könnte es eine Katastrophe sein.
Um sicherzustellen, dass MySQL die CPU-Ressourcen voll ausnutzen kann, wird empfohlen, die CPU auf den maximalen Leistungsmodus zu setzen. Diese Einstellung kann im BIOS und Betriebssystem vorgenommen werden. Natürlich ist die Einstellung dieser Option im BIOS besser und gründlicher. Aufgrund der Unterschiede zwischen verschiedenen BIOS-Typen ist die Einstellung der CPU auf den Maximalleistungsmodus sehr unterschiedlich, daher zeigen wir Ihnen hier nicht, wie Sie die Einstellung vornehmen.
2. Speicher
Dann schauen wir uns den Speicher an und was wir optimieren können.
i) Werfen wir zunächst einen Blick auf Numa
Non-Uniform Memory Access Structure (NUMA: Non-Uniform Memory Access) ist ebenfalls die neueste Speicherverwaltungstechnologie. Sie entspricht der symmetrischen Multiprozessor-Architektur (SMP: Symmetric Multi-Processor).
Die Kosten für den SMP-Zugriff auf den Speicher sind gleich, aber unter der NUMA-Architektur sind die Kosten für den lokalen Speicherzugriff und den nicht-lokalen Speicherzugriff unterschiedlich. Entsprechend dieser Funktion können wir im Betriebssystem die Speicherzuweisungsmethode des Prozesses festlegen. Zu den derzeit unterstützten Methoden gehören:
–interleave=nodes
–membind=nodes
–cpunodebind=nodes
–physcpubind=cpus
–localalloc
–preferred=node
Kurz gesagt, Sie können angeben, dass Speicher lokal, auf bestimmten CPU-Knoten oder bei der Abfrage zugewiesen wird. Sofern der Abfragezuweisungsmodus –interleave=nodes nicht festgelegt ist, kann Speicher auf jedem NUMA-Knoten zugewiesen werden. Selbst wenn auf anderen NUMA-Knoten noch Speicher vorhanden ist, weist Linux den verbleibenden Speicher diesem Prozess nicht zu, sondern verwendet SWAP, um Speicher abzurufen. Erfahrene Systemadministratoren oder DBAs wissen alle, wie zerstörerisch die durch SWAP verursachte Verschlechterung der Datenbankleistung sein kann.
Am einfachsten ist es also, diese Funktion zu deaktivieren.
Zu den Methoden zum Deaktivieren der Funktion gehören: Sie können diese Funktion vorübergehend über das BIOS, das Betriebssystem oder beim Starten des Prozesses deaktivieren.
a) Aufgrund der Unterschiede in den verschiedenen BIOS-Typen ist die Vorgehensweise zum Deaktivieren von NUMA sehr unterschiedlich, daher zeigen wir Ihnen hier nicht, wie Sie es einrichten.
b) Um es im Betriebssystem zu deaktivieren, können Sie numa=off direkt am Ende der Kernelzeile in /etc/grub.conf hinzufügen, wie unten gezeigt:
kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/VolGroup-root rd_NO_LUKS.UTF-8 rd_LVM_LV=VolGroup/root rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto rd_LVM_LV=VolGroup/swap rhgb crashkernel=auto quiet KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off
In Darüber hinaus können Sie vm.zone_reclaim_mode=0 festlegen. Versuchen Sie, so viel Speicher wie möglich zurückzugewinnen.
c) Deaktivieren Sie beim Starten von MySQL die NUMA-Funktion:
numactl --interleave=all mysqld &
Natürlich ist es am besten, sie im BIOS auszuschalten.
ii) Schauen wir uns noch einmal vm.swappiness an.
vm.swappiness ist die Strategie des Betriebssystems zur Steuerung des physischen Speicheraustauschs. Die zulässigen Werte sind Prozentsätze mit einem Minimum von 0 und einem Maximum von 100. Der Standardwert ist 60. Das Setzen von vm.swappiness auf 0 bedeutet, so wenig wie möglich auszutauschen, und 100 bedeutet, so viele inaktive Speicherseiten wie möglich auszutauschen.
Um genau zu sein: Wenn der Speicher grundsätzlich voll ist, bestimmt das System anhand dieses Parameters, ob der selten genutzte inaktive Speicher im Speicher ausgetauscht oder der Datencache freigegeben werden soll. Der Cache speichert Daten, die von der Festplatte gelesen werden, in der Zukunft möglicherweise erneut, wie der Name schon sagt „Langzeit“-Erinnerung.
Wir können vmstat verwenden, um die Menge des inaktiven Speichers anzuzeigen:
#vmstat -an 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free inact active si so bi bo in cs us sy id wa st 1 0 0 27522384 326928 1704644 0 0 0 153 11 10 0 0 100 0 0 0 0 0 27523300 326936 1704164 0 0 0 74 784 590 0 0 100 0 0 0 0 0 27523656 326936 1704692 0 0 8 8 439 1686 0 0 100 0 0 0 0 0 27524300 326916 1703412 0 0 4 52 198 262 0 0 100 0 0
Detailliertere Informationen können Sie über /proc/meminfo anzeigen:
#cat /proc/meminfo | grep -i inact Inactive: 326972 kB Inactive(anon): 248 kB Inactive(file): 326724 kB
这里我们对不活跃inactive内存进一步深入讨论。Linux中,内存可能处于三种状态:free,active和inactive。众所周知,Linux Kernel在内部维护了很多LRU列表用来管理内存,比如LRU_INACTIVE_ANON, LRU_ACTIVE_ANON, LRU_INACTIVE_FILE , LRU_ACTIVE_FILE, LRU_UNEVICTABLE。其中LRU_INACTIVE_ANON, LRU_ACTIVE_ANON用来管理匿名页,LRU_INACTIVE_FILE , LRU_ACTIVE_FILE用来管理page caches页缓存。系统内核会根据内存页的访问情况,不定时的将活跃active内存被移到inactive列表中,这些inactive的内存可以被交换到swap中去。
一般来说,MySQL,特别是InnoDB管理内存缓存,它占用的内存比较多,不经常访问的内存也会不少,这些内存如果被Linux错误的交换出去了,将浪费很多CPU和IO资源。 InnoDB自己管理缓存,cache的文件数据来说占用了内存,对InnoDB几乎没有任何好处。
所以,我们在MySQL的服务器上最好设置vm.swappiness=0。
我们可以通过在sysctl.conf中添加一行:
echo "vm.swappiness = 0" >>/etc/sysctl.conf
并使用sysctl -p来使得该参数生效。
三、文件系统
最后,我们看一下文件系统的优化
i)我们建议在文件系统的mount参数上加上noatime,nobarrier两个选项。
用noatime mount的话,文件系统在程序访问对应的文件或者文件夹时,不会更新对应的access time。一般来说,Linux会给文件记录了三个时间,change time, modify time和access time。
我们可以通过stat来查看文件的三个时间:
stat libnids-1.16.tar.gz File: `libnids-1.16.tar.gz' Size: 72309 Blocks: 152 IO Block: 4096 regular file Device: 302h/770d Inode: 4113144 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access : 2008-05-27 15:13:03.000000000 +0800 Modify: 2004-03-10 12:25:09.000000000 +0800 Change: 2008-05-27 14:18:18.000000000 +0800
其中access time指文件最后一次被读取的时间,modify time指的是文件的文本内容最后发生变化的时间,change time指的是文件的inode最后发生变化(比如位置、用户属性、组属性等)的时间。一般来说,文件都是读多写少,而且我们也很少关心某一个文件最近什么时间被访问了。
所以,我们建议采用noatime选项,这样文件系统不记录access time,避免浪费资源。
现在的很多文件系统会在数据提交时强制底层设备刷新cache,避免数据丢失,称之为write barriers。但是,其实我们数据库服务器底层存储设备要么采用RAID卡,RAID卡本身的电池可以掉电保护;要么采用Flash卡,它也有自我保护机制,保证数据不会丢失。所以我们可以安全的使用nobarrier挂载文件系统。设置方法如下:
对于ext3, ext4和 reiserfs文件系统可以在mount时指定barrier=0;对于xfs可以指定nobarrier选项。
ii)文件系统上还有一个提高IO的优化万能钥匙,那就是deadline。
在Flash技术之前,我们都是使用机械磁盘存储数据的,机械磁盘的寻道时间是影响它速度的最重要因素,直接导致它的每秒可做的IO(IOPS)非常有限,为了尽量排序和合并多个请求,以达到一次寻道能够满足多次IO请求的目的,Linux文件系统设计了多种IO调度策略,已适用各种场景和存储设备。
Linux的IO调度策略包括:Deadline scheduler,Anticipatory scheduler,Completely Fair Queuing(CFQ),NOOP。每种调度策略的详细调度方式我们这里不详细描述,这里我们主要介绍CFQ和Deadline,CFQ是Linux内核2.6.18之后的默认调度策略,它声称对每一个 IO 请求都是公平的,这种调度策略对大部分应用都是适用的。但是如果数据库有两个请求,一个请求3次IO,一个请求10000次IO,由于绝对公平,3次IO的这个请求都需要跟其他10000个IO请求竞争,可能要等待上千个IO完成才能返回,导致它的响应时间非常慢。并且如果在处理的过程中,又有很多IO请求陆续发送过来,部分IO请求甚至可能一直无法得到调度被“饿死”。而deadline兼顾到一个请求不会在队列中等待太久导致饿死,对数据库这种应用来说更加适用。
实时设置,我们可以通过
echo deadline >/sys/block/sda/queue/scheduler
来将sda的调度策略设置为deadline。
我们也可以直接在/etc/grub.conf的kernel行最后添加elevator=deadline来永久生效。
总结
CPU方面
关闭电源保护模式
内存:
vm.swappiness = 0
关闭numa
文件系统:
用noatime,nobarrier挂载系统
IO调度策略修改为deadline。