Inleiding
Inleiding
Het is alweer enige tijd geleden dat we een uitvoerig overzicht van onze servers hebben gegeven. Met de start van ons Phoenix-project is er bovendien flink wat veranderd. De recentste toevoeging is onze nieuwe databaseserver Artemis 7. We richten ons in dit artikel op de hardware- en softwareconfiguratie van de servers.
Momenteel gebruiken we 25 fysieke servers om Tweakers in de lucht te houden. Een van de redenen voor dat aantal is dat zo nog een groot deel kan uitvallen voordat je echt niks meer op je scherm krijgt bij een bezoek aan ons
De servers zijn verdeeld over drie racks. Zoals te lezen is in het Phoenix-verhaal, staan twee daarvan op onze primaire locatie en de derde op de secundaire locatie. Naast de servers zit er nog meer hardware in die racks. We hebben negen switches, drie loadbalancers, zes pdu's, twee kvm-switches, twee 'out of band'-routers en drie racklades in gebruik. In het verhaal over Phoenix is de netwerkstructuur uitvoerig beschreven. Aangezien daar verder niets aan veranderd is, slaan we die in dit verhaal over.

Racks 1 en 2 in EUnetworks en rack '3' in Telecity. Helaas is het moeilijk om rechte foto's te maken in die krappe gangen…
De drie racks lijken erg leeg, maar schijn bedriegt. Achter de bovenste afdekplaten zitten nog de diverse switches (3 à 4 per rack), kabelgeleiders en andere zaken die 'naar achteren' zijn opgehangen, zoals de kvm's en access routers. Die opvallende Google search-appliance is overigens, als enige machine in onze racks, niet voor Tweakers in gebruik; hij doet werk voor onze zustersite Computable.
Zoals je ziet komt er aardig wat bij kijken om een site als Tweakers in de lucht te houden. De vraag of dat 'allemaal wel nodig is' lezen we vaak als we hierover uitwijden. Het is niet zo makkelijk om zomaar 'ja' op die vraag te antwoorden. Wat wij nodig vinden, zal een ander overdreven krachtig of uitgebreid vinden. Wij hebben onszelf echter tot doel gesteld om een hoge uptime te combineren met een zeer goede performance van de site. Beide principes moeten wat ons betreft ook blijven gelden bij zo veel mogelijk onverwachte pieken in de belasting en dat maakt 'overdreven veel' en 'overdreven snelle' hardware noodzakelijk.
Er zijn uiteraard verschillende wegen die naar Rome leiden. Onze structuur is voortgekomen uit een jarenlange uitbreiding van wat ooit een eenvoudige LAMP-stack was. Er zijn op allerlei plekken toevoegingen gedaan om beperkingen van MySQL, PHP of Apache op te vangen. Zelfs Linux is niet helemaal heilig gebleken toen we onze storage-server met OpenSolaris uitwerkten.

De toevoeging van allerlei losse services is in veel gevallen ook weerspiegeld in de inzet van een of meer losse servers. Geen van die kerntaken draait op virtuele machines, we vragen doorgaans voldoende van dergelijke servers om ook daadwerkelijk bare metal te kunnen verantwoorden. Daarbij moet wel gezegd worden dat we soms bundels taken op een server combineren, maar daarvoor is uiteraard geen virtualisatie nodig.
Webservers
Bij een bezoek aan Tweakers komt je browser uiteindelijk bij de loadbalancers terecht. Nadat een van de loadbalancers je netwerkverbinding heeft aangenomen, stuurt hij de gegevens door naar een van de webservers. In zekere zin zijn de webservers daarom de belangrijkste servers die we hebben. Zonder die krijg je niets, terwijl als een database onbereikbaar is, je in ieder geval nog een foutmelding kunt krijgen. We hebben daarom drie webservers in elk van beide datacentra, zes in totaal. Op deze manier kan zelfs bij uitval van een van de twee locaties nog steeds een webserver uitvallen zonder dat we daar noemenswaardig last van hebben. Aangezien het dataverkeer voor onze primaire locatie gratis is, sturen we 95% van het verkeer daarheen. Er gaat nog wel 5% naar de secundaire locatie, zodat alle caches gevuld blijven en we zeker weten dat die webservers ook gewoon goed werken.
Onze webservers zijn traditioneel behoorlijk zwaar uitgerust. In tegenstelling tot veel andere sites hebben we dus niet een heleboel lichte servertjes. Dat doen we omdat we niet alleen schaalbaarheid belangrijk vinden, maar ook willen dat iedere individuele request snel wordt afgehandeld. Bovendien beperken we zo het aantal servers in onze racks en de hoeveelheid beheer die daarmee gemoeid is. De hardware is voor alle zes servers dezelfde en bestaat momenteel uit:
Onderdeel | 6x webserver |
Server |
IBM x3550 M3 |
Cpu |
2x Intel X5675, 3.06GHz hexacore |
Geheugen |
24GB 1333MHz |
Disk |
1x 146GB 10K SAS |
We combineren overigens de taken van 'reverse proxy'-, web- en applicatieservers in deze machines. Dit hebben we gedaan om zowel de spof's te beperken als om nog wat snellere communicatie tussen de diverse dicht op elkaar zittende diensten te faciliteren.
Voor de schaling is dat uiteraard zowel een voor- als een nadeel. Enerzijds is het eenvoudig om er een webserver bij te zetten, zodat de capaciteit van ieder onderdeel toeneemt, maar anderzijds is het lastig om alleen een specifieke taak, bijvoorbeeld de proxyservers, meer capaciteit te geven. We houden dit soort dingen in de gaten en zijn er ook niet vies van om waar nodig taken naar losse servers te verhuizen.

