[PHP/MySQL/Memcache] Het beste gebruik van memcache

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • SvMp
  • Registratie: September 2000
  • Niet online
Voor een website, die veelvuldig gebruik maakt van MySQL, wil ik memcache gebruiken om de website sneller te maken.

Ik wil niet domweg queries cachen, maar gericht de cache inzetten voor veel gebruikte functies, zoals het opzoeken van een afbeelding of een produktlijst opvragen, zaken die gepaard gaan met de nodige queries.

Het implementeren daarvan is eenvoudig. Als de website kort geleden opgevraagd is, is de website een stuk sneller.

Nu komt het probleem: Hoe het beste omgaan met wijzigingen?
Via de backend worden wijzigingen aangebracht in de database. Deze worden niet direct meegenomen, omdat er informatie uit de memcache kan worden gehaald.

De simpelste manier is om de cache te legen (flush) na iedere wijziging vanaf het admin-panel.
Deze manier is echter niet effectief. Alles moet opnieuw gecached worden.

Een effectievere manier is de entries in de cache in rubrieken indelen, bijv. vertalingen, afbeeldingen en produkten. Er kan dan gericht geflusht worden na een wijziging. Na mijn weten bestaat deze mogelijkheid niet.

De beste manier is de entries weghalen die gegevens bevatten die inmiddels gewijzigd zijn.
En dat is lastig, omdat er veel afhankelijkheden zijn. Soms worden gegevens uit wel 4 verschillende tabellen gehaald. Het is behoorlijk complex om bij te houden welke rows uit welke tabels bij de query betrokken zijn, om rekening te houden met de memcache als er zaken zijn gewijzigd.

Een mogelijke oplossing is alleen hele kleine dingen cachen die veel gebruikt worden door het script.

Voorbeeld:
Vertalingen, zeer geschikt hiervoor.
Query: SELECT tekst FROM vertalingen WHERE tekstID=? AND taal=?
Wordt veel herhaald, omdat van elke zin een vertaling wordt opgehaald. Memcache kan hier uitermate nuttig werk verrichten. Query-resultaat wordt opgeslagen onder de key "vertaling_{$taal}_{$tekstID}". Vóórdat er een query wordt uitgevoerd, wordt op deze key gezocht.
Als ik een vertaling verander, moet het script dat de verandering voorvoert controleren of de vertaling in de memcache staat en zo ja, wissen.

Maar meestal heb je te maken met veel uitgebreidere queries waar veel verschillende rijen uit verschillende tabellen in voor komen. Dan is het niet meer zo gemakkelijk.

Voorbeeld:
SELECT produktcode, produktnaam FROM produkten WHERE categoriecode=?

Deze query geeft produkten die dezelfde categoriecode hebben.
Bij het wijzigen van een produkt is het niet een kwestie van een unieke, onveranderlijke, key controleren.
In dit geval is het al zo dat je moet kijken wat de categoriecode vóór de wijziging is. Deze moet geflusht worden (er is een produkt afgegaan of de code/naam zijn gewijzigd). Als er een gewijzigde categoriecode is, moet ook die code geflusht worden (er is een produkt bijgekomen). Dit is al veel meer werk. En dan is dit nog maar een enkelvoudige query.

Ik ben benieuwd naar suggesties voor de beste methode om met memcache en gewijzigde gegevens om te gaan, zonder dat het verzandt in een complexe administratie.

[ Voor 24% gewijzigd door SvMp op 06-07-2010 11:11 ]


Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Nu online
Je kan er voor kiezen om HTML te gaan cachen op basis van de URL.

Stel je hebt voor elke productpagina een url als: /[taal]/product/[id]/[productnaam]. Als dan in de backend ook maar iets veranderd waar dat product id in voor komt dan wis je de cache voor dat product-id. Je memcache key kun je instellen op "/[taal]/product/[id]" en dat is in de backend redelijk makkelijk uit te zoeken.

