PHP APC – Snabba upp din hemsida med cache

PHP snabbt med acceleratorEn nackdel med PHP jämfört med andra alternativ som t.ex. Dotnet är att kod skriven med PHP kompileras först när när webbservern ska läsa filen och resultatet av kompileringen sparas inte. Om PHP-filen inte ändras så är det egentligen onödigt att kompilera PHP-koden för varje förfrågning webbservern får. Det är här en accelerator för PHP som t.ex. APC (Alternative PHP Cache) kommer in i bilden.

Det finns många alternativ till APC och en del används i stor utsträckning även idag. XCache och eAccelerator är två vanliga alternativ för att slipper kompilera PHP-kod vid varje exekvering. Från och med PHP version 5.5 och framåt så kommer PHP att levereras med en inbyggd cache, Zend OPCache. PHP version 5.5 befinner sig dock endast i beta och när versionen väl släpps som stabil faller det naturligt att många uppdaterar med försiktighet. Funktionen ska dock inte vara påslagen som standard och det bör fungera även med andra cache alternativ.

Zend OPCache har visat sig vara snabbare än APC i genomsnitt och planerarna på att integrera APC i PHP har därför förändrats över tid.

Varför gör APC PHP-applikationer snabbare?

För att förstå hur en PHP-applikation kan bli snabbare av APC så måste stegen för vad som händer på serversidan beskrivas. På ett mycket förenklat sätt kan det scenariot beskrivas som följande.

När du anropar en PHP-fil på en webbserver genom webbläsaren så kommer webbservern att exekvera PHP för att ta hand om filändelsen. PHP kommer läsa in PHP-koden från filen och kompilera det till OP-kod med hjälp av Zend Engine. OP-koden kommer sedan att exekveras och resultatet returneras tillbaka till webbservern för att i sin tur skickas tillbaka till din webbläsare.

APC snabbar upp denna process genom att spara OP-koden i minnet och om inte filen ändrats vid nästa förfrågan så kommer den tidigare sparade OP-koden exekveras. På så sätt slipper du att PHP ska kompilera om kod vid varje förfrågan. Vid stora PHP-applikationer som Dupral, Joomla, WordPress och även vid egenskrivna applikationer så kommer detta snabba upp exekveringen och resultatet av webbsidorna väldigt mycket.

APC ger även dina PHP-applikationer delat minne

APC-delat-minne-i-PHPAPC har ytterligare ett syfte och det är tillhandahålla en möjlighet för PHP att dela på minne. Du kan med andra ord spara variabler, arrayer och objekt som går att nå från alla PHP-instanser på den lokala webbservern. Detta kan vara ett bättre alternativ till memcached om du vet att du endast kommer köra PHP-applikationen från en webbserver.

Föreställ dig att du har en hemsida och i botten vill du skriva ut hur många rader det finns i en viss MySQL-tabell. Kanske för att visa på antal inlägg i en blogg, uppladdade videos eller antalet medlemmar på sidan. Genom att låta APC spara värdet så kan du visa en cache av värdet under exempelvis 10 minuter innan värdet uppdateras igen. På så sätt slipper det exekveras en SQL-fråga för varje gång PHP-scriptet exekveras. Du sparar på så sätt både serverkapacitet och sidan laddas snabbare.

Du kan se kodexempel på detta längre ner.

Hur installerar jag APC på mitt webbhotell?

Många webbhotell kör redan någon form av PHP-accelerator för snabba upp denna process. Det är inte säkert att det är just APC som används på ditt webbhotell. Det är tyvärr heller inte möjligt att endast installera APC för en webbhotellkund då hela servern påverkas, så finns det inte redan installerat så kommer du nog få klara dig utan.

För dig som har VPS eller en egen dedikerad server så kan du självklart installera det själv. Tillvägagångssättet kan skilja sig något mellan distributioner av Linux eller om du eventuellt kör Windows. För Linux kan du installera det genom PECL med följande kommando.

pecl install apc

Paketförråden för många Linux-distar har APC så du kan installera det genom dem också, vilket i många fall kan rekommenderas. För Debian & Ubuntu borde något i stil med detta fungera.