Drie van de webservers gebroederlijk bij elkaar
Varnish
De meeste requests komen eerst binnen bij Varnish. Dit is een zeer krachtige en snelle reverse proxy server, die voorkomt dat onze Apaches zich moeten bezighouden met statische content. Denk bij statische content vooral aan plaatjes, JavaScript- en css-bestanden. We maken al een paar jaar gebruik van Varnish, maar met Phoenix hebben we besloten om alle requests via Varnish te laten lopen. De losse Lighttpd voor tweakimg.net is daarmee komen te vervallen. Er zat uiteindelijk geen snelheidsvoordeel in het gebruik van de losse Lighttpd-webserver voor statische content, terwijl het wel extra software was om te beheren.
Iedere Varnish heeft een eigen cache van 5GB, die alleen in ram-geheugen wordt bijgehouden. Ondanks die relatief beperkte cachegrootte, haalt Varnish bij ons een gemiddelde hitrate van ongeveer 97%. Dat betekent dat er van iedere honderd hits op de webserver slechts drie doorgestuurd worden naar Apache. Zo gek is dat natuurlijk niet, want op een pagina van Tweakers staan al gauw meer dan veertig statische elementen. Het zou zonde zijn om dat allemaal door Apache te laten verwerken, terwijl Varnish dat sneller en met veel minder belasting voor de hardware kan.
Apache en PHP
Tweakers is geschreven in PHP. Hoewel we daar elementen van hebben herschreven in Java, komt elke pageview van een bezoeker nog gewoon binnen op PHP. Daarbinnen wordt dan besloten waar de benodigde data vandaan gehaald moet worden. Dat kan onder andere uit MySQL, MongoDB, Memcached, het bestandssysteem en onze Java-back-end zijn. Voor de routing van requests, en om de onderliggende databeheercode en de weergave ervan te scheiden gebruiken we het Symfony Framework.
Doordat Varnish het gros van het webserver-werk op zich neemt, konden we Apache als applicatieserver blijven gebruiken. Er zijn allerlei snellere alternatieven, waaronder Nginx en Lighttpd, maar die zijn doorgaans lastiger te configureren met PHP en vaak minder krachtig of minder flexibel. Bovendien zijn ze vooral sneller voor de requests die bij ons direct door Varnish worden afgehandeld en ze zijn niet (noemenswaardig) sneller dan Varnish. Zodra je alleen nog maar requests doet waarbij PHP actief is, is er nog maar nauwelijks prestatiewinst met de alternatieve webservers te behalen. Het grootste deel van de tijd zit dan toch in zaken waarop de webserversoftware geen invloed heeft, zoals berekeningen in PHP, en queries naar MySQL en andere databronnen.
Engine
Eind 2012 schreven we uitgebreid over onze Java-back-end. Deze noemen we intern, bij gebrek aan een betere naam, simpelweg Engine. Samenvattend komt het erop neer dat MySQL en PHP samen niet goed overweg konden met de complexiteit van onze Pricewatch of de gecombineerde zoekresultaten die met Tweakers 7 geïntroduceerd werden. En omdat we de filtering van specificaties en dergelijke compleet en snel wilden houden, hebben we uiteindelijk alles herschreven in Java.
Om de communicatie met deze Engines zo snel mogelijk te houden en om ook hier geen spof te introduceren hebben we ervoor gekozen om op iedere webserver zo'n Engine te deployen. Ondanks snelle 1Gbit-switches en -nics is het nog altijd veel sneller om met localhost te communiceren dan over het netwerk te gaan.
De omgeving is opgezet als Java Servlet en we hebben daarvoor op iedere webserver een instantie van Tomcat 7 draaien. Deze heeft 8GB ram toegekend gekregen. Voor de liefhebbers: we gebruiken deze Garbage Collection-parameters:
Type | Instellingen |
Geheugen |
-Xms8G -Xmx8G -XX:+UseNUMA |
Permgen |
-XX:PermSize=256M -XX:MaxPermSize=256M |
Garbage Collection |
-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled |
Met de standaard-garbage-collector, de Parallel Garbage Collector, bleek dat er zo nu en dan een relatief lange application pause ontstond. Dat komt doordat Java de hele applicatie even stillegt om de laatste stappen van het opruimen van de ontstane memory garbage op te ruimen. Afhankelijk van je taak is dat natuurlijk niet per se een probleem; dat geheugen moet toch een keer opgeruimd worden.
Bij ons kwam het daardoor echter voor dat zo'n Engine meer dan twee seconden onbereikbaar was. Het opgeruimd houden van 8GB geheugen kost helaas aardig wat tijd, zelfs op onze snelle hardware. Doordat onze PHP-code automatisch naar een andere Engine verbindt als het te lang duurt, merk je daar als gebruiker verder weinig van, maar het was geen ideale situatie. Met de Concurrent Mark Sweep garbage collector is dat verleden tijd geworden. Deze ruilt een beetje opruimkwaliteit in voor een veel gunstiger pauzeregime. In technische termen: de maximale throughput is wat lager en het geheugen wordt iets minder goed opgeruimd, maar in ruil daarvoor zijn de latencypieken ook veel lager geworden.
ActiveMQ
We gebruiken ActiveMQ, via het Stomp-protocol, om bepaalde zaken vanuit PHP uitgesteld te kunnen verwerken. Het is bijvoorbeeld nergens voor nodig om een logfile direct bij te werken tijdens een pageview, dat mag best een paar minuten later gebeuren. Door deze log-updates in een Message Queue in ActiveMQ te plaatsen zorgen we ervoor dat deze asynchroon met de pageview opgeslagen worden.
Daardoor hoeft niet bij elke pageview een verbinding gemaakt te worden met onze database om vervolgens een insert te doen. We kunnen bovendien tijdens het verwerken meteen verschillende van deze inserts groeperen. Daarnaast kunnen we zo het aantal processen dat tegelijk de data in de database bijwerkt beperken.
Een laatste groot voordeel is dat we de load van onze database kunnen monitoren en het tempo van de verwerking daarop kunnen aanpassen. Als de load stijgt, kunnen we het uitlezen van de message queues vertragen of zelfs tijdelijk pauzeren. Hierdoor kunnen we de invloed van het opslaan van log-gegevens en daarmee de hele databaseload (een beetje) beperken.

