Database Limiet

Mijn applicatie heeft meer dan 15 databases nodig, hoe verder?

Het Byte platform is ontworpen voor accounts (domeinen) met maximaal 15 databases. Waarom? Iedere account heeft een unieke database-servernaam. Dit maakt het mogelijk om databases van individuele accounts te wisselen tussen databaseclusters, bijvoorbeeld wanneer een site plotseling erg druk wordt en een zwaardere databaseserver nodig heeft. Omdat de servernaam uniek is per domein, hoeven we in zo'n geval alleen de databases te kopiëren en de servernaam naar het nieuwe cluster te laten verwijzen. Bij weinig kleine databases kan dit verplaatsen binnen een paar seconden en merken sitebezoekers niets van de migratie achter de schermen. Echter, hoe groter en hoe meer databases, hoe langer het verplaatsen duurt en hoe langer de bijbehorende site "blijft hangen". Bij 100 databases onder één account is het vrijwel onmogelijk om zonder significante downtime te wisselen tussen databaseclusters.


Nu komen er regelmatig ontwikkelaars bij ons die een applicatie hebben gemaakt voor zogenaamde "virtuele sub-sites". Dat wil zeggen dat een enkele applicatie meerdere sites op het scherm tovert, bijvoorbeeld op basis van de domeinnaam waarmee de applicatie werd aangeroepen. Mogelijk heeft iedere subsite eigen data, die uit een eigen database moet komen. De applicatiecode staat op één account en er wordt vanaf verschillende sites naar doorverwezen. Men vraagt ons: hoe kunnen we het beheer centraal houden, maar voorkomen we dat we tegen de databaselimiet aan lopen?


De essentie van de oplossing is om voor iedere subsite een apart hostingaccount met database aan te vragen. Dit heeft enkele nadelen:

  • Meer administratie, want aparte database login gegevens per subsite
  • Iets duurder, want een klein bedrag aan hostingkosten per subsite


Deze opstelling heeft echter ook grote voordelen:

  • Gescheiden databaserechten: indien de database van één subsite gehacked wordt, is de schade beperkt en de impact geïsoleerd, want andere subsites zijn beschermd met een eigen login.
  • Betere controle en hogere granulariteit: indien er iets misgaat, kan eenvoudig de backup van 1 subsite worden teruggeplaatst, in plaats van alles of niets.
  • Maar het allerbelangrijkste is natuurlijk dat het gebruik van aparte databases (en logins) per subsite het mogelijk maakt om boven de 15 subsites te schalen. Bovendien draagt het gebruik van aparte databases (en logins) sowieso bij aan de generieke schaalbaarheid van de applicatie. Zo wordt het bijvoorbeeld erg eenvoudig om een uitzonderlijk drukke subsite te verplaatsen naar een eigen databasecluster. Als de nood aan de man komt, is dit een werkje van een paar minuten.


De eenvoudigste implementatie van een dergelijke architectuur, is het plaatsen van aparte configuratiebestanden op de hoofdsite. Bijvoorbeeld een bestand "subsite7.domein.nl.conf" met daarin de database- en andere gegevens van deze site. Indien men surft naar subsite7.domein.nl, kan de applicatie onder water het volgende bestand includen (uiteraard even checken op syntax en lettercase van HTTP_HOST):

$_SERVER['HTTP_HOST'].conf

Niet noodzakelijk maar nuttig...

Een volgende, niet noodzakelijke maar mogelijk nuttige stap is om ook de applicatiecode te decentraliseren. Het beheren van tig verschillende applicatieinstanties klinkt u wellicht weinig aanlokkelijk in de oren. Het goede nieuws is: indien u de juiste scripts gebruikt, heeft u aan een dergelijke setup geen extra werk en alleen de extra voordelen van een gedecentraliseerde applicatie:

  • U hoeft niet al uw subsites in één keer te upgraden naar de laatste versie van uw applicatie.
  • De applicatie draait per subsite onder eigen gebruikersrechten, dus het hacken van één subsite heeft geen invloed op de andere subsites.


