0 follower

Datacachning

Datacachning handlar om att lagra nÄgon PHP-variabel i cacheminne och hÀmta tillbaka den senare frÄn cache. För detta ÀndamÄl tillhandahÄller cachekomponentens basklass CCache tvÄ metoder som anvÀnds för det mesta: set() och get().

För att lagra en variabel $value i cacheminnet vÀljer vi ett unikt ID och anropar set():

Yii::app()->cache->set($id, $value);

Cachelagrade data förblir i cachen obegrÀnsat lÀnge om de inte tas bort pÄ grund av nÄgon cachningspolicy (t.ex. slut pÄ cacheutrymme medförande att det Àldsta datat tas bort). För Àndring av detta beteende, kan en förfallotidsparameter lÀmnas med i anropet till set() sÄ att data stÀdas bort frÄn cachen efter en viss tid:

// keep the value in cache for at most 30 seconds
Yii::app()->cache->set($id, $value, 30);

Senare, nÀr variabeln behöver kommas Ät (antingen i samma eller nÄgon annan webbrequest), ÄterhÀmtas den frÄn cache genom anrop till get() med ID bifogat. Om vÀrdet som returneras Àr false, innebÀr detta att sökt vÀrde inte Àr tillgÀngligt i cachen utan mÄste genereras pÄ nytt.

$value=Yii::app()->cache->get($id);
if($value===false)
{
    // regenerate $value because it is not found in cache
    // and save it in cache for later use:
    // Yii::app()->cache->set($id,$value);
}

Vid val av ID för en variabel som skall cachas, tillse att ID:t Àr unikt bland alla andra variabler som kan komma att cachas i applikationen. Det Àr INTE ett krav att ID:t Àr unikt över fler applikationer dÄ cachekomponenten Àr intelligent nog att Ätskilja ID:n tillhörande skilda applikationer.

Vissa cachelagringar, sÄ som MemCache, APC, stöder ÄterhÀmtning av multipla cachelagrade vÀrden genom ett satsvis arbetssÀtt, vilket kan reducera onödig resursanvÀndning vid ÄterhÀmtning av cachelagrad data. Metoden mget() finns tillgÀnglig för detta ÀndamÄl. I hÀndelse av att den underliggande cachelagringen inte stöder nÀmnda finess, simuleras den av mget().

För att ta bort ett cachat vÀrde, anropa delete(); för att ta bort allting frÄn cache, anropa flush(). Var mycket försiktig med att anropa flush() eftersom Àven cachelagrat data frÄn andra applikationer tas bort.

Tips: Eftersom CCache implementerar ArrayAccess, kan en cachekomponent anvÀndas som en array. HÀr följer nÄgra exempel:

$cache=Yii::app()->cache; 
$cache['var1']=$value1;  // equivalent to: $cache->set('var1',$value1); 
$value2=$cache['var2'];  // equivalent to: $value2=$cache->get('var2');

1. Cacheberoende ¶

Förutom utgÄngen förfallotid, kan cachelagrat data ocksÄ ogiltiggöras som följd av nÄgon förÀndring i beroenden. Till exempel, om innehÄllet i nÄgon fil cachelagras och filen Àndras, sÄ skall kopian i cachen markeras som ogiltig och det senaste innehÄllet frÄn filen lÀsas i stÀllet.

Ett beroende representeras som en instans av CCacheDependency eller nedÀrvd klass. Dependency-instansen bifogas data som skall cachas i anropet till set().

// the value will expire in 30 seconds
// it may also be invalidated earlier if the dependent file is changed
Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));

Om vi nu ÄterhÀmtar $value frÄn cachen medelst anrop till get(), kommer beroendet att utvÀrderas. Om en förÀndring skett erhÄlls returvÀrdet false, vilket indikerar att data behöver genereras pÄ nytt.

Nedan följer en sammanstÀllning av tillgÀngliga cacheberoenden:

  • CFileCacheDependency: beroendet Ă€ndras vid förĂ€ndring av filens tidangivelse avseende senaste Ă€ndring.

  • CDirectoryCacheDependency: beroendet Ă€ndras vid förĂ€ndring av nĂ„gon fil i katalogen eller dess underkataloger.

  • CDbCacheDependency: beroendet Ă€ndras vid förĂ€ndring i resultatet av databasfrĂ„gan given av specificerad SQL-sats.

  • CGlobalStateCacheDependency: beroendet Ă€ndras vid förĂ€ndring av vĂ€rdet för det specificerade globala tillstĂ„ndet. Ett globalt tillstĂ„nd Ă€r en variabel som behĂ„ller sitt vĂ€rde över multipla request och multipla sessioner i en applikation. Det definieras via CApplication::setGlobalState().

  • CChainedCacheDependency: beroendet Ă€ndras om nĂ„got av beroendena i kedjan förĂ€ndras.

  • CExpressionDependency: beroendet Ă€ndras om vĂ€rdet av det specificerade PHP-uttrycket Ă€ndras.

2. Cachning av databasfrÄgor ¶

Sedan version 1.1.7, har Yii stöd för cachning av databasfrÄgor. Med hjÀlp av datacachning lagrar frÄgecachning resultatet av en DB-frÄga och kan pÄ sÄ vis spara exekveringstid i databasen för en frÄga som upprepas senare, eftersom den kan hÀmtas direkt frÄn cache.