Omdat ActiveMQ zo belangrijk is bij elke pageview, willen we daarmee natuurlijk geen spof introduceren. Vandaar dat we ervoor gekozen hebben om met ActiveMQ een network of brokers op te zetten. In ons geval betekent dit dat iedere webserver een eigen ActiveMQ draait en dat deze de inkomende berichten doorstuurt naar een van twee centrale brokers. De consumers maken verbinding met die centrale instanties om de berichten uit te lezen en te verwerken.
De PHP-code op de webservers probeert eerst de berichten naar de lokale instantie te verzenden, die is tenslotte het snelst te bereiken. Mocht dat niet lukken, dan wordt een van de centrale instanties geprobeerd. Door deze opstelling kunnen de berichten op de lokale server gebufferd worden voordat ze naar de centrale message queue worden verzonden. Al met al moet dat ertoe leiden dat we vrij eenvoudig de verwerking van berichten kunnen pauzeren, vertragen of naar een andere server verhuizen, zonder dat de webservers, en dus de bezoekers, daar last van hebben.
Video
We zijn alweer enkele jaren geleden begonnen met het plaatsen van video's op onze eigen servers. Ondertussen is er zelfs een heuse videoredactie die dagelijks nieuwe video's opneemt op locatie en in onze eigen videostudio. Dat levert uiteraard allerlei technische uitdagingen op. Video's zijn groot, het afspelen ervan over het internet vereist specifieke instellingen bij het transcoderen en het transcoderen naar verschillende versies duurt vrij lang. Dat laatste geldt zeker voor de 1080p- en 720p-versies.
Om te voorkomen dat de videoredactie continu bezig is met het saaie produceren van allerlei losse versies van dezelfde video's wilden we daar veel aan automatiseren. Daar bestaan onder andere allerlei cloudoplossingen voor, externe partijen die het hele proces van video-upload, transcoderen en uitserveren op zich kunnen nemen. Doordat onze volledige colocatie in het datacentrum door True wordt gesponsord bevinden wij ons in een vrij unieke situatie. De kostenberekeningen die op het internet rondzwerven, gaan voor ons niet op. Onze kosten voor stroom, het rack en de bandbreedte zijn immers veel lager dan gebruikelijk, in de meeste gevallen zelfs nihil.
Uiteindelijk kwamen we terecht bij StreamOne. Dit bedrijf biedt een videoserverplatform aan waarmee we zelf servers kunnen plaatsen, die vervolgens voorzien worden van software om video's te serveren, te transcoderen en/of te beheren. In de praktijk lijkt dit platform sterk op ons eigen webserverplatform, maar het bij elkaar zoeken van de juiste software, het bijhouden van videobibliotheken en het uitvogelen van de juiste transcodingparameters is ons hiermee uit handen genomen. Ook kunnen we hiermee live-streams verzorgen, bijvoorbeeld van evenementen bij ons op kantoor.
De hardware voor ons videoplatform bestaat momenteel uit de volgende servers. Voor de specificaties van de VM-host kun je verderop in deze review terecht.
Onderdeel | 2x Videostreaming | 2x Videotranscoding | 2x Videotranscoding/Controller |
Server |
Dell R210 |
Sun X2270 |
VM |
CPU |
Core i3 530 2,93GHz |
2x Xeon X5570 2,93GHz |
6 cores |
RAM |
8GB DDR3-1066 |
12GB DDR3-1333 |
8GB |
Storage |
1x 160GB SATA |
1x 250GB SATA |
gedeeld met host |
Videostreaming
De videostreaming vindt plaats vanaf twee, voor ons doen, eenvoudige webservers. Deze zijn vooral ingericht om domweg meer dan 2Gbit aan netwerkbandbreedte met hun streamingwerk vol te kunnen krijgen. Daarvoor is bij dit soort eenvoudige taken met moderne hardware overigens niet heel veel nodig. Vandaar dat het eenvoudige webservertjes zijn gebleven.
Momenteel hebben we alleen videowebservers in onze primaire locatie. De bandbreedte kost ons daar tenslotte niets. Omdat we toch ook video's willen kunnen blijven serveren als onze primaire locatie uitvalt, komen daar binnenkort nog twee webservertjes bij. Overigens zijn de huidige twee ondertussen afgeschreven, dus die worden dan ook tegelijk vervangen.
Videotranscoding
De videotranscoding vond in eerste instantie alleen op onze VM-servers plaats. Op beide VM-servers hebben we een 'zware' VM geplaatst voor het transcoderen van video's en voor het bijhouden van de meta-informatie ervan. In de praktijk bleek dat de videoredactie vaak verschillende video's vlak achter elkaar uploadt en dat dan vooral bij beurzen lange wachttijden ontstaan voordat een video eindelijk klaar is voor gebruik.

