Turbola din webbplats med Memcached

Din senaste PHP / MySQL-webbplats är äntligen online. Och det är fantastiskt. Men det är inte så snabbt som du vill att det ska vara, på grund av att många SQL-frågor körs varje gång en sida genereras. Och ovanför har du en känsla av att den inte kommer att skala bra under tunga belastningar. Och du är troligtvis rätt.

I den här handledningen ser vi hur du kan förbättra din webbplats starkt och hjälpa till att skala till att hantera många samtidiga besökare genom att implementera ett cachelag mellan din kod och din databas. Den goda nyheten är att det är ganska lätt, och kan göras om några minuter!


Presentera Memcached

Memcached är ett högpresterande minnesdatakachningssystem.

Moderna webbplatser och webbapplikationer använder mycket data, och det är inte ovanligt att räkna upp så många som 20 eller till och med 30 SQL-frågor i en enda sidgenerering. Multiplicera denna mängd med ett stort antal besökare, och du får ofta en överbelastad databas och sidor som tar sekunder att genereras och skickas till kunden.

Det verktyg vi ska använda idag för att förbättra prestanda kallas Memcached. Det är ett högpresterande minnesdatakachningssystem. Eller för att uttrycka det på ett annat sätt, en mycket snabb applikation som körs på din server och använder en bråkdel av tillgängligt minne för att lagra en associativ uppsättning data. Du kan be Memcached att göra två saker:

  • Spara värdet V med nyckeln K
  • Hämta värdet V lagras med nyckeln K

Det här ser minimalistiskt ut, men det finns mycket du kan göra tack vare dessa två funktioner, som vi kommer att se väldigt snart. Faktum är att Memcached kan göra några fler saker, men de är alla bundna för att lagra eller hämta data.

Installera Memcached på moderna Linux-distributioner är ganska enkelt:

  • Ubuntu: sudo apt-get install memcached
  • Gentoo: sudo emerge install memcached
  • Röd hatt : sudo yum installera memcached

När det är installerat, startas Memcached automatiskt varje gång din server startar. Du kan ange hur mycket minne som är reserverat för Memcached tillsammans med andra alternativ i konfigurationsfilen (/etc/memcached.conf). 64 MB är allokerad som standard. Konfigurationsfilen innehåller även IP-adressen och porten Memcached kommer att vara bunden till. Ursprungliga värden (127.0.0.1 och 11211) är bra för en standardinställning.


Få åtkomst till Memcached från PHP

Vi vill lagra och hämta data från dina PHP-skript. Det betyder att vi behöver ett sätt att ansluta till Memcached från PHP. För det ska vi installera "Memcache" -tillägget för PHP. Eftersom det är en PECL-förlängning är det väldigt lätt att installera med "pecl" genom att skriva följande kommando:

 sudo pecl installera memcache

Det finns två PHP-tillägg relaterade till Memcache: "Memcache" och "Memcached" (märka "d" i den andra). Båda är mycket lika, men den första har ett mindre fotavtryck. I denna handledning använder vi lättare Memcache. När den är installerad ska den här tillägget aktiveras och de Memcache-relaterade funktionerna ska nu vara tillgängliga för dina PHP-skript.


Hur fungerar Caching?

Vårt arbete här är baserat på följande antaganden:

  • att hämta data från databasen tar resurser (CPU + i / o)
  • Att hämta data från databasen tar tid
  • vi hämtar ofta samma data om och om igen

Vi vill också lagra våra data på ett sätt som gör att vi kan hämta det effektivt.

I allmänhet vill vi spara vår data i en bestående miljö (till exempel vår MySQL-databas). Men vi vill också lagra våra data på ett sätt som gör att vi kan hämta det effektivt, även om lagringen är ohållbar. Så i slutändan kommer vi att ha två kopior av våra data : en lagras i MySQL och den andra lagras i Memcache.

Här är de steg vi måste vidta för att detta ska ske:

  • Varje skrivoperation (SQL skär och uppdateringar) kommer att utföras i både MySQL och Memcached
  • Varje läsoperation (SQL väljer) kommer att utföras i Memcached, och kommer att falla tillbaka till MySQL vid fel

Vid den här tiden ser du förmodligen vilka delar av din kod som behöver ändras: delar där du skriver data och delar där du läser data. Om din PHP-kod är välstrukturerad borde du ha packat in din datakodskod i funktioner eller -even bättre klasser. Om så är fallet bör uppdateringen av din webbplats vara mycket snabb. Om inte, kanske du har lite mer arbete.


Anslut till vår Cache Server

Låt oss först skapa en anslutning till vår Memcached-server. Här är koden du ska använda, tidigt i dina PHP-skript:

 // Anslutningskonstanter definierar ('MEMCACHED_HOST', '127.0.0.1'); definiera ('MEMCACHED_PORT', '11211'); // Anslutning av anslutning $ memcache = ny Memcache; $ cacheAvailable = $ memcache-> anslut (MEMCACHED_HOST, MEMCACHED_PORT);

Vid denna tidpunkt har vi etablerat en anslutning till vår Memcache-server. Det kan ha misslyckats, men vi vet så tack vare $ cacheAvailable variabel.


Lagrar data i vår cache

Låt oss dyka in i datalagring. Vi ska ta ett exempel för att göra saker tydligare - en webbshop. Vi har ett skript som heter edit_product.php vars syfte är att spara en produkts data i vår databas. Var och en av våra produkter har följande information:

  • id
  • namn
  • beskrivning
  • pris