Alternatief is een cache van bv 30 seconden ofzo. Bij een drukke site levert dat ook al voldoende winst op.

Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
vertaling is juist iets wat ik persoonlijk dan weer naar een template laag zou verplaatsen. Met smarty kun je bijvoorbeeld de {#tekst#} constructie gebruiken. En die strings staan dan weer in een dynamisch van uit het backend geschreven include file, die ik in mijn frontend display class weer in laad

code:
1
2
3
4
5
[nl]
tekst = """dit is een tekst"""

[en]
tekst  = """this is a text"""


In mijn optiek net zo makkelijk als die gegevens uit een memcacheD te halen :)

Doctrine1 schrijft bijvoorbeeld de query cache weg met een hash en een timestamp in het welk systeem je kiest (files, memcached, apc of wat je maar wilt) Op basis van de hash weet ie of de query in de cache zit, en de timestamp zorgt voor een invalid. Bij een systeem wat zo druk is dat je query cache nodig hebt, is het is meestal ook wel acceptabel dat je naar gegevens van zeg 5 minuten oud zit te kijken. Alleen de data die je echt realtime nodig hebt, haal je altijd zonder die query cache op.
rutgerw schreef op dinsdag 06 juli 2010 @ 11:21:
Je kan er voor kiezen om HTML te gaan cachen op basis van de URL.

Stel je hebt voor elke productpagina een url als: /[taal]/product/[id]/[productnaam]. Als dan in de backend ook maar iets veranderd waar dat product id in voor komt dan wis je de cache voor dat product-id. Je memcache key kun je instellen op "/[taal]/product/[id]" en dat is in de backend redelijk makkelijk uit te zoeken.

Alternatief is een cache van bv 30 seconden ofzo. Bij een drukke site levert dat ook al voldoende winst op.
Dat is een ook oplossing, als het systeem echt zo druk is kun je ook kijken naar varnish met ESI. Dan wordt je hele pagina als statisch getoond via de varnish proxy, en via SSI kun je dan een koppeling maken met je PHP backend.

Beetje wat er bij nu.nl ook gebruikt wordt bijvoorbeeld goed artikel van Peter/ibs hierover

[ Voor 34% gewijzigd door kwaakvaak_v2 op 06-07-2010 12:02 ]

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 11-09 13:55
SvMp schreef op dinsdag 06 juli 2010 @ 11:00:
Een effectievere manier is de entries in de cache in rubrieken indelen, bijv. vertalingen, afbeeldingen en produkten. Er kan dan gericht geflusht worden na een wijziging. Na mijn weten bestaat deze mogelijkheid niet.
Dit kun je bereiken met pseudo-namespacing; Prefix de cache indexes die je in een bepaalde namespace wilt hebben met een bepaalde variabele. Wanneer je alle waarden in die namespace wilt wijzigen verander je de waarde van die variabele.

[ Voor 22% gewijzigd door frickY op 06-07-2010 12:13 ]


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Offtopic: Heb je de queries en indexen al wel geoptimaliseerd? Genoemd voorbeeld is dermate simpel dat een bruikbare index er al voor zorgt dat je met een paar duizendsten van een seconde al een antwoord te pakken hebt. Daar heb je echt geen memcache voor nodig. Ga met EXPLAIN aan de slag en versnel de boel door de juiste indexen aan te maken.

Mocht MySQL het probleem zijn, PostgreSQL kent een ander cachingmechanisme waardoor veelgebruikte data in de cache komt te staan en niet het resultaat van een enkele query (wat met MySQL het geval is). Hierdoor profiteren veel meer queries van de cache, mogelijk zelfs alle queries. Je hebt dan effectief een in-memory-database die nooit meer iets vanaf schijf hoeft te halen. Daarnaast worden views veel efficiënter uitgevoerd waardoor je ook daar weer winst kan behalen.