Info: Vissa DBMS (t.ex. MySQL) stöder Àven frÄgecachning i databasservern. JÀmfört med denna frÄgecachning i server, Àr finessen som avhandlas hÀr mer flexibel samt har potential att vara mer effektiv.

Aktivera frÄgecachning

För att aktivera frÄgecachning, tillse att CDbConnection::queryCacheID refererar till ID för en giltig cache-applikationskomponent (standardvÀrde cache).

AnvÀnda frÄgecachning med DAO

För att anvÀnda frÄgecachning, anropa metoden CDbConnection::cache() nÀr DB-frÄgor genomförs. Följande Àr ett exempel:

$sql = 'SELECT * FROM tbl_post LIMIT 20';
$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post');
$rows = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll();

NÀr ovanstÄende programsatser körs, kommer Yii att först att undersöka om det finns ett giltigt resultat i cache för den SQL-sats som skall exekveras. Det sker genom att följande tre villkor kontrolleras:

  • cache innehĂ„ller en post indexerad av aktuell SQL-sats.
  • postens giltighetstid ej överskriden (mindre Ă€n 1000 sekunder sedan den först sparades i cache).
  • dess dependency ej Ă€ndrad (maxvĂ€rdet av update_time oförĂ€ndrat sedan frĂ„geresultatet sparades i cache).

Om samtliga villkor ovan Àr uppfyllda, kommer det cachelagrade resultatet att returneras. I annat fall skickas SQL-satsen till databasservern för exekvering och tillhörande resultat lagras i cache, samt returneras.

AnvÀnda frÄgecachning med ActiveRecord

FrÄgecachning kan Àven anvÀndas med Active Record. För att göra detta anropas en snarlik metod CActiveRecord::cache() pÄ följande sÀtt:

$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post');
$posts = Post::model()->cache(1000, $dependency)->findAll();
// relationell AR-frÄga
$posts = Post::model()->cache(1000, $dependency)->with('author')->findAll();

Metoden cache() hÀr, Àr i praktiken en genvÀg till CDbConnection::cache(). Internt, vid exekvering av SQL-satsen som ActiveRecord genererat, kommer Yii att försöka anvÀnda frÄgecachning sÄ som beskrivits i förra delavsnittet.

Cachning av multipla frÄgor

Som standard gÀller att ett anrop till metoden cache() (i antingen CDbConnection eller CActiveRecord), medför att nÀsta SQL-sats markeras för cachning. Varje annan SQL-frÄga kommer INTE att cachelagras, sÄvida inte cache() anropas igen. Till exempel,

$sql = 'SELECT * FROM tbl_post LIMIT 20';
$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post');
 
$rows = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll();
// frÄgecachning kommer INTE att anvÀndas
$rows = Yii::app()->db->createCommand($sql)->queryAll();

Genom att lÀmna med en extra $queryCount-parameter till metoden cache(), kan vi framtvinga frÄgecachning av multipla frÄgor. NÀr vi i följande exempel anropar cache(), specificeras att frÄgecachning skall anvÀndas för de tvÄ följande frÄgorna:

// ...
$rows = Yii::app()->db->cache(1000, $dependency, 2)->createCommand($sql)->queryAll();
// frÄgecachning KOMMER ATT anvÀndas
$rows = Yii::app()->db->createCommand($sql)->queryAll();

Som bekant Àr det möjligt att flera SQL-frÄgor exekveras nÀr en relationell AR-frÄga genomförs (möjlig att kontrollera i loggmeddelanden). Till exempel, om sambandet mellan Post och Comment Àr HAS_MANY, kommer följande kod att faktiskt exekvera tvÄ DB-frÄgor:

  • first selekteras posterna med antal begrĂ€nsat till 20;
  • dĂ€refter hĂ€mtas kommentarerna som tillhör de tidigare selekterade posterna.
$posts = Post::model()->with('comments')->findAll(array(
    'limit'=>20,
));

Om vi anvÀnder frÄgecachning pÄ följande sÀtt kommer endast den första DB-frÄgan att cachelagras:

$posts = Post::model()->cache(1000, $dependency)->with('comments')->findAll(array(
    'limit'=>20,
));

För att cachelagra bÄda DB-frÄgorna behöver vi lÀmna med den extra parametern som indikerar hur mÄnga DB-frÄgor vi vill cachelagra hÀrnÀst:

$posts = Post::model()->cache(1000, $dependency, 2)->with('comments')->findAll(array(
    'limit'=>20,
));

BegrÀnsningar

FrÄgecachning fungerar inte med frÄgeresultat som innehÄller resursidentifierare (resource handles). Till exempel, nÀr kolumntypen BLOB anvÀnds i vissa DBMS, kommer frÄgeresultatet att returnera en resursidentifierare som kolumndata.

Somliga cachelagringsmetoder har begrÀnsningar i minnesstorlek. Till exempel memcache begrÀnsar storleken pÄ varje post till 1MB. Om ett frÄgeresultat överskrider denna maxstorlek kommer cachelagringen att misslyckas.

Found a typo, or you think this page needs improvement?
Edit it on GitHub !