Je laatste PHP / MySQL-website is eindelijk online. En het is geweldig. Maar het is niet zo snel als u wilt, vanwege de vele SQL-query's die worden uitgevoerd telkens wanneer een pagina wordt gegenereerd. En daarbovenop heb je het gevoel dat het niet goed zal schalen onder zware belasting. En je hebt waarschijnlijk gelijk.
In deze zelfstudie zullen we zien hoe u de reactietijd van uw website aanzienlijk kunt verbeteren en hoe deze schaal kan worden aangepast om veel gelijktijdige bezoekers te verwerken, door een cachetaag tussen uw code en uw database te implementeren. Het goede nieuws is dat het vrij eenvoudig is en binnen een paar minuten kan worden gedaan!
Memcached is een high-performance in-memory data caching-systeem.
Moderne websites en webtoepassingen gebruiken veel gegevens, en het is niet ongebruikelijk om maar liefst 20 of zelfs 30 SQL-query's in een generatie van één pagina te tellen. Vermenigvuldig dit bedrag met een groot aantal bezoekers en u krijgt vaak een overbelaste database en pagina's die seconden in beslag nemen en naar de klant worden verzonden.
De tool die we vandaag gaan gebruiken om de prestaties te verbeteren, heet Memcached. Het is een high-performance in-memory data caching-systeem. Of om het op een andere manier te zeggen, een zeer snelle applicatie die op uw server draait en een fractie van het beschikbare geheugen gebruikt om een associatieve array van gegevens op te slaan. U kunt Memcached vragen om twee dingen te doen:
V
met de sleutel K
V
opgeslagen met de sleutel K
Dit ziet er minimalistisch uit, maar dankzij deze twee functies kun je veel doen, zoals we binnenkort zullen zien. In feite kan Memcached nog een paar dingen doen, maar ze zijn allemaal gebonden aan het opslaan of ophalen van gegevens.
Memcached installeren op moderne Linux-distributies is vrij eenvoudig:
sudo apt-get install memcached
sudo emerge install memcached
sudo yum install memcached
Na de installatie wordt Memcached automatisch gestart telkens wanneer uw server opstart. U kunt de hoeveelheid geheugen die is gereserveerd voor Memcached, samen met andere opties, instellen in het configuratiebestand (/etc/memcached.conf
). 64 MB is standaard toegewezen. Het configuratiebestand bevat ook het IP-adres en de poort waaraan Memcached is gebonden. Standaard waarden (127.0.0.1
en 11211
) zijn prima voor een standaard setup.
We willen gegevens opslaan en ophalen uit uw PHP-scripts. Dit betekent dat we een manier nodig hebben om verbinding te maken met Memcached vanuit PHP. Daarvoor gaan we de "Memcache" -extensie voor PHP installeren. Omdat het een PECL-extensie is, is het zeer eenvoudig om met de "pecl" te installeren door het volgende commando te typen:
sudo pecl installeer memcache
Er zijn twee PHP-uitbreidingen gerelateerd aan Memcache: "Memcache" en "Memcached" (let op de "d" in de tweede). Beide lijken erg op elkaar, maar de eerste heeft een kleinere voetafdruk. In deze zelfstudie gebruiken we de lichtere Memcache. Na de installatie moet deze extensie worden ingeschakeld en moeten de Memcache-gerelateerde functies nu beschikbaar zijn voor uw PHP-scripts.
Ons werk hier is gebaseerd op de volgende veronderstellingen:
We willen onze gegevens ook opslaan op een manier die ons in staat stelt deze efficiënt op te halen.
Over het algemeen willen we onze gegevens opslaan in een persistente omgeving (bijvoorbeeld onze MySQL-database). Maar we willen onze gegevens ook opslaan op een manier die ons in staat stelt deze efficiënt op te halen, zelfs als de opslag niet persistent is. Dus uiteindelijk zullen we hebben twee exemplaren van onze gegevens : één wordt opgeslagen in MySQL en de andere wordt opgeslagen in Memcache.
Hier zijn de stappen die we moeten nemen om dit mogelijk te maken:
INSERTS
en updates
) wordt uitgevoerd in zowel MySQL als MemcachedSELECT
) zal worden uitgevoerd in Memcached en zal terugvallen op MySQL in geval van een foutOp dit punt ziet u waarschijnlijk welke delen van uw code moeten worden gewijzigd: delen waar u gegevens schrijft en delen waar u gegevens leest. Als je PHP-code goed gestructureerd is, zou je je datatoegangscode moeten hebben ingepakt in functies of zelfs betere klassen. Als dit het geval is, zou het updaten van uw site erg snel moeten zijn. Zo niet, dan heb je misschien wat meer werk.
Laten we eerst een verbinding maken met onze Memcached-server. Hier is de code die je zou moeten gebruiken, vroeg in je PHP-scripts:
// Verbindingsconstanten definiëren ('MEMCACHED_HOST', '127.0.0.1'); define ('MEMCACHED_PORT', '11211'); // Verbinding maken $ memcache = nieuwe Memcache; $ cacheAvailable = $ memcache-> connect (MEMCACHED_HOST, MEMCACHED_PORT);
Op dit moment hebben we een verbinding met onze Memcache-server tot stand gebracht. Het is misschien mislukt, maar we weten het dankzij de $ cacheAvailable
veranderlijk.
Laten we duiken in gegevensopslag. We gaan een voorbeeld nemen om dingen duidelijker te maken - een online winkel. We hebben een script genaamd edit_product.php
waarvan het doel is om de gegevens van een product in onze database op te slaan. Elk van onze producten heeft de volgende informatie:
Op een bepaald moment in onze edit_product.php
code, we voeren een INSERT
of BIJWERKEN
SQL-query waarvan het doel is om de gegevens van dit product naar onze MySQL-database te schrijven. Het zou er precies zo uit kunnen zien:
// We hebben onze gegevens gevalideerd en ontsmet // We zijn aan elke riskante char ontsnapt met mysql_real_escape_string () // Nu willen we deze opslaan in onze database $ sql = "INSERT INTO-producten (id, naam, beschrijving, prijs) WAARDEN ( $ id, '$ naam', '$ beschrijving', $ prijs) "; $ querySuccess = mysql_query ($ sql, $ db);
Zoals ik hierboven al zei, willen we onze gegevens opslaan in onze MySQL-database en Memcached-server. Dit is hoe we verder gaan:
// We hebben onze gegevens gevalideerd en ontsmet // We zijn aan elke riskante char ontsnapt met mysql_real_escape_string () // Nu willen we ze naar onze database schrijven: $ sql = "INSERT INTO producten (id, naam, beschrijving, prijs) WAARDEN ($ id, '$ naam', '$ beschrijving', $ prijs) "; $ querySuccess = mysql_query ($ sql, $ db); // We hebben onze gegevens in onze database geschreven // Nu gaan we de productnaam, beschrijving en prijs in onze cache opslaan // De methode "set" vertelt onze Memcached-server om de gegevens te bewaren die aan een specifieke sleutel zijn gekoppeld ($ querySuccess = == true) // We bouwen een unieke sleutel die we later opnieuw kunnen bouwen // We gebruiken het woord 'product' plus de ID van ons product (bijv. "product_12") $ key = 'product_'. $ Id; // We slaan een associatieve array op die onze productgegevens bevat $ product = array ('id' => $ id, 'naam' => $ naam, 'omschrijving' => $ omschrijving, 'prijs' => $ prijs); // En we vragen Memcached om die gegevens op te slaan $ memcache-> set ($ key, $ product);
Op dit moment bevatten zowel onze database als onze cache onze productgegevens.
Als onze cache niet beschikbaar is, willen we terugvallen op MySQL.
Laten we nu onze gegevens ophalen. Laten we in hetzelfde voorbeeld zeggen dat onze online winkel een script heeft genaamd product.php
die een specifiek product weergeeft. Toegang tot de pagina product.php? id = 12
zal het product weergeven waarvan de identifier 12 is.
Op een bepaald moment in onze product.php
code, we voeren een SELECT
SQL-query waarvan het doel is om de gegevens van een product op te halen uit onze MySQL-database. Het zou er precies zo uit kunnen zien:
// We hebben onze gegevens gevalideerd en ontsmet // We zijn ontsnapt aan elke riskante char met mysql_real_escape_string () // Nu willen we lezen uit onze database: $ sql = "SELECT ID, naam, beschrijving, prijs FROM producten WHERE id =" . $ Id; $ queryResource = mysql_query ($ sql, $ db); $ product = mysql_fetch_assoc ($ queryResource);
Zoals we hierboven al zeiden, willen we onze gegevens zo mogelijk van onze Memcached-server halen, omdat deze sneller is dan die van MySQL. Maar in het geval dat onze cacheserver niet kan worden bereikt of als het eenvoudigweg niet de gegevens opslaat die we nodig hebben, willen we terugvallen op MySQL. Dit is hoe we verder gaan:
// Initialiseer onze $ productvariabele $ product = null; // Eerst controleren we of onze cacheserver beschikbaar is // De variabele $ cacheAvailable is geïnitialiseerd toen we verbinding maakten met onze cacheserver if ($ cacheAvailable == true) // We bouwen de sleutel die we hebben gekoppeld aan onze productgegevens $ key = 'artikel_' . $ Id; // Nu krijgen we de gegevens van onze cacheserver $ product = $ memcache-> get ($ key); // hebben we toegang tot MySQL nodig? if (! $ product) // In het geval dat we doen ... omdat onze productvariabele $ nog steeds nul is // We hebben onze gegevens gevalideerd en ontsmet // We zijn aan elke riskante char ontsnapt met mysql_real_escape_string () // Nu willen we lezen uit onze database: $ sql = "SELECT ID, naam, omschrijving, prijs FROM producten WHERE id =". $ Id; $ queryResource = mysql_query ($ sql, $ db); $ product = mysql_fetch_assoc ($ queryResource);
Op dit punt hebben we de gegevens opgehaald die we nodig hadden. Het is waarschijnlijk gedaan vanuit onze cache, maar kan afkomstig zijn van MySQL als de cache niet was gevuld of om de een of andere reden niet kon worden geopend.
We hebben gezien hoe Memcached kan worden gebruikt om uw website te versnellen en uw databaselading te beperken. Ons voorbeeld hierboven was gebaseerd op PHP en MySQL omdat deze technologieën breed worden toegepast, maar dit principe is universeel en werkt net hetzelfde met veel andere technologieën: C / C ++, Java, Python, Ruby, Perl, .Net, MySQL, Postgres, Erlang, Lua, Lisp, Cold Fusion, Ocaml en io staan samen met PHP op de officiële Memcached-wiki.
Zoals ik eerder al vermeldde, biedt Memcached meer functies dan de eenvoudige set en krijgen we methoden die we hierboven hebben gezien. Twee nuttige extra functies zijn oplopende / aflopende updates en de mogelijkheid om een vervaltijd in te stellen voor een specifieke opgeslagen gegevens. Beide zijn beschikbaar in PHP, samen met enkele andere, zoals u kunt zien in de Memcache-documentatie.
Veel plezier met het implementeren van dit op uw websites en geniet van de -free- prestaties verbeteren. Heel erg bedankt voor het lezen en laat het me weten als je nog vragen hebt in de reacties hieronder.