Bij het opvragen van gegevens uit welke bron dan ook, is er altijd enige vertraging. Ping naar webservers wordt gemeten in milliseconden, de toegangstijd tot opslag kan latenties in de microseconden hebben, terwijl RAM-latentie wordt gemeten in CPU-klokcycli. Natuurlijk zouden dit soort snelheden slechts een paar decennia geleden ondenkbaar zijn geweest, maar in het heden zijn ze nooit snel genoeg. Toegangssnelheid is regelmatig een knelpunt in de prestaties. Een van de manieren waarop dit kan worden aangepakt, is met caching.
Caching is een proces waarbij een tijdelijke kopie van een bron wordt opgeslagen op een manier die sneller toegankelijk is dan normaal. Er is een enorm scala aan implementaties, zowel in software als hardware. Caches kunnen fungeren als leescaches, schrijfcaches of beide.
Caches lezen
In een leescache worden eerder opgevraagde gegevens opgeslagen in een cache voor snellere toegang. In sommige scenario's kan de cache zelfs preventief worden geladen met gegevens waardoor het eerste verzoek vanuit de cache kan worden gedaan in plaats van alleen volgende verzoeken.
De leescache die u waarschijnlijk kent, is de browsercache. Hier slaat de browser een lokale kopie op van de gevraagde bronnen. Dit betekent dat als en wanneer de webpagina opnieuw wordt geladen of een vergelijkbare pagina wordt geladen die veel van dezelfde inhoud gebruikt, die inhoud kan worden aangeboden vanuit de cache in plaats van de webserver. Dit betekent niet alleen dat de webpagina sneller kan laden, maar het vermindert ook de belasting op het web server en vermindert de hoeveelheid gegevens die de gebruiker moet downloaden, wat belangrijk kan zijn bij gemeten verbindingen.
RAM zelf fungeert ook als leescache voor gegevens op de harde schijf. In dit geval worden gegevens voor een actief programma preventief in het RAM geladen, zodat de CPU er sneller toegang toe heeft. Gegevens van het RAM worden vervolgens verder in de cache opgeslagen in de CPU-cache, hoewel het proces hiervoor een stuk ingewikkelder is omdat de CPU-cache wordt gemeten in megabytes en niet in gigabytes.
Schrijf caches
Een schrijfcache is een cache die gegevens kan absorberen die naar een langzamer apparaat worden geschreven. Een bekend voorbeeld hiervan is de SLC-cache in moderne SSD's. Met deze cache kunnen gegevens niet sneller worden gelezen, het is echter veel sneller om naar te schrijven dan naar de TLC- of QLC-flash die de rest van de SSD vormt. De SLC-cache kan schrijfbewerkingen met hoge snelheid absorberen en zet die gegevens vervolgens zo snel mogelijk over naar de TLC-flash die een veel betere opslagdichtheid biedt, maar ook een stuk langzamer is om naar te schrijven. Door het flashgeheugen op deze manier te gebruiken, wordt het geoptimaliseerd voor zowel hoge schrijfsnelheden als een hoge opslagdichtheid.
Hybride caches
Er zijn veel manieren om met caches om te gaan, waardoor ze zowel als lees- als schrijfcache kunnen fungeren. Elk van deze methoden verwerkt schrijfbewerkingen anders en heeft voor- en nadelen. De drie opties zijn omschrijven, doorschrijven en terugschrijven. Een write-around cache slaat de cache volledig over tijdens het schrijven, de write-through cache schrijft naar de cache, maar beschouwt de bewerking pas als voltooid wanneer deze naar de opslag is geschreven. De terugschrijfcache schrijft naar de cache en beschouwt de bewerking vervolgens als voltooid, en vertrouwt op de cache om deze naar de opslag over te brengen als dat nodig is.
Rondschrijven kan handig zijn als u een groot aantal schrijfacties verwacht, omdat het cacheverloop minimaliseert. Het betekent echter wel dat een bewerking die vervolgens een van die geschreven gegevens leest, de eerste keer ten minste één cachefout zal tegenkomen. Write-through-caches cachen schrijfbewerkingen onmiddellijk in de cache, wat betekent dat het resultaat de eerste keer dat het wordt opgevraagd vanuit de cache kan worden weergegeven. Om echter als voltooid te worden beschouwd, moet een schrijfbewerking de gegevens ook naar schijf schrijven, wat vertraging toevoegt. Een terugschrijfcache heeft hetzelfde voordeel als een doorschrijfcache, waardoor geschreven gegevens direct vanuit de cache kunnen worden bediend. Het vereist echter geen schrijfbewerkingen om naar schijf te schrijven om als voltooid te worden beschouwd. Dit vermindert de schrijflatentie, maar brengt het risico van gegevensverlies met zich mee als de cache vluchtig is en de gegevens niet zijn teruggeschreven naar de opslag voordat de stroom uitvalt.
Hoe gegevens uit de cache verwijderen?
Een van de beperkende factoren van elke cache is capaciteit. Een grote cache kost veel tijd om te zoeken, waardoor een groot deel van het voordeel van het gebruik van een cache teniet wordt gedaan. Geheugentechnologieën die worden gebruikt voor caching zijn ook vaak duurder dan het geheugen waaruit ze cachen. Als dit niet het geval was, is het waarschijnlijk dat die geheugenlaag van geheugentechnologie zou zijn veranderd om de prestaties te verbeteren. Beide factoren betekenen dat caches relatief klein zijn, vooral in vergelijking met het opslagmedium waarvan ze cachen. RAM heeft minder capaciteit dan opslag en CPU-cache heeft minder capaciteit dan RAM. De SLC-cache heeft minder capaciteit dan het TLC-geheugen.
Dit alles betekent dat het vaak nodig is om gegevens uit de cache te halen om ruimte vrij te maken voor nieuwe gegevens die in de cache moeten worden opgeslagen. Hier zijn verschillende benaderingen voor. "Minst vaak gebruikt", geeft de voorkeur aan het verwijderen van cache-items met het laagste aantal toegangen. Dit kan handig zijn om te voorspellen welke vermeldingen het minste effect hebben op toekomstige cachemissers, maar zou ook zeer recent toegevoegde items tellen als een laag aantal toegangen, wat kan leiden tot cache karnen.
"Minst recentelijk gebruikt" geeft de voorkeur aan het verwijderen van cache-items die al een tijdje niet zijn gebruikt. Hierbij wordt ervan uitgegaan dat ze momenteel niet worden gebruikt, maar er wordt geen rekening mee gehouden of ze een tijdje geleden intensief zijn gebruikt. "Meest recent gebruikt" geeft er de voorkeur aan om de meest recent gebruikte cache-items te verwijderen, ervan uitgaande dat ze zijn gebruikt en niet opnieuw hoeven te worden gebruikt. De beste aanpak is over het algemeen een combinatie van alle drie, gebaseerd op gebruiksstatistieken.
Verouderde informatie en veiligheidsrisico's
Het grootste risico van caches is dat de informatie die ze bevatten oud kan worden. Een cache-invoer wordt als verouderd beschouwd wanneer de oorspronkelijke gegevens zijn bijgewerkt, waardoor de cache-invoer verouderd is. Het is belangrijk om regelmatig te controleren of de live-kopie die wordt aangeboden nog steeds overeenkomt met de kopie in de cache.
Met name op websites is het ook uiterst belangrijk om te bepalen welke gegevens wel en niet in de cache kunnen worden opgeslagen. Het is bijvoorbeeld prima dat een groot, onveranderlijk JavaScript-bestand in de cache wordt opgeslagen. Dit voorkomt dat de gebruiker het elke keer hoeft te downloaden, en kan zelfs andere gebruikers ten goede komen die door dezelfde cache worden bediend. U kunt echter geen sessiespecifieke gegevens cachen. Stel je voor wat er zou gebeuren als je naar een berichten-app bladerde terwijl je als jezelf was aangemeld, alleen om te ontdekken dat je een gecachte versie van de berichten van een andere gebruiker te zien kreeg. Gelukkig kunnen webservers specificeren welke bronnen wel en niet in de cache kunnen worden opgeslagen en deze problemen zijn over het algemeen bekend, dus er zijn maar weinig problemen zoals deze.
Conclusie
Een cache is een gedeelte van het geheugen dat recent gebruikte gegevens kan opslaan in een opslagmethode die sneller toegankelijk is dan het zou zijn om het normale gegevenstoegangsproces opnieuw te voltooien. Een cache is meestal beperkt in capaciteit, wat betekent dat het gegevens moet verwijderen zodra deze vol is. Caches zijn over het algemeen transparant voor de gebruiker, wat betekent dat latentie de enige indicatie is dat het resultaat via een cache is geleverd.