Snellere databases met MySQL 5.1 en Percona

londen-mysql2

The Big Ben

Enkele weken geleden zijn techneuten Wojtek en Gertjan twee dagen in Londen geweest, voor een zeer interessante MySQL-cursus. Deze cursus werd verzorgd door Percona, een bedrijf dat zich specialiseert in consultancy en performance-analyses voor MySQL-servers. Nu hebben we bij Byte in de vele jaren dat we MySQL beheren voor onze klanten, natuurlijk veel ervaring opgedaan met betrekking tot het beheer en de performance van MySQL. Het kan echter nooit kwaad om eens te horen wat de echte specialisten hierover zeggen. In die twee dagen hebben we een hoop geleerd: MySQL is een prachtig product, maar het kent z'n quirks. En pas als je weet wat die quirks zijn kun je er rekening mee houden bij het configureren van een server. In deze blogpost zal ik allereerst ingaan op het resultaat van deze training, omdat dat natuurlijk is waar u als (potentiële) klant het meest aan heeft. Verder zal ik een aantal van de aanpassingen toelichten die we gedaan hebben.

MySQL (groen) gebruikt niet meer dan 2 GB op een 32-bits server. Gelukkig vindt Linux resterend geheugen ook lekker als cache voor bestanden (oranje).

MySQL (groen) gebruikt niet meer dan 2 Gigabyte op een 32-bits server. Gelukkig vindt Linux resterend geheugen ook lekker als cache voor bestanden (oranje).

De grootste verschillen tussen de oude en de nieuwe MySQL-opstelling, zit in de versie van MySQL en de versie van het besturingssysteem. We maken bij Byte voor heel veel servers nog steeds gebruik van 32-bits software. De noodzaak om naar 64-bits software over te stappen is er eigenlijk niet, omdat websites nooit meer dan 3.2 GB aan intern geheugen mogen en kunnen gebruiken. De enige software die we gebruiken die dat mogelijk wel doet, is, u raadt het al, MySQL. Voor onze nieuwe databaseservers zijn we dus overgestapt naar 64-bits Linux en 64-bits MySQL. Het meeste werk daarbij was nog het geschikt maken van onze build-omgeving voor 64-bits software ;-) .

Qua hardware gebruikten we altijd al behoorlijk zware servers: 4 tot 6 snelle harde schijven in een RAID-5 opstelling, 4 tot 8 GB intern geheugen en snelle 4 tot 8 core Xeon-processoren. Het viel ons echter al vaak op dat de servers die we hadden niet hun volledige potentiaal benutten. Meestal werden de disks het eerst een bottleneck. Daarnaast zagen we op servers met 8 (of meer) CPU's dat eigenlijk alleen de eerste CPU zwaar belast werd, de tweede een stuk minder zwaar en de overige cores hadden eigenlijk heel weinig te doen. Zonde!

Het ontlasten van disks kunnen we voor een deel opvangen met meer, of nog snellere schijven, en met een andere RAID-opstelling. RAID-10 geeft bijvoorbeeld iets minder opslagcapaciteit dan RAID-5, maar het is én sneller, én veiliger. Verder kunnen de disks ook ontlast worden door de server meer intern geheugen te geven. MySQL kan daarmee veel meer data in het snelle RAM houden, en hoeft het niet elke keer van de relatief langzame disks te lezen.

Gebruik van CPU's 0, 1 en 7. CPU's 2 t/m zijn niet getoond, maar liggen in gebruik tussen 1 en 7 in. Duidelijk is te zien dat Linux vooral core 0 gebruikt, en de resterende nauwelijks.

Gebruik van CPU's 0, 1 en 7. CPU's 2 t/m zijn niet getoond, maar liggen in gebruik tussen 1 en 7 in. Duidelijk is te zien dat Linux vooral core 0 gebruikt, en de resterende nauwelijks.

De volgende, en minstens zo belangrijke, stap, is de versie van MySQL zelf. We gebruikten altijd nog versie 5.0 van MySQL. Deze versie staat erom berucht dat het vrij slecht schaalt op moderne, multicore, CPU's. Versie 5.1 van MySQL zou hier een stuk beter mee om moeten gaan. Uiteraard kan het altijd nog beter, en Percona heeft een aantal aanpassingen voor MySQL gemaakt die het nog beter laat presteren op multi-core CPU's. Verderop in dit artikel kunt u iets meer technische informatie vinden over de aanpassingen van Percona. Deze slimme verbeteringen hebben wij ook in de nieuwe setup verwerkt.

Op dit moment hebben we de eerste machine, gebaseerd op onze nieuwe inzichten, in productie draaien, en de snelheid is fantastisch! Er draaien inmiddels een aantal sites van onze klanten op, die ik hartelijk wil danken voor hun hulp bij het testen! Op het stabiele platform zijn backups normaal beschikbaar en wordt er uiteraard ook gebruik gemaakt van een replicator. We zijn op zoek naar meer mensen die hun site op dit nieuwe platform willen testen. Het overzetten doen wij voor u, en gaat zonder downtime of dataverlies. Indien u interesse heeft kunt u zich aanmelden via support@byte.nl.