Acties:
  • 0 Henk 'm!

  • Brains
  • Registratie: Oktober 2006
  • Laatst online: 04-03-2024
Ter aanvulling van de post van frickY:

Wij gebruiken ook een dergelijke oplossing: een key op basis van objecttype + parameters => [taal].[objecttype].[uid] Bij het opslaan van een object zijn alle uniek identificerende parameters bekend, dus ook cache-key.

Indien nodig loopen we over alle chache-keys heen om meerdere items te wijzigen. Meestal dan ook direct een replace van het item.

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Je zou de theorie achter Zend_Cache eens kunnen doorlezen, dat is wel goed opgezet.

Het komt er op neer dat je één of meerdere tags geeft aan je cache-items (bijvoorbeeld de naam van een database-tabel). Zodra je iets wijzigt in een tabel gooi je alle cache-items met als tag die betreffende tabel weg. Dit kan natuurlijk slimmer, maar geeft even het idee aan.

Als iets dan afhankelijk is van vier tabellen, dan hangen er dus vier tags aan.

Acties:
  • 0 Henk 'm!

  • SvMp
  • Registratie: September 2000
  • Niet online
Ik vind de suggestie van frickY waardevol.

Evenals de andere tips trouwens. Voor een website die voor 99% read-only is, is Varnish passender. Daar ben ik ook mee aan het experimenteren.
Brains schreef op dinsdag 06 juli 2010 @ 12:42:
Ter aanvulling van de post van frickY:

Indien nodig loopen we over alle chache-keys heen om meerdere items te wijzigen. Meestal dan ook direct een replace van het item.
Hoe doe je dat?
Probleem van Memcache is, is dat je niet een lijst kunt maken van alle aanwezige keys. Helaas kun je ook geen jokertekens voor de key gebruiken bij het verwijderen van een entry.
Je kunt alleen checken of een key met een bepaalde naam er is. Alle mogelijke keynamen genereren en nalopen is onwerkbaar.

Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Memcache heeft wel een delete_many mogelijkheid om snel veel cache te kunnen clearen. Maar... memcache is en blijft een heel eenvoudig cache systeem. Alleen het laagste niveau get/set kan je met memcache doen. De rest van de intelligentie moet je ergens anders laten.

Een aantal mogelijke oplossingen zijn:
- cache key prefixes om een hele cache groep tegelijk te kunnen resetten
- altijd alle cache direct setten bij het wijzigen van data. Ik ga er nu vanuit dat jouw systeem voornamelijk leest en nauwelijks schrijft. In dat geval is bij elke wijziging alle relevante caches opnieuw wegschrijven vaak de beste optie. Maar wel een lastige optie uiteraard.
- bij het wijzigen een lijst met mogelijk beinvloede keys genereren en die allemaal deleten/genereren

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • Brains
  • Registratie: Oktober 2006
  • Laatst online: 04-03-2024
Via de extended stats kun je het eea opvragen, maar dat is beperkt tot 1-2 mb aan keys, zie bijv:
http://100days.de/serendi...ontent-Keys-with-PHP.html

Wij houden naast het cache ook een cache-register bij, dat kan zowel in de db als in de cache-provider. Wij hebben een "write once, read many"-strategy, waarbij het aantal cache-updates erg laag is tov de reads. De extra actie na het wijzigen van een object, het controleren en updaten van het cache, nemen we dan voorlief. Die actie zou je ook kunnen verleggen buiten de reguliere infromatiestroom.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

