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.
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 ]