Technische details

Om dit artikel af te sluiten wil ik een drietal aanpassingen van Percona toelichten, om enerzijds te laten zien wat een vreemde quirks er soms in veel gebruikte software zit, en anderzijds om te laten zien hoe complex performanceverbeteringen kunnen zijn. De verbeteringen die Percona gemaakt heeft richten zich met name op InnoDB, een van de storage-engines van MySQL.

Voor de eerste twee verbeteringen is het belangrijk om te weten dat MySQL en InnoDB multi-threaded zijn. Dat wil zeggen dat die ene MySQL-server waar uw site zijn data in opslaat, feitelijk bestaat uit een heleboel (honderden) mini-programmaatjes die allemaal met elkaar samenwerken. Het voordeel van multi-threaded software is, dat elk van deze threads op een andere CPU-core kan draaien. Het nadeel is echter dat ze onderdeel uitmaken van dezelfde applicatie (MySQL), en dus ook informatie moeten delen. Het delen van deze informatie kan ervoor zorgen dat die threads soms op elkaar moeten wachten.

CPU-gebruik met MySQL 5.1. Nog steeds heeft Linux een voorkeur voor CPU 0, maar de overige CPU's worden een stuk beter benut!

CPU-gebruik met MySQL 5.1. Nog steeds heeft Linux een voorkeur voor CPU 0, maar de overige CPU's worden een stuk beter benut!

Twee van de threads in de InnoDB-engine hebben een bijzondere taak: de ene leest data van disk naar het interne geheugen, om ervoor te zorgen dat die data klaar staat en snel beschikbaar is als het nodig is. De andere zorgt ervoor dat data die gewijzigd is, ook daadwerkelijk van het interne geheugen op disk opgeslagen wordt. Traditioneel heeft InnoDB maar één van beide threads, waardoor het lezen of schrijven (in de achtergrond) onder bepaalde omstandigheden lang kan duren. Percona heeft echter een aanpassing gemaakt, waardoor het mogelijk wordt om meerdere van deze threads te gebruiken. Hierdoor schaalt MySQL beter op meerdere CPU's.

Verder doet InnoDB een vreemde aanname: het neemt aan dat het op een server draait met slechts 1 harde schijf! Van harde schijven kan aan de hand van het type bepaald worden hoeveel operaties per seconde (IOPS) hij uit kan voeren. Een standaard 7200 RPM SATA schijf uit een normale PC kan maximaal 100 IOPS verwerken. Een snelle 10.000 RPM SAS schijf voor servers kan 140 IOPS aan, en een 15.000 RPM SAS schijf kan er 170 aan. (Over IOPS wordt erg veel gediscussieerd, en de genoemde getallen zeggen eigenlijk vrij weinig over hoeveel performance een disk echt kan leveren, want dat hangt van veel meer zaken af. Het gaat me er echter om om het verschil tussen de verschillende typen aan te geven).

InnoDB limiteert alle threads die data willen lezen of schrijven tot een maximum van 100 operaties per seconde! Dat wil zeggen dat InnoDB nooit optimaal kan profiteren van de dure en snelle schijven die je in een server stopt! De helden van Percona hebben ervoor gezorgd dat deze limiet instelbaar wordt, en dat je als beheerder zelf in kan schatten hoeveel operaties je server aankan. Een bijzonder handige verbetering!

De laatste verbetering die ik toe wil lichten, heeft te maken met het eerder genoemde delen van informatie tussen threads. Als meerdere threads tegelijkertijd dezelfde data willen wijzigen (meerdere bezoekers die tegelijk een reactie in gastenboek schrijven), dan moet MySQL ervoor zorgen dat één van de twee threads voorrang krijgt, en dat de andere moet wachten totdat de eerste thread klaar is. Dit gebeurt met zogenaamde locks of mutexes. De programmeurs van MySQL zijn echter vrij lui geweest, en hebben hier hele grote mutexes voor gebruikt. Er wordt veel meer data gelocked voor andere threads, dan strikt noodzakelijk is. Daardoor moeten threads vaak lang op elkaar wachten, wat een van de belangrijkste redenen is dat MySQL slecht schaalt op meerdere cores.
Percona heeft een verbetering gemaakt, die de grote locks opbreekt in meerdere kleine locks. Hierdoor kunnen meer threads tegelijk van (bijna) dezelfde data gebruik maken.

Conclusie

Met de nieuwe hardware, nieuwe software en nieuwe instellingen hebben we een supersnelle databasesetup gecreëerd. De toekomst zal uit moeten wijzen hoeveel sneller we hier daadwerkelijk mee zijn, want synthetische benchmarks kunnen geven maar beperkt inzicht. De eerste resultaten zijn in elk geval veelbelovend.