Van boven naar beneden: videowebserver Aedon, mailserver Aphrodite en 'nieuwe' videotranscoders Ares en Abaris
Daarom hebben we twee van onze oude webservers teruggeplaatst, die omgebouwd zullen worden tot videotranscodingserver. Deze bieden wat krachtigere cpu-cores en geven daarnaast (beter) directe toegang tot alle speciale cpu-features, zoals SSE3 en SSE4, en het ram-geheugen. Bovendien hoeven we met deze servers niet bang te zijn dat andere taken (op andere VM's) er last van krijgen en kunnen we ze daarom tot de volle 100% belasten. De twee transcodingservers op de VM-servers blijven voorlopig ook gewoon meedraaien, waardoor we de capaciteit ruimschoots verdubbelen.
De VM's zijn behalve voor transcoding ook verantwoordelijk voor de opslag van de video's en het bijhouden van de metadata. De metadata wordt in een MySQL-database bijgehouden. Aangezien die verder relatief licht belast wordt, kon die gewoon op een van de twee VM's meedraaien.
Voor de opslag van de video's wordt gebruikgemaakt van de centrale nas-opslag. Het belangrijkste dat de VM hierbij doet is het coördineren van de bestandsopslag en het doorgeven van bestanden aan de videowebservers.
Databases en filestorage
Tweakers begon jaren geleden met enkel een normale rdbms en PHP-code die daarin alle data opsloeg en weer uithaalde. Hoewel Femme bij de allereerste webserver per ongeluk voor MiniSQL (afgekort mSQL) koos, werd dat kort daarna MySQL en na al die jaren wordt het grootste deel van de gegevens van Tweakers nog altijd in MySQL opgeslagen. We zijn alleen alternatieven gaan gebruiken als daar een goede reden voor was. Momenteel hebben we de volgende servers voor de opslag van gegevens:
Onderdeel | MySQL-master | MySQL-slave | 2x 'NoSQL' | 2x Search | Nas |
OS |
Linux |
Linux |
Linux |
Linux |
OpenSolaris |
Server |
IBM x3550 M4 |
Dell R710 |
IBM x3550 M3 |
IBM x3550 M3 |
Sun x4270 |
CPU |
2x E5-2643 3,3GHz |
2x X5660 2,80GHz |
2x E5645 2,4GHz |
2x E5645 2,4GHz |
2x E5520 2,26GHz |
RAM |
256GB DDR3-1600 |
48GB DDR3-1066 |
48GB DDR3-1333 |
48GB DDR3-1333 |
24GB DDR3-1066 |
Controller |
ServeRaid M5110 |
Perc H700 |
ServeRaid M5015 |
ServeRaid M5015 |
JBOD icm ZFS |
OS-disks |
2x 250GB SATA |
2x 300GB 10k SAS |
Geen losse |
2x 146GB 10k SAS |
2x 146GB 10k SAS |
Data-disks |
6x 256GB SSD |
6x 50GB SSD |
2x 900GB 10k SAS |
2x 900GB 10k SAS |
10x 500GB SATA |
SSD-accelerator |
Geen |
Geen |
1x 50GB |
2x 50GB |
2x 80GB (read), 2x 32GB (write)
|
MySQL
MySQL heeft een turbulente geschiedenis en stond bekend als een database die veel van de SQL-standaard afweek, niet goed met complexe queries overweg kon en vrij instabiel was. Het grootste voordeel was destijds dat het gratis te gebruiken was en dat het eenvoudig op te zetten was in combinatie met PHP. Daarnaast was het snel met heel simpele queries, het type dat je bij websites veel gebruikt.
Aangezien MySQL in de loop der jaren steeds stabieler is geworden en het tegenwoordig ook redelijk complexe queries aankan, hebben we niet de moeite genomen om over te stappen naar alternatieven, zoals PostgreSQL. Het overstappen zou namelijk veel werk geweest zijn, onder meer omdat een groot deel van de SQL-statements herschreven zou moeten worden om ze te vertalen van MySQL's eigen SQL-dialect in het dialect van de nieuwe database. Al met al wogen de voordelen niet op tegen de nadelen van onder andere veel werk en uren downtime gedurende de migratie.
We slaan het gros van de data op in InnoDB-tabellen, hoewel we nog lang niet altijd alle beschikbare mogelijkheden voor veilige data-opslag gebruiken. Foreign keys werken in MySQL bijvoorbeeld nog steeds een beetje raar.
Momenteel gebruiken we voor MySQL master/slave-replicatie om gegevens veilig te stellen in geval van een calamiteit. We onderzoeken op dit moment of we dat naar multimasterreplicatie kunnen ombouwen.

Telecity-databases: 'NoSQL'-database Narwhal, Search-server Squid en MySQL-slave Apollo. Onderaan nog backup/nfs-server Athena.
'NoSQL'
Databases hebben doorgaans wat moeite met data die veel wordt aangepast en tegelijk ook veel wordt gelezen. Daarnaast laat SQL weinig flexibiliteit in opslag toe. MySQL is daar geen uitzondering op.
We liepen met onze sessies tegen deze beide beperkingen aan. In de sessies slaan we onder andere een aantal voorkeuren, de tijd van je laatste bezoek en nog een aantal gegevens op. Hierdoor verandert jouw sessie bij elk bezoek aan Tweakers. Bovendien hebben we miljoenen van deze sessie-records in de database staan; die willen we dan ook opgeruimd houden. Periodiek lopen we de verlopen sessies langs om ze uit de database te verwijderen.
Dit samenspel van veel reads, continu lichte updates en af en toe grote deletes bleek echter een behoorlijke aanslag op MySQL te plegen. Daarnaast wilden we de voorkeuren flexibeler kunnen opslaan. Als jij een bepaalde instelling niet hebt gekozen, dan is het zonde als die toch ruimte in de database inneemt en daarnaast willen we juist ook bij nieuwe voorkeuren met een query kunnen nagaan of en hoe vaak ze worden gebruikt. Bij een rdbms betekent het toevoegen van een instelling dat je een kolom aan een tabel moet toevoegen en dat betekent bij MySQL dat de tabel waarin de data is opgeslagen, op de achtergrond helemaal herschreven wordt. Dat levert op zijn beurt enige downtime op bij zo'n grote tabel. Om dat te voorkomen sloegen we de voorkeuren al zodanig op dat MySQL ze domweg als bytes zag, zonder per voorkeur een losse query te kunnen doen.
Al met al leek MongoDB ons een betere keuze voor de sessieopslag. In eerste instantie werd deze samen met MySQL op onze databaseservers gezet, later hebben we het verhuisd naar twee eigen servers. Ook MongoDB draait effectief in master/slave-replicatie, hoewel MongoDB het zelf een 'replica set' noemt. Naast de twee servers draait een van onze managementservers nog een arbiter-instantie, zodat er onder normale omstandigheden drie MongoDB-servers zijn en er altijd een meerderheid is om te bepalen welke de master moet zijn.
Aangezien ook MongoDB nog enige moeite heeft met onze sessies, beraden we ons nog op de vraag of we bij MongoDB blijven of toch nog op zoek gaan naar een andere oplossing.
De bijbehorende NoSQL-servers zijn vooral voorzien van veel geheugen, MongoDB maakt daar gretig gebruik van. Daarnaast kan de raid-controller die we daarin hebben geplaatst gebruikmaken van de 50GB-ssd om zowel lees- als schrijfwerkzaamheden te versnellen.
Naast MongoDB draaien ook Memcached en de centrale ActiveMQ-omgevingen op deze servers.
Memcached
Om te voorkomen dat we voor elk wissewasje een query op MySQL moeten uitvoeren gebruiken we al jaren Memcached. Dit is een centrale geheugen-cache die door de webservers aangesproken kan worden om snel aan gegevens te komen. Memcached wordt vaak ingezet om kleine plukjes informatie te bewaren, die relatief duur zijn om uit de database te halen. Het voordeel van een centrale cache is dat als webserver A iets opslaat, het ook toegankelijk is voor webserver B. Bovendien zorgt dit ervoor dat als webserver C het weer overschrijft, ook A en B de nieuwste versie van de data hebben.
Een goed voorbeeld van waar wij het inzetten, is de reaction count. Bij een lijstje van nieuwsberichten zie je bij elk artikel staan hoeveel reacties er zijn, maar om die te tellen moet je eigenlijk in de reactietabel een vrij 'dure' query uitvoeren. Om te voorkomen dat dit steeds opnieuw gedaan moet worden, wordt de uitkomst in Memcached bewaard. Bij het tonen van een lijst nieuwsberichten worden die cijfers met één multiget opgehaald en kost het veel minder rekentijd dan wanneer we het uit MySQL moeten halen.
Uiteraard slaan we er nog veel meer in op, maar al met al gebruiken we van de 2GB aan cache-grootte slechts zo'n 800MB aan data. Dat lijkt weinig, maar het gaat daarbij alsnog om ruim vijf miljoen records. Omdat we slechts 2GB aan cache voor Memcached hebben en zelfs dat nog ruim is, draait Memcached samen met MongoDB op de NoSQL-servers.
Memcached biedt geen vorm van replicatie. Er wordt van uitgegaan dat je zo veel gegevens in Memcached wil opslaan dat je bij verschillende servers liever alle informatie verspreidt dan dat je het meer dan eens wil opslaan. Aangezien dat voor onze kleine hoeveelheid data niet geldt, hebben we er zelf een replicatielaag omheen gebouwd, zodat we altijd een van twee memcached-servers kunnen aanspreken en data waar nodig in beide wordt bijgewerkt.
Search
Databases zijn over het algemeen niet erg geschikt om te gebruiken als full text search engine. In de loop der jaren zijn er wel wat trucjes voor ontstaan binnen MySQL, maar de ervaring leert dat een specialistische omgeving in de praktijk beter werkt. Bovendien stelt dat ons in staat om ook daarvoor weer dedicated hardware in te zetten.
Voor het forum kwamen we destijds uit op Xapian en diens client Omega. Hoewel deze zoekmachine ons in de loop der jaren goed is bevallen, zijn er al een aantal jaren af en toe klachten over de manier waarop de zoekresultaten tot stand komen. Omdat we in de tussentijd goede ervaringen hadden met onze eigen Java-back-end, is die ondertussen uitgebreid met een Lucene-zoekmachine voor het forum. Op het moment van schrijven is deze in bèta en te testen.
Daarmee zijn (bijna) al onze zoekmachines ondertussen uitgewerkt in Lucene. Aangezien het opbouwen van de forumzoekdatabase enige uren kost, is het niet handig dit enkel in ram-geheugen bij te houden. Dit doen we wel bij alle andere zoekmachines; die kosten samen slechts een paar minuten om op te bouwen.
We laten de zoekdatabase voor het forum daarom door Lucene op disk opslaan en alleen onze dedicated search-servers maken daarom een forumzoekmachine aan. De rest van de engines (zie webservers) draait weliswaar dezelfde Java-code, maar is geconfigureerd om deze database over te slaan. Overigens draaien deze Tomcats met 16GB ram, zodat Lucene wat meer ruimte heeft om dingen in het ram te houden.
De twee search-servers zijn tegelijk aangeschaft met de beide NoSQL-servers. Het belangrijkste verschil zit 'm in de I/O-configuratie. Bij de search-servers zijn de twee 900GB-disks dedicated als datadisk. Ze hoeven dus niet ook nog eens het lees- en schrijfwerk voor het besturingssysteem uit te voeren. Daarnaast beschikt de raid-controller in deze machines over twee 50GB-ssd's om nog wat meer werk te kunnen cachen.
Filestorage
Onze fileserver is momenteel de oudste server die nog in een kerntaak aan het werk is. Deze hebben we destijds met OpenSolaris en ZFS opgezet. Hoewel dit goed bevalt, is helaas de support voor OpenSolaris vrij kort na de plaatsing stopgezet en kunnen we nu dus niet zomaar op dezelfde weg doorgaan.

Momenteel voorziet deze server ons serverpark van centrale opslag van bestanden. De afbeeldingen die onze redactie en gebruikers uploaden, de video's die we hosten: het staat allemaal op deze machine. Ook speelt deze server een belangrijke rol in het verdelen van de JavaScript, CSS- en PHP-bestanden over de verschillende servers. Het centrale bestandssysteem is via NFSv3 beschikbaar gemaakt.
Overigens maken de webservers een kopie van de JavaScript, CSS- en PHP-bestanden om onnodig netwerkverkeer te voorkomen. Die kopie maken ze met een rsync-daemon op de nfs-server. Ook van populaire video's en afbeeldingen worden kopieën in de webservers bijgehouden. Bij de afbeeldingen gebeurt dat in de ram-caches van Varnish. De videowebservers kopiëren de populaire video's naar hun lokale harde schijf.
We zijn momenteel op zoek naar goede vervanging voor deze webserver. ZFS bevalt goed, maar we hebben onze twijfels over de stabiliteit van de Linux-implementatie. En onze belangrijkste ervaring met OpenSolaris is dat het een aanzienlijke aanslag pleegt op de beheercapaciteit als er een server met een vreemd besturingssysteem tussen je machines zit. Kortom, we willen niet zomaar (weer) een Solaris- of FreeBSD-server opzetten.
Daarnaast hebben NFS (en ZFS) als nadeel dat het erg lastig is om er een multimastercluster mee op te bouwen. We hebben daarom ook nog wat onderzoekswerk te doen naar alternatieven als Ceph en GlusterFS. De voorlopige conclusie is overigens dat er nog te veel haken en ogen aan dergelijke clustersystemen zitten en we met onze omvang toch beter af zijn met een 'eenvoudige' nas met ZFS.
Overige servers
Hoewel we al zeventien servers hebben genoemd in dit verhaal, zijn we er nog niet helemaal. We hebben ook nog allerlei servers en VM's in gebruik voor diverse secundaire taken. Denk daarbij aan het versturen en ontvangen van e-mail, het bijhouden van backups, het uitvoeren van monitoring en het aanbieden van diverse ontwikkelplatforms.
Onderdeel | 2x VM | Mail | 2x Management | Development | Backups |
OS |
Linux+KVM |
Linux |
Linux |
Linux+KVM |
Nexenta Core |
Server |
Dell R410 |
Dell R610 |
Dell R310 |
IBM x3550 M3 |
Dell R510 |
CPU |
2x Xeon E5630 2,53GHz |
2x Xeon X5570 2,93GHz |
Xeon X3440 2,53GHz |
2x Xeon E5645 2,4GHz |
2x Xeon E5620 2,4GHz |
RAM |
64GB DDR3-1066 |
24GB DDR3-1333 |
4GB DDR3-1333 |
144GB DDR3-1333 |
24GB DDR3-1333 |
Controller |
|
PERC 6 |
SAS 6iR |
ServeRAID M5015 |
PERC H700 |
OS-disks |
1x 250GB |
2x 300GB 10k SAS |
2x 160GB SATA |
Geen losse |
2x 146GB 10k SAS |
Data-disks |
MD3200i iSCSI |
4x 50GB SSD |
|
6x 900GB 10k SAS |
12x 2TB SATA |
SSD-accelerator |
|
|
|
2x 50GB |
|
VM's + iSCSI
Voor veel servertaken gebruiken we dedicated hardware. Toch zijn er nog diverse taken waarvoor we een gescheiden besturingssysteem wilden, zonder daar meteen ook een dedicated machine op te willen zetten. We hebben onder andere twee losse VM's voor de spamfiltering van de inkomende e-mail. Verder draaien het verzamelen van accesslogs, monitoring door zabbix, onze dns-servers en de irc-server op eigen virtuele servers. Daarnaast zetten we zo nu en dan nog losse VM's op voor tijdelijke taken.
Mail
In eerste instantie was ook de centrale mailserver gehost op de VM-servers, maar vooral het versturen van de nieuwsbrief naar duizenden Tweakers leverde grote pieken in de belasting op, wat leidde tot onderbrekingen bij andere gebruikers van de mailserver. Aangezien we onze oude searchserver nog in het rack hadden hangen, hebben we die omgebouwd tot mailserver. De snellere hardware en snellere toegang tot de bestanden van de mailopslag hebben de problemen verholpen.
Servermanagement
Om een serverpark van deze omvang goed te beheren, moet je uiteraard ook allerlei interne diensten aanbieden. Denk aan (caching) dns-servers, een centrale tijdserver, dhcp en ldap. Sinds Phoenix worden onze servers bovendien beheerd met Puppet om zo eenvoudig nieuwe servers te kunnen installeren en snel wijzigingen in de configuraties te kunnen uitrollen over verschillende servers. Al deze taken zijn verzameld binnen onze managementservers.

Managementserver Maia helemaal alleen onderin…
Development
Development nemen we serieus. Vandaar dat we al jaren 'afgedankte' hardware inzetten voor de diverse test- en ontwikkelservers. Tijdens het ontwikkelen van Tweakers 7 hebben we dat zelfs nog wat verder doorgetrokken. We hebben daarbij een alfa-, bèta- en gamma-opstelling gemaakt. Ieder van die drie omgevingen bestaat uit een webserver en een databaseserver.
Omdat het uiteraard zonde is om voor zulke weinig bezochte sites zes fysieke servers te plaatsen, hebben we die verenigd in een krachtige VM-host met veel geheugen en snelle I/O. Bovendien kunnen we zo eenvoudigweg nog meer developmentmachines opzetten. Gedurende de ontwikkeling van Tweakers 7 hadden we bijvoorbeeld ook een 'Tweakers 6.9'-testserver. Onze SVN-omgeving wordt eveneens op deze VM-server gehost.
Deze testservers zijn tegelijk een mooie manier om te testen of onze databasebackups goed zijn gegaan. Althans, we zien in ieder geval dat ze geïmporteerd worden en overduidelijke fouten zullen er ook uitspringen. Als er echter ergens een obscure tabel verkeerd is ingeladen, zullen we dat natuurlijk niet zo snel zien.
Behalve de bovenstaande server hebben we in onze kantooromgeving ook nog wat servers voor het testen en ontwikkelen van onze code.
Backup
Er zijn een aantal zaken waarvan we actief backups bijhouden. De belangrijkste zijn de centrale databases, filestorage en onze SVN-omgeving. Doordat Puppet zijn gegevens in SVN opslaat, hebben we ook van de belangrijkste serverconfiguraties een backup. Voor de filesystem-backups maken we gebruik van de snapshot-functie van ZFS. De backups worden met ZFS Send & Receive overgestuurd van de NFS-server naar de backupserver. Het grootste voordeel hiervan is dat we ook automatisch een vorm van 'deduplicatie' in de backups hebben; bestanden die niet veranderen, staan maar één keer op de server.
De MySQL-databases zijn steeds volledige dumps, waarvan we er een behoorlijk aantal bewaren. Aangezien dit per keer 'slechts' een paar gigabyte is en we oude backups weggooien, gaat de 24TB aan bruto-opslag uiteindelijk nog even mee. Althans, dat hopen we 
Naast deze onsite-backupserver hebben we ook nog een server op ons kantoor die periodiek een kopie van de recentste backups krijgt toegestuurd.
Toekomstige uitbreidingen
We proberen onze servers vlot te vervangen. Dat betekent niet dat ze altijd precies drie jaar na aanschaf worden ingeruild, maar dat is wel waar we ons op richten. Een enkele keer komt het beter uit om een server wat eerder te vervangen, zodat we bijvoorbeeld een nieuwe aanpak voor een bepaalde service kunnen uitwerken.
Ook dit jaar gaan we weer flink wat vervangen. Het belangrijkste is de centrale storage. Het liefst zouden we een omgeving opzetten met multi-master-replicatie, zodat er naar een willekeurige fileserver in een van de beide locaties geschreven kan worden en de clients transparant omgezet kunnen worden bij problemen.
In de praktijk blijkt dat dit soort systemen erg zeldzaam is. Zelfs ruim boven ons budget is het nog niet gebruikelijk dat fileservers elkaar via een tcp/ip-netwerk actueel kunnen houden. Het is meestal één kant op, in een variant op een master-slave-opstelling. Omdat het systeem voor ons niet alleen storage moet bieden, maar ook beheersbaar en flexibel moet zijn, gaan we hier waarschijnlijk weer simpelweg aan de slag met ZFS. Op welk besturingssysteem of welke appliance dat dan komt, weten we nog niet. Het liefst wordt dat natuurlijk Linux, maar helaas is ZFS op Linux geen officieel ondersteund bestandssysteem. Dat maakt de combinatie daardoor automatisch een minder goed recept voor stabiliteit en continuïteit.
Naast de storage staan er nog diverse servers op de agenda om vervangen te worden. Daaronder bevinden zich de 'slave' MySQL-server, de VM-hosts en de videowebservers. Aangezien die in hun huidige vorm vrij goed werken, zullen dat domweg varianten op dezelfde soort server zijn. Alleen dan uiteraard drie jaar nieuwer.
Op het gebied van software willen we ook nog verder met nieuwe versies en zullen we diverse aspecten tunen. Zo wordt het https-verkeer nu direct naar Apache verzonden. Dat is zonde, want daardoor wordt Varnish overgeslagen. Aangezien onze loadbalancers ook zelf https kunnen 'terminaten', gaan we onderzoeken hoe we dat het efficiëntst kunnen inzetten. Helaas is dat typisch een wijziging die simpel lijkt, maar in de praktijk allerlei haken en ogen met zich meebrengt. Op het moment van schrijven wordt dit daarom alleen nog voor tweakimg.net gedaan.
Zoals eerder gemeld willen we onderzoeken waarom MongoDB relatief slecht met de hoeveelheid queries en updates overweg kan. Wellicht is een nieuwere versie beter of stappen we over op een van de alternatieven. Vooral Redis lijkt een goede kandidaat. Verder moeten we nog hard aan de slag om al onze oude code na te pluizen op compatibiliteit met PHP 5.4 en 5.5.