De sleutel van gedecentraliseerde applicaties is automatisering van deployment. Het updaten van uw applicatiecode moet automatisch gebeuren en u zou nooit met de hand hoeven bij te sturen. Een mogelijke implementatie, die met succes op het Byte platform in productie draait, is gebaseerd op enkele simpele shell scripts en PKI authenticatie.


Bestempel één account tot hoofdaccount. Hier upload u steeds de nieuwste versie van uw applicatie.


Zorg dat uw hoofdaccount en alle subsites SSH toegang hebben via onze SSH server (via het Service Panel kunt u dit instellen).

Log in op de SSH server (zie Alles Over Shell) en maak een PKI pair aan (druk paar keer op enter):

ssh-keygen -t dsa

U ziet dan:

Generating public/private dsa key pair.
Enter file in which to save the key (/home/users/abcdeftp/.ssh/id_dsa):
Created directory '/home/users/abcdeftp/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/users/abcdeftp/.ssh/id_dsa.
Your public key has been saved in /home/users/abcdeftp/.ssh/id_dsa.pub.
The key fingerprint is:
d5:b4:0b:e9:92:9e:f9:f3:42:26:f0:8c:05:08:39:ba mike@corona

Doe vervolgens op uw hoofdaccount:

cd ~/.ssh
mkdir to-copy
chmod 700 to-copy
cp id_dsa.pub to-copy/authorized_keys
chmod 600 to-copy/authorized_keys

Per subsite-account dient u deze eenmalig te initialiseren vanaf uw hoofdaccount, met het volgende commando:

rsync -va ~/.ssh/to-copy/ subsite1.nl@localhost:.ssh/

U kunt dit commando ook voor het gemak in een scriptje zetten, bijvoorbeeld "initialiseer-subsite":

#!/bin/bash
test $# -ne 1 && \
echo "Usage: $0 <domeinnaam>" && exit 65
rsync -va ~/.ssh/to-copy/ $1@localhost:.ssh/

U kunt nu "initialiseer-subsite subsite1.domein.nl" aanroepen om de site te initialiseren.


Vervolgens heeft u een klein scriptje nodig om alle namen van subsites te genereren. Deze kunnen bijvoorbeeld uit een database komen. We noemen het script "alle-subsites" en dit bestaat bijvoorbeeld uit:

echo "select domain from accounts where type='subsite' and enddate > NOW()" |\
 mysql -u u001234_root -pGEHEIM -h dbint001234 \
 db001234_administratie | egrep -v '^domain$' | sort

Dit zou een lijst moeten geven met alle accounts die u bij ons heeft.

Nu komt het mooiste script: de synchronisatie van uw applicatie. We noemen dit script "synchroniseer":

set -e
for i in `alle-subsites`;
do
        echo Bezig met synchroniseren $i...
        rsync -a --del ~/bronbestanden/ $i@localhost:core_files/
done
echo "Mooi, iedereen is weer up to date."
echo "Je hebt een koffie verdiend!"

Er wordt hier geïtereerd over alle subsites (gegenereerd door het script "alle-subsites"). Voor ieder account wordt de map "bronbestanden" (in de hoofdmap van uw hoofdaccount) gesynchroniseerd naar de map "core_files" in de hoofdmap van iedere subsite. Let op: bestanden die in de map core_files op een subsite staan, maar niet in de map "bronbestanden" op het hoofdaccount, worden verwijderd!


Een eerste synchronisatie (bijvoorbeeld bij een nieuwe account) zal mogelijk even duren. Maar bij volgende updates is het een kwestie van seconden, omdat alleen de gewijzigde bestanden worden gesynchroniseerd.

Nog niemand heeft een waardering kenbaar gemaakt voor dit artikel
 You need to enable JavaScript to vote

We proberen de kwaliteit van onze kennisbank voortdurend te verbeteren.
Geef de informatie op deze pagina een waardering met de slider hierboven.