SvMp schreef op dinsdag 06 juli 2010 @ 11:00:
Bij het wijzigen van een produkt is het niet een kwestie van een unieke, onveranderlijke, key controleren.
In dit geval is het al zo dat je moet kijken wat de categoriecode vóór de wijziging is. Deze moet geflusht worden (er is een produkt afgegaan of de code/naam zijn gewijzigd). Als er een gewijzigde categoriecode is, moet ook die code geflusht worden (er is een produkt bijgekomen). Dit is al veel meer werk.
Zo moeilijk is dat toch niet? In de procedure die je gebruikt om het product naar je database weg te schrijven (of een van de lagen er net boven) weet je dat soort dingen als het goed is toch wel. Het lijkt me doorgaans zelfs relatief eenvoudig om te bepalen of er een key verwijderd moet worden en daar mag je best wat scheutig mee zijn, over het algemeen kan het niet zoveel kwaad om een paar keys teveel te verwijderen of opnieuw te genereren.
En dan is dit nog maar een enkelvoudige query.
Imho moet je bij je cache sowieso wel een beetje oppassen dat je niet alle data tig keer opnieuw aan het cachen bent. Daar neemt mogelijk je hitratio alleen maar van af. Door de cache wat finer grained te maken (en dan niet vergeten goed gebruik te maken van multiget) moet je een heel eind kunnen komen met relatief eenvoudige verwijderingen van specifieke groepjes caches.

Verder zijn er al diverse andere tips genoemd natuurlijk :)
Ik ben benieuwd naar suggesties voor de beste methode om met memcache en gewijzigde gegevens om te gaan, zonder dat het verzandt in een complexe administratie.
Je zal er uiteraard bij de opzet van wat je nou precies cached al rekening mee moeten houden dat het later ook weer eenvoudig te verversen is. Soms moet je dan wellicht besluiten je caching wat te ruim te maken of juist finer grained te maken domweg om het beheersbaar te houden. Je voorbeeld van de categorieen, je zou dan bijvoorbeeld alleen die producten zo moeten cachen, maar dan wellicht niet ook nog eens allerlei varianten gefiltered op prijs en gesorteerd op leeftijd, etc etc. Dan weet je bij het bijwerken van producten dat je maar maximaal drie cache-keys (productcache, productcategorie en evt voormalige productcategorie) hoeft te verwijderen.

Overigens is het altijd zinvol om ook domweg je mysql-queries te blijven optimaliseren, domweg omdat je af en toe ook cache-misses zal hebben.
cariolive23 schreef op dinsdag 06 juli 2010 @ 12:12:
Mocht MySQL het probleem zijn, PostgreSQL kent een ander cachingmechanisme waardoor veelgebruikte data in de cache komt te staan en niet het resultaat van een enkele query (wat met MySQL het geval is). Hierdoor profiteren veel meer queries van de cache, mogelijk zelfs alle queries. Je hebt dan effectief een in-memory-database die nooit meer iets vanaf schijf hoeft te halen. Daarnaast worden views veel efficiënter uitgevoerd waardoor je ook daar weer winst kan behalen.
Blijkbaar heb je de klok horen luiden, maar weet je niet waar de klepel hangt. Hoewel MySQL inderdaad een (uitschakelbare) query cache kent die puur op resultaatbasis werkt, heeft het ook (voor iedere storage engine verschillend) een cache-infrastructuur. Veel gebruikte data zal InnoDB dan ook in de zgn buffer pool terug kunnen vinden. En die buffer pool van InnoDB wordt o.a. op dezelfde manier gebruikt als wat je nu van PostgreSQL beweert dat het als voordeel tov MySQL heeft.
Sterker nog, het is zelfs bij MySQL meer common practice om die buffer pool groot te maken (bijv 50-80% van je beschikbare ram) dan dat het bij PostgreSQL is om de shared buffers groot te maken (ivm dubbele caching, zowel in de shared buffers als in de OS disk cache).

Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