aptitude install php-apc

För distributionerna Red Hat, Fedora och CentOS skiljer det sig lite.

yum install php-pecl-apc

Du måste köra kommandona som superuser eller root. Det kan också vara klokt att först söka efter APC i biblioteket för att få dess exakta namn. Det är inte säkert att namnen på paketen ovan stämmer helt överens.

För mer information om hur du installerar APC, se dokumentationen.

Konfigurera APC för bästa resultat

Har du full tillgång till servern kan du konfigurera APC för att fungera bäst efter dina förhållanden. Jag rekommenderar att öka minnesmängden till en nivå så du vet att det inte kommer begränsas. Detta förutsätter givetvis att det finns ledigt minne tillgängligt. Om APC regelbundet får slut på minne så kommer du gynnas mindre av att ha det aktiverat.

Du kan också ändra om APC ska radera den cache som finns automatiskt (apc.stat) så fort PHP-filen ändrats. Som standard är detta satt till 1 vilket har funktionen aktiverat och detta rekommenderas också.

Om du endast vill att APC ska vara aktiverat på filer du väljer så kan du stänga av så inte alla filer automatiskt sparas (apc.cache_by_default) med cache. Detta gör att du kan specificera vilka filer som ska spara med cache i ett filter (apc.filters).

Det finns en hel del möjligheter att konfigurera APC efter ens egna önskemål. Du hittar alla konfigurationer här.

PHP-kodexempel med APC & delat minne

Som nämnts ovan kan APC dela minne som är tillgängligt från alla PHP-instanser som körs. Följande exempel visar hur du kan spara en cache av antalet rader i en tabell för att slippa exekvera onödiga SQL-frågor.

// Öppna anslutning till databas
$mysqli = new mysqli('localhost', 'db_user', 'db_password', 'db_name');

// Försök hämta data från APC
if(!$num_rows = apc_fetch('num_rows')) {
    // Ingen data hittades, exekvera SQL-fråga och spara data i APC.
    $result = $mysqli->query('SELECT COUNT(*) FROM `table1`');
    if($row = $result->fetch_array(MYSQLI_NUM)) {
        $num_rows = $row[0];
        apc_store('num_rows', $num_rows, 600); // Spara i 10min (600 sek)
    }
}

printf('Antal rader: %d', $num_rows);

Exemplet ovan demonstrerar hur du kan nyttja APC för att spara data och låta bli att köra onödiga SQL-frågor. Om apc_fetch() misslyckas så exekveras SQL-frågan och antalet rader i tabellen sparas med funktionen apc_store() i 10 minuter.

Om du har en webbplats med väldigt många besökare varje minut så finns det mycket resurser att spara genom att använda sig av detta. Om du inte har tillgång till APC eller använder en annan accelerator för PHP så kan du uppnå liknande resultat med Memcached.

Andra APC-funktioner som kan vara intressanta är:

  • apc_add() – Samma som apc_store(), med undantaget att den inte skriver över befintlig data.
  • apc_delete() – Tar bort värde.
  • apc_exists() – Kontrollerar om en APC-nyckel finns.
  • apc_inc() – Ökar värdet på en befintlig Integer.
  • apc_dec() – Minskar värdet på en befintlig Integer.

Du hittar fler exempel och fler funktioner i PHP-manualen för APC.

Framtida stöd i PHP

APC fungerar bra för PHP 4, och fram till PHP 5.4. Som det nämns i inledningen kommer Zend OPCache att implementeras i PHP 5.5 vilket i mångas tyckte gör andra cache-system för PHP överflödiga. Zend Optimizer+ som det heter nu finns också att använda sig om du endast önskar komma åt funktionen för cache av OP-kod.

Många applikationer kan dock fortfarande snabbas upp rejält genom att lägga in exempelvis APC och det kan vara betydligt lättare att implementera det, än att uppgradera ett helt system så det blir kompatibelt med PHP 5.5.

Valet ligger helt enkelt i dina händer. Jag kommer givetvis att blogga mer om PHP 5.5 och Zend OPCache när en stabil version släppts.

Lämna en kommentar