We hebben nog een aantal leuke ontwikkelingen in de pijplijn zitten, die we hopelijk binnenkort uit kunnen gaan werken. Hierbij kunt u onder andere denken aan verbeterde databasebackups, zodat ze sneller en makkelijker teruggezet kunnen worden, en het gebruiken van onze replicators als read-nodes voor alle leesqueries.

If you liked this post, say thanks by sharing it:
  • http://www.davidbaakman.nl David Baakman

    Indien blijkt dat je IO op de databaseserver de bottleneck is, dan is het misschien ook een goed idee om eens te kijken naar SSD’s.

    Met 12 SSD’s (in RAID-0 – bewuste keuze) haalden we op een DB2 database een betere performance dan met een (gesharede, dat wel) IBM DS4800 met 128 schijven. Het enige ‘probleem’ waar we tegen aan liepen is dat Dell niet echt een prijstechnisch interessante aanbieding wou doen en we – na 10 jaar een Dell-only shop te zijn geweest – voor zelfbouw hebben gekozen (Supermicro SC216 als enclosure, icm Intel X25-M’s, gekoppeld via een PERC H800). Maar op die manier heb je voor relatief weinig geld een vrij heftige hoeveelheid iops.

    Overigens lijkt me 4-8 GB geheugen voor een databaserver tegenwoordig aan de lage kant. Is dat niet de reden waarom je IO zo ontzettend de bottleneck vormt? Het is natuurlijk helemaal afhankelijk van je type load en je data, dat besef ik terdege, maar ‘t zou me niets verbazen wanneer je bufferpool hit ratio te laag is, en MySQL daardoor vaker dan wenselijk terug moet naar disk.

  • http://www.byte.nl Gertjan Oude Lohuis

    Hoi David, dank voor je reactie!
    We hebben ook serieus naar SSD’s gekeken, alleen zijn die prijstechnisch op dit moment niet echt interessant voor onze shared databaseclusters. We hebben vooral veel ruimte nodig voor de grote databases van onze klanten, gecombineerd met veel RAM om de veel gebruikte data te kunnen cachen. Wij hebben helaas niet de luxe van een eigen applicatie in een gecontroleerde omgeving, waar je je hardware op aan kan passen, we moeten keuzes maken.

    Hoe is jullie ervaring trouwens met SSD’s op een hardware RAID-controller? Gebruik je hardware RAID-0, of gebruik je de controller alleen als JBOD zonder de NVRAM van de controller te gebruiken? Volgens mij zijn er nog geen hardware RAID-controllers die goed met SSD’s om weten te gaan. Het gebruik van NVRAM zorgt bij trage mechanische schijven voor een enorme versnelling, maar bij SSD’s juist voor vertraging omdat die zelf eigenlijk geen access- en seektime hebben.

    Overigens heb je gelijk over die 4-8 GB, dat is eigenlijk vrij weinig voor serieuze databaseservers. Het is echter wel zo dat onze servers verschrikkelijk moeilijk te configureren en optimaliseren zijn, omdat er zoveel verschillende databases op draaien. Maar hopelijk kunnen we dat met een grote hoeveelheid geheugen in deze nieuwe setup opvangen.

  • http://www.davidbaakman.nl David Baakman

    Op het moment dat je echt veel ruimte nodig hebt worden SSD’s inderdaad een dure hobby…. Dat had ik overigens niet 1-2-3 verwacht bij shared hosting, dat je dan erg veel ruimte nodig hebt. Bij mijn shared host heb ik volgens mij iets van 50MB db ruimte; dat zijn (ruimtetechnisch) 160 klanten per 80 GB SSD. Waarschijnlijk verkijk ik me helemaal op de hoeveelheden/server hoor, bij ons gebeurt het zelden dat er meer dan 1 applicatie op een databaseserver in productie draait.

    Ik kan me trouwens ook wel voorstellen dat het lastig te optimaliseren is zonder invloed te hebben op de applicaties: met een paar slechte queries die full table scans doen over grote tabellen krijg je een database server wel plat, en dat heeft invloed op de rest van de applicaties die connecten naar die database server.

    Die servers waar we SSD’s op gebruiken draaien we inderdaad hardware RAID-0 (en zonder trim), maar ik heb geen flauw idee van de block groottes of cache settings. En ja, ik verwacht dat we qua snelheid puur gelimiteerd worden door de controller (die 12 stuks zijn ook alleen maar bedoeld voor de ruimte, niet voor de snelheid). Maar in dit geval geldt: snel genoeg is snel genoeg, en het is een tijdelijke omgeving. Dus het zal absoluut nog wel sneller kunnen, of beter, maar dat is prijstechnisch gezien niet interessant om uit te zoeken.