ACM schreef op dinsdag 06 juli 2010 @ 23:07:
Blijkbaar heb je de klok horen luiden, maar weet je niet waar de klepel hangt. Hoewel MySQL inderdaad een (uitschakelbare) query cache kent die puur op resultaatbasis werkt, heeft het ook (voor iedere storage engine verschillend) een cache-infrastructuur. Veel gebruikte data zal InnoDB dan ook in de zgn buffer pool terug kunnen vinden. En die buffer pool van InnoDB wordt o.a. op dezelfde manier gebruikt als wat je nu van PostgreSQL beweert dat het als voordeel tov MySQL heeft.
Sterker nog, het is zelfs bij MySQL meer common practice om die buffer pool groot te maken (bijv 50-80% van je beschikbare ram) dan dat het bij PostgreSQL is om de shared buffers groot te maken (ivm dubbele caching, zowel in de shared buffers als in de OS disk cache).
Mee eens. Ik ben groot voorstander van PostgreSQL vanwege de vele extra mogelijkheden. Maar dit is toch niet een voorbeeld dat ik zou noemen.

Dan eerder de mogelijkheid om je memcache server direct vanuit postgres aan te spreken zodat je al je cache clears direct door triggers kan laten uitvoeren. Lijkt me in ieder geval een beter voorbeeld :)

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Wolfboy schreef op woensdag 07 juli 2010 @ 04:48:
Dan eerder de mogelijkheid om je memcache server direct vanuit postgres aan te spreken zodat je al je cache clears direct door triggers kan laten uitvoeren. Lijkt me in ieder geval een beter voorbeeld :)
MySQL heeft vziw ook een plugin voor integratie met memcached. :) Geen idee hoe ie werkt want ik heb het nooit gebruikt, onze keys zijn net als in dit topic lang niet altijd eenvoudig te vertalen naar equivalenten van eenvoudige selects en toen we daarmee begonnen bestond die plugin vziw ook nog niet.

Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37

TheNephilim

Wtfuzzle

Dit topic ga ik even in de gaten houden; ik maak ook gebruik van memcached in PHP, ik cache de queries met de statement als key.

Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

ACM schreef op woensdag 07 juli 2010 @ 08:12:
[...]

MySQL heeft vziw ook een plugin voor integratie met memcached. :) Geen idee hoe ie werkt want ik heb het nooit gebruikt, onze keys zijn net als in dit topic lang niet altijd eenvoudig te vertalen naar equivalenten van eenvoudige selects en toen we daarmee begonnen bestond die plugin vziw ook nog niet.
De MySQL memcached plugin is vziw alleen bruikbaar als tabel. Je hebt dus een tabel die volledig via memcached werkt met bijbehorende limitaties. Directe toegang tot memcached is er vziw niet.

Maargoed, dat is de discussie ook niet. Aangezien de TS hoogst waarschijnlijk geen ervaring met Postgres heeft en het hele systeem daar niet voor gebouwd is lijkt dat me niet de meest logische keuze op dit moment :+

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37

TheNephilim

Wtfuzzle

Om deze discussie nog even leven in te blazen, hier even een voorbeeld zoals ik zelf Memcached gebruik. 2 webservers draaien naast Apache/PHP ook Memcached op 256MB en MySQL slave.

We gebruiken memcached nu voor enkele statistieken queries en voor het voor zijn van de MySQL replicatie. Namelijk, je hebt 5 records die aan de gebruiker worden laten zien, deze klikt op 1 rij en daarmee word deze geupdate. Maar soms kwam bij het reloaden van deze pagina de records weer naar boven, zonder dat die aangepast waren. Hij had de records sneller gelezen van de slave, dan dat de master geschreven had naar de slaves. De applicatie is een browsergame trouwens.
Ik kreeg te tip hier op Tweakers om de gegevens naar Memcached te pushen en die eerst te laten zien. Nu moest ik dus gegevens ophalen, wijzigingen doorvoeren en laten zien. Hieronder de snippets:

Hier de pushfunctie zoals ik deze aanroep, en de update query richting de master:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Query naar memcached pushen
 $db->push_results($sql, "horse_id", array($horse_id => array("ride_timestamp" => time(), "riding_goods" => ($horse['riding_goods']+1))));

// Paard updaten
$db->query("
UPDATE 
  (`horse_timestamps` AS `ht` 
  INNER JOIN 
    `horse_riding` AS `hr` 
  USING 
     (`horse_id`))
SET 
  `ht`.`ride_timestamp`=".time().",
  `hr`.`riding_goods`=`hr`.`riding_goods`+1
WHERE
  `ht`.`horse_id`=".$horse_id);


Hier de pushfunctie zelf:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public static function push_results ($sql, $key, $array=array())
  {
    global $memcache;
    
    // Results ophalen
    $query = self::query($sql);
    while ($row = self::fetch_assoc($query))
    {      
      // Checken of gegevens gereplaced moeten worden
      if (is_array($array[$row[$key]]))
      {
        if (in_array("remove", $array[$row[$key]]))
        {
          // do nothing
        }
        else
        {
          foreach ($array[$row[$key]] AS $key=>$value)
          {
            $row[$key] = $value;
          }
          
          $result[] = $row;
        }
      }
      else
      {
        $result[] = $row;
      }
    }
    
    // Mem-free
    self::free_result($query);
    
    // Push to cache
    $memcache->set(md5($sql), $result, MEMCACHE_COMPRESSED, 3) or die ("Failed to save data at the server");
  }


Nu de functie om het eruit te halen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static function fetch_results ($sql, $push=false, $timeout=3)
  {
    global $memcache;
    
    // Cache checken
    $cache = $memcache->get(md5($sql));
    if ($cache)
    {
      return $cache;
    }
    else
    {
      $result = array();
      
      // Results ophalen
      $query = self::query($sql);
      while ($row = self::fetch_assoc($query))
      {
        $result[] = $row;
      }
      
      // Mem-free
      self::free_result($query);
      
      // Push to cache
      if ($push) $memcache->set(md5($sql), $result, MEMCACHE_COMPRESSED, $timeout) or die ("Failed to save data at the server");
      
      return $result;
    }
  }


De 2 functies zitten in een DB-wrapper-class. Opmerkingen of suggesties zijn altijd welkom! :D

Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
Inner joins kunenn een probleem met lag geven in een master-slave database zie deze blog bijvoorbeeld.

Tuurlijk werkt die memcache ook prima (denk ik), maar het 'probleem' kan mogelijk ontstaan zijn op een andere laag :)

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 14:37

TheNephilim

Wtfuzzle

kwaakvaak_v2 schreef op vrijdag 09 juli 2010 @ 13:37:
Inner joins kunenn een probleem met lag geven in een master-slave database zie deze blog bijvoorbeeld.

Tuurlijk werkt die memcache ook prima (denk ik), maar het 'probleem' kan mogelijk ontstaan zijn op een andere laag :)
Klopt, we hebben in de meeste situaties de UPDATE's gewoon weer opgesplitst in nieuwere queries. Er zitten er nog enkele zoals deze. We zijn zachtjes aan begonnen met testen en het lijkt goed te gaan, volgende week hopen we nog enkele tientallen testers erbij te krijgen.

Bedoel je het probleem mbt replicatielag?

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

kwaakvaak_v2 schreef op vrijdag 09 juli 2010 @ 13:37:
Inner joins kunenn een probleem met lag geven in een master-slave database zie deze blog bijvoorbeeld.

Tuurlijk werkt die memcache ook prima (denk ik), maar het 'probleem' kan mogelijk ontstaan zijn op een andere laag :)
MySQL heeft sowieso een replicatiemodel dat een vertraging tussen de slaves tov de master kan hebben. Dat sommige situaties dat verergeren, maakt het probleem niet per se weg als je dat oplost :) Dus het is altijd verstandig daar rekening mee te houden.

Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
Bernardo schreef op vrijdag 09 juli 2010 @ 14:12:
[...]