Vid någon tidpunkt i vår edit_product.php kod kör vi en FÖRA IN eller UPPDATERING SQL-fråga vars syfte är att skriva produktens data till vår MySQL-databas. Det kan se ut så här:

 // Vi har validerat och sanitiserat våra data // Vi har undvikit alla riskabla karaktärer med mysql_real_escape_string () // Nu vill vi spara den i vår databas $ sql = "INSERT INTO produkter (id, namn, beskrivning, pris) VÄRDEN ( $ id, '$ name', '$ description', $ pris) "; $ querySuccess = mysql_query ($ sql, $ db);

Som jag nämnde ovan vill vi lagra våra data både i vår MySQL-databas och Memcached-server. Så här går vi vidare:

 // Vi har validerat och sanitiserat våra data // Vi har släppt alla riskfyllda röster med mysql_real_escape_string () // Nu vill vi skriva dem till vår databas: $ sql = "INSERT INTO produkter (id, namn, beskrivning, pris) VÄRDER ($ id, '$ name', '$ description', $ pris) "; $ querySuccess = mysql_query ($ sql, $ db); // Vi har skrivit vår data i vår databas // Låt oss nu lagra produktnamnet, beskrivningen och priset i vår cache // Metoden "set" berättar att vår Memcached-server lagrar data som är kopplade till en viss nyckel om ($ querySuccess = == true) // Vi bygger en unik nyckel som vi kan bygga igen senare // Vi använder ordet "produkt" plus vår produkts id (t.ex. "product_12") $ key = 'product_'. $ Id; // Vi lagrar en associativ array som innehåller vår produktdata $ product = array ('id' => $ id, 'name' => $ name, 'description' => $ description, 'price' => $ pris); // Och vi ber Memcached att lagra den data $ memcache-> set ($ key, $ product); 

Vid denna tidpunkt innehåller både vår databas och cache vår produktinformation.


Hämtar data från vår cache

Om vår cache inte är tillgänglig, vill vi komma tillbaka till MySQL.

Låt oss nu hämta vår data. I samma exempel, låt oss säga att vår webbutik har ett skript som heter product.php som visar en viss produkt. Åtkomst till sidan product.php? id = 12 kommer att visa produkten vars identifierare är 12.

Vid någon tidpunkt i vår product.php kod kör vi a VÄLJ SQL-fråga vars syfte är att hämta en produkts data från vår MySQL-databas. Det kan se ut så här:

 // Vi har validerat och sanitiserat våra data // Vi har undvikit alla riskfyllda char med mysql_real_escape_string () // Nu vill vi läsa från vår databas: $ sql = "VÄLJ ID, namn, beskrivning, pris FRÅN produkter VAR ID =" . $ Id; $ queryResource = mysql_query ($ sql, $ db); $ product = mysql_fetch_assoc ($ queryResource);

Som vi nämnde ovan vill vi hämta vår data från vår Memcached-server om möjligt, eftersom det är snabbare än att få det från MySQL. Men om vår cache-server inte kan nås, eller om den helt enkelt inte lagrar de data vi behöver, vill vi komma tillbaka till MySQL. Så här går vi vidare:

 // Initiera vår $ produktvariabel $ product = null; // Först kontrollerar vi att vår cache-server är tillgänglig // $ cacheAvailable-variabeln initierades när vi anslutit till vår cachem server om ($ cacheAvailable == true) // Vi bygger nyckeln vi associerade med vår produktdata $ key = "product_". $ Id; // Nu får vi data från vår cacheserver $ product = $ memcache-> get ($ key);  // behöver vi åtkomst till MySQL? om (! $ produkt) // Om vi ​​gör ... eftersom vår $ produktvariabel fortfarande är null // Vi har validerat och sanitiserat våra data // Vi har undgåt alla riskfyllda karaktärer med mysql_real_escape_string () // Nu vill vi läsa från vår databas: $ sql = "VÄLJ ID, namn, beskrivning, pris FRÅN produkter WHERE id =". $ Id; $ queryResource = mysql_query ($ sql, $ db); $ product = mysql_fetch_assoc ($ queryResource); 

Vid denna tidpunkt har vi hämtat de data vi behövde. Det var troligtvis gjort från vår cache, men det kan vara från MySQL om cacheminnet inte fylldes eller inte kunde nås av någon anledning.


Slutsats

Vi har sett hur Memcached kan användas för att påskynda din webbplats och begränsa din databasbelastning. Vårt exempel ovan var baserat på PHP och MySQL eftersom dessa teknologier är allmänt utplacerade, men denna princip är universell och fungerar precis samma med många andra tekniker: C / C + +, Java, Python, Ruby, Perl, .Net, MySQL, Postgres, Erlang, Lua, Lisp, Cold Fusion, Ocaml och Io listas tillsammans med PHP på den officiella Memcached wiki.

Som jag kort sagt nämnde tidigare, erbjuder Memcached fler funktioner än den enkla uppsättningen och får metoder vi har sett ovan. Två användbara tilläggsfunktioner är uppgraderings- / minskningsuppdateringar och möjligheten att ställa in en utgångstid till en specifik lagrad data. Båda är tillgängliga i PHP, tillsammans med några andra, som du kan se i Memcache dokumentationen.

Ha det roligt att implementera detta på dina webbplatser, och njut av förbättringen av -fri prestanda. Tack så mycket för att läsa och var god och låt mig veta om du har några frågor i kommentarerna nedan.