Bedoel je het probleem mbt replicatielag?
Wat ACM hierboven zegt, mySQL heeft soms wat snelheids problemen met de replicatie, dat de master dus voorloopt op de slaves. Geen probleem als je enkel maar slaves gebruikt voor reading. Dan heb je overal dezelfde gegevens staan behalve dan de gegevens die net ingevoerd zijn. Het is dus handig om hier in je applicatie rekening mee te houden, door bijvoorbeeld 1 DB enkel en alleen maar voor je realtime gegevens te gebruiken, en die voor de 'backup' te repliceren naar een slave mocht je dat nodig vinden, en 1 database met master/slave setup voor al je minder belangrijke shit.

In het geval van een schaakspel bijvoorbeeld, je huidige zetten gaan in een realtime database met innoDB (geen tablelock, maar rowlock!). De scores, de tracking (voor replay bijvoorbeeld), user to user berichtjes, shoutbox etc gaan in een master/slave DB (want niemand gaat door hebben dat het berichtje een seconde te laat is ;)) Wat handig kan zijn voor het verwerken van dit soort messages is een systeem als gearman.

Speler doet een zet, je schrijft A1 zwart paard naar B3 en reset de schaakklok, vervolgens schop je een gearman worker de lucht in, die gaat direct naar de achtergrond. Gearman dispatcher pakt die worker op, schrijft je zet naar de zetten database, doet evt wat analyse op die zet en scrhijft dat weg naar de master/slave DB.

Waarom maar 1 mysql DB met alles gebruiken, als je voor hetzelfde geld er meerdere kan gebruiken.


(en persoonlijk zou ik voor het bij houden van zetten niet eens een mySQL gebruiken, maar een noSQL key/val storage systeem, juist omdat dit nu precies een voorbeeld is waar die dingen erg makkelijk voor kunnen zijn. (en de hele match in 1 recordset met bijvoorbeeld Atomic operations

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
cariolive23 schreef op dinsdag 06 juli 2010 @ 12:12:
Mocht MySQL het probleem zijn, PostgreSQL kent een ander cachingmechanisme waardoor veelgebruikte data in de cache komt te staan en niet het resultaat van een enkele query (wat met MySQL het geval is). Hierdoor profiteren veel meer queries van de cache, mogelijk zelfs alle queries. Je hebt dan effectief een in-memory-database die nooit meer iets vanaf schijf hoeft te halen. Daarnaast worden views veel efficiënter uitgevoerd waardoor je ook daar weer winst kan behalen.
Ter aanvullig op ACM: De query cache van MySQL is een onding. Alleen al vanwege de global mutex zet je die op een beetje server liever uit. En met MyISAM heb je de OS cache nog.
Waarom maar 1 mysql DB met alles gebruiken, als je voor hetzelfde geld er meerdere kan gebruiken.
Omdat de foutkans toeneemt en de boel complexer wordt om te repareren.

Voor memcached houd ik zelf de volgende dingen aan:
- Queries moeten snel zijn. Het cachen van een snelle query heeft op zichzelf weinig zin.
- Na zware dataverwerking cachen is wel zinvol.
- Als je meerdere elementen op één pagina hebt die afzonderlijk opgevraagd moet worden, en je kunt gebruik maken van een multiget (met één opvraagactie gegevens voor meerdere keys opvragen), dan is cachen zinvol.

Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
GlowMouse schreef op maandag 12 juli 2010 @ 11:33:

Omdat de foutkans toeneemt en de boel complexer wordt om te repareren.
onzin... Dan heb je het project/code vanaf de start gewoon niet goed opgezet imho..

Als je gewoon netjes een object maakt wat de moves bij houdt, hoeft alleen dat object maar te weten wat de moves database is. En als je het heel voor door trekt, zelfs dat nog niet eens, maar hoeft enkel je storage laag maar te weten waar de data naar toe moet. De lagen erboven horen niet eens te weten waar de data vandaan komt.

Als je idd in je presentatie laag, een keiharde query op je DB doet, ja dan neemt de kans op fouten toe.

Driving a cadillac in a fool's parade.

Pagina: 1