Kontakt os

Du har brug for en server-side cache, du har læst to sammenligningssider, og begge konkluderede, at det kommer an på situationen. Meget hjælpsomt. Lad os derfor få afklaret spørgsmålet om Redis vs. Memcached med det samme: Memcached er det bedste valg, når du ønsker en enkel, hurtig cache og intet andet, mens Redis er det bedste valg, når cachen skal indeholde strukturerede data, overleve en genstart eller aflaste din applikation.
Både Redis og Memcached er:
Det er her, de fleste artikler stopper. Denne artikel fortsætter, for de interessante forskelle begynder først herefter.
Begge gemmer data i hukommelsen for at gøre applikationer hurtigere. De er blot rettet mod forskellige udfordringer.
Memcached er enkelt. Det tilbyder grundlæggende key-value-lagring og er fremragende til hurtig caching af data takket være sin multithreaded ydeevne.
Redis understøtter mere komplekse datatyper og permanent datalagring, hvilket gør det alsidigt til en bredere vifte af opgaver som f.eks. messaging og sessionsstyring. Det tilbyder også avancerede muligheder som datasharding, hvor et datasæt fordeles på tværs af flere servere, så ingen enkelt maskine indeholder det hele, samt et udvalg af eviction-politikker.
Med udgangspunkt i et projekt, vi har udviklet for en kunde, vil jeg gennemgå, hvordan de håndterer datalagring og skalerbarhed, samt hvilken der performer bedst i forskellige scenarier. Først det grundlæggende.
Redis, som står for Remote Dictionary Server, blev skabt i 2009 af Salvatore Sanfilippo for at forbedre skalerbarheden af den weblog-analysator, hans italienske startup var ved at udvikle. Den første prototype blev skrevet i Tcl og senere omskrevet til C. Da Sanfilippo gjorde projektet open source, begyndte det at vinde frem. GitHub og Instagram var blandt de første virksomheder, der tog det i brug, og projektets egen dokumentation er stadig referencen for dets funktionalitet og begrænsninger.
Memcached kom lidt tidligere, i 2003, og blev bygget af Brad Fitzpatrick til hans LiveJournal-hjemmeside. Det blev oprindeligt udviklet i Perl og derefter oversat til C. Nogle af verdens største virksomheder bruger det, herunder Facebook, YouTube og Twitter, og dets virkemåde er dokumenteret i Memcached-wikien.

Redis er ikke bare en key-value-store; det er en server til datastrukturer. De fem, du oftest vil få brug for, er:
Udover disse indeholder den også bitmaps, bitfields, HyperLogLogs (probabilistiske tællere) og geospatiale indeks, samt streams til append-only logs. JSON, forespørgsler, tidsserier og — fra Redis 8 — vektorsæt tilføjes via moduler (dokumentation for Redis-datatyper). Det er langt fra bare "nøgler og strenge", og netop denne bredde er grunden til, at Redis kan bruges i situationer, hvor en almindelig cache ikke slår til.
Redis understøtter operationer på datatyper, hvilket betyder, at du kan læse eller ændre en del af et objekt uden at skulle indlæse det hele i din applikation, redigere det og gemme det igen.
Til hukommelseshåndtering bruger den en indkapslet version af malloc/free, som er standardmekanismen i C til at anmode om og frigive hukommelse. Det er enklere end Memcacheds Slab-mekanisme, som jeg kommer ind på herunder.
Nøgler kan være op til 512 MB, og det samme gælder værdier, som beskrevet i dens dokumentation for datatyperFor samlede datatyper som lister og sæt gælder denne grænse pr. element.
Memcached har ingen datatyper. Den gemmer strenge indekseret af en strengnøgle, og den bruger mindre hukommelse end Redis til dette formål.
Den er også begrænset af hukommelsen på den maskine, den kører på. Når den er fuld, begynder den at slette værdier efter princippet om mindst nyligt anvendte (LRU). Dens allokeringsmekanisme, Slab, opdeler hukommelsen i bidder af forskellig størrelse og gemmer hver nøgle-værdi-post i den bid, der passer. Det er det, der forhindrer hukommelsen i at fragmentere i huller, der er for små til at blive genbrugt.
Nøgler har en øvre grænse på 250B og værdier på 1MB. Det er dog standardindstillinger, og du kan øge den maksimale slab-størrelse ved opstart (se Memcached-wiki).
Tænk på et cachelagret objekt som en frakke, der afleveres i en garderobe. Med Memcached kan du kun hente hele frakken: For at ændre indholdet i en lomme skal strengen indlæses, deserialiseres, feltet redigeres, serialiseres og gemmes igen.
Redis lader dig række ned i lommen. Hash-datatypen giver dig adgang til hvert felt individuelt, så enhver CRUD-operation (opret, læs, opdater, slet) kun kører mod det pågældende felt. Én netværks-roundtrip, til omtrent samme pris som en almindelig get eller set, erstatter fire udvekslinger og to serialiseringstrin.
Her er den samme sessionsopdatering på begge måder:
# Memcached — the whole session object is the unit of work
value = mc.get("session:42") # 1. fetch the whole blob
session = deserialise(value) # 2. deserialise in app memory
session["last_seen"] = now() # 3. edit one field
mc.set("session:42", serialise(session)) # 4. serialise + write it all back
# → 2 network round trips, 2 (de)serialisation steps, in your app code
# Redis — the field is the unit of work
HSET session:42 last_seen <now> # one round trip, no (de)serialisation
# → the read-modify-write collapses into a single command on the serverÅrsagen til, at dette virker, er ikke specifik for vores projekt. Redis' egen dokumentation og uafhængige benchmarks viser, at det er reduktionen af netværks-roundtrips frem for hastigheden på kommandoer, der øger gennemløbet – se afsnittet om ydeevne nedenfor for tallene.

Redis er overvejende single-threaded, hvilket betyder, at én kerne udfører kommandoerne, uanset hvor mange maskinen har. (Threaded I/O blev introduceret i Redis 6, og Redis 8 samt Valkey-forken har videreudviklet I/O-multithreading – men selve kommandoerne kører stadig på én tråd; AWS bemærker den samme skelnen mellem single-threaded og I/O-multithreading i deres Sammenligning af ElastiCache-motorer.) Med indbygget clustering-understøttelse skalerer den i stedet effektivt horisontalt.
Clustering fungerer via en master/slave-arkitektur, hvor én node modtager skrivninger, mens de andre indeholder kopier af dataene. Hver master har to slaver for redundans, så hvis masteren svigter, forfremmer systemet automatisk en af dem. Prisen er vedligeholdelse: Det er sværere at holde flere synkront kørende noder sunde end blot én.
Memcached skalerer let vertikalt, fordi den er multithreaded. Giv den flere kerner og mere hukommelse, så er opgaven løst.
Den skalerer også horisontalt på klientsiden via en distribueret algoritme, som du selv implementerer. Det kræver mere arbejde end Redis, som leveres med clustering direkte ud af boksen.
Den største forskel på de to er, hvad der overlever en genstart. Redis er (for det meste) en in-memory datalagring, der ikke er flygtig. Memcached er en in-memory cache, der er flygtig: genstart processen, og indholdet er væk.
Redis understøtter persistens – hvilket er grunden til, at det kaldes en datalagring – på to måder (Dokumentation for Redis-persistens):
En underproces håndterer disse filer, og den detalje afgør, hvilken du bør vælge.
Er et stort datasæt et problem? For RDB, ja. Det tager tid at oprette filen, hvilket kan ses på svartiderne, selvom den indlæses hurtigere ved opstart end AOF-loggen.
Vælg AOF, hvis datatab er uacceptabelt. Den kan opdateres ved hver kommando, og da den kun tilføjer data, opstår der ingen problemer med korruption. Den fylder dog også meget mere end et RDB-snapshot.
Intet, helt bevidst. Intet snapshot, ingen log. En genstart, et nedbrud eller en failover starter med en tom cache, og den første bølge af forespørgsler bagefter går direkte videre til databasen.
Det er fint, når cachen indeholder afledte data, der er billige at genberegne. Det bliver et problem for kapacitetsplanlægningen, når de ikke er.
Memcached er begrænset til LRU-rydningspolitikken (least recently used), mens Redis understøtter otte (Dokumentation for Redis-nøglerydning):
Det, du får ud af det, er kontrol. Med Memcached bestemmer LRU, og det må du leve med. Med Redis kan du beskytte de nøgler, der ikke må forsvinde, og lade alt andet blive slettet omkring dem.
Det er typisk her, sammenligningssider erstatter beviser med påstande. Lad os bruge tal i stedet.
Redis offentliggør sine egne gennemløbstal. Deres benchmark-dokumentation rapporterer, at en Linux-server på indgangsniveau, der kører en enkelt Redis-instans, håndterer i omegnen af 100.000 forespørgsler i sekundet med små payloads ved en latenstid på under et millisekund på et lokalt netværk. Det loft tilhører én kerne. Kommandoafvikling er single-threaded, så tilføjelse af flere kerner til maskinen løfter det ikke. Redis 6 tilføjede threaded I/O, som paralleliserer socket-læsninger og -skrivninger, men selve kommandoerne kører stadig på én tråd.
Memcached er multithreaded fra ende til anden, så gennemløbet stiger i takt med antallet af kerner, indtil netværksinterfacet er mættet. Det er hele deres ydelsesfordel, og den er reel: På en maskine med mange kerner, der serverer store, simple værdier, flytter Memcached mere data pr. sekund, end en enkelt Redis-proces kan. Det er grunden til, at AWS dokumenterer de to forskelligt, selv inden for den samme administrerede tjeneste – deres eget whitepaper bemærker, at Memcached "udnytter større [instans]-størrelser med flere kerner godt," mens Redis administreres mere som en stateful database (Memcached vs. Redis: Ydelse i stor skala med Amazon ElastiCache).
To forbehold betyder mere end overskriftstallene. For det første er en Redis-implementering sjældent én proces, og sharding på tværs af instanser vinder fordelen ved flere kerner tilbage til prisen for vedligeholdelse af klyngen. For det andet er operationer pr. sekund den forkerte målestok, når én Redis-kommando erstatter flere applikations-roundtrips. En opdatering af et hash-felt er én netværksudveksling, hvor Memcached kræver en læsning, en deserialisering, en skrivning og en serialisering. Redis kan være langsommere pr. operation og stadig komme først i mål.
Det er ikke kun vores egen erfaring, der taler; mekanismen er dokumenteret og målbar. Da hver kommando er en netværks-roundtrip, er det roundtrip-tiden – ikke kommandoafviklingen – der normalt begrænser gennemløbet. Redis' egen pipelining-guide gør pointen klar: På en forbindelse med 250 ms roundtrip-tid bliver en server, der er i stand til 100.000 forespørgsler pr. sekund, stadig begrænset til cirka fire pr. sekund, indtil du holder op med at betale for en roundtrip pr. kommando. Uafhængige benchmarks viser gevinstens størrelse: I en meget citeret test kørt på DigitalOcean-infrastruktur, øgede eliminering af roundtrips en standard redis-benchmark fra ca. 97.000 GET/s til ca. 1,35 millioner GET/s – en gevinst på ~14x, der udelukkende kom fra at fjerne netværksudvekslinger, ikke fra hurtigere kommandoer. Det er den samme løftestang, som vores ændring af session-objekter trak i, blot i en anden form: én hash-kommando i stedet for en læsning, en deserialisering, en redigering, en serialisering og en skrivning. (Pipelining samler mange kommandoer; hash-typen samler én læs-modificer-skriv-proces – forskellige teknikker, identisk princip: færre ture over netværket.)
Reglen er derfor: Memcached til et stort antal uafhængige læsninger af hele værdier på en stor maskine. Redis, hvor datastrukturen gør det muligt at udføre færre, smartere operationer.
Tre situationer retfærdiggør de operationelle omkostninger, og de deler en fællesnævner: Cachen udfører noget, som dine applikationsservere ellers ville skulle gøre.
Memcached passer, når cachen reelt er en cache: værdier, der skrives som helhed, læses som helhed og kan tåle at gå tabt.
Her er den del, der sjældent kommer med på en sammenligningsside. Vi kalder det exit-cost-testen: Før du vælger en cache, så spørg dig selv, hvad det vil koste at forlade den igen. De to svar er ikke symmetriske.
Hos Imaginary Cloud har vi brugt begge dele i mange forskellige kundeprojekter. I et af dem, jeg var involveret i, skulle vi vælge mellem dem. Vi startede med Memcached på grund af dens enkelhed, brugervenlighed og nemme opsætning, og fordi vi blot havde brug for en cache, så persistens var ikke et krav. Efter lidt test skiftede vi til Redis for at få fordelene ved datatyper.
Operationerne for datatyper passede til den type data, vi lagrede. Redis tilbyder også en kommando til at søge efter nøgler, der matcher et mønster, sammen med mange andre kommandoer til at arbejde med nøgler, og det viste sig at være den funktion, vi hele tiden vendte tilbage til. Det var den afgørende faktor for migreringen.
Selve migreringen var ligetil, da Redis understøtter de fleste af de kommandoer, som Memcached gør. Peg klienten mod den nye cache, lad cachen fylde op, og fortsæt.
At gå den anden vej er en helt anden sag. Memcached har ingen datatyper, så hver eneste Redis-datatypekommando skal oversættes til flere Memcached-kommandoer med databehandling imellem for at opnå det samme resultat. Den logik ender tilbage i den applikationskode, du ellers lige havde flyttet den ud af.
Denne asymmetri er testen. Start på Memcached, og du bevarer en billig vej til Redis. Start på Redis, opdag at du kun havde brug for en simpel cache, og du skal til at omskrive applikationslogikken for at komme tilbage. Når kravene er reelt usikre, bør exit-omkostninger vægte højere end nogen benchmark.
Redis er mere fleksibel og har flere funktioner. Memcached tjener stadig visse formål rigtig godt og præsterer i nogle tilfælde bedre, fordi multi-threading giver pote, når du flytter store mængder simple data.
Redis understøtter dataoperationer takket være sine datatyper, og de reducerer både antallet af netværks-I/O og de involverede datastørrelser. En opdatering af et hash-felt koster omtrent det samme som et almindeligt get eller set, så arbejdet bliver udført uden at belaste din applikation med ekstra tid på netværket.
Så, er der en vinder? Nej, selvfølgelig ikke. Anvend ydelsesreglen og derefter exit-omkostningstesten. Vælg Memcached til store mængder uafhængige læsninger af hele værdier på en stor maskine. Vælg Redis, hvor datastrukturen gør det muligt at udføre færre og smartere operationer. Når de to ligger tæt op ad hinanden, så vælg den, der er billigst at forlade. Vores erfaring er, at det at afveje fordele og ulemper fra starten er det, der sparer dig for en migrering midt i projektet.
Hvis du godkender arkitekturen frem for at skrive den, kan den tekniske sammenligning koges ned til tre kommercielle spørgsmål. Vi bruger dem på alle infrastruktur- og stack-valg, ikke kun caching.
1. Hvad koster det at køre? Memcached har et lavere hukommelsesforbrug pr. element, så det samme datasæt kan være i en mindre instans. Redis koster mere pr. gigabyte cache, når persistens og replikering er aktiveret, fordi et RDB-snapshot kræver ekstra plads til den forked child-proces, og en replikeret klynge mangedobler antallet af instanser. En lille forskel ved et par gigabyte. Mærkbar ved et par hundrede.
2. Hvem har ansvaret mandag morgen? En enkelt Memcached-instans kræver stort set ingen vedligeholdelse. En Redis-klynge med master- og replika-noder, failover og finjustering af persistens er et system, som nogen skal tage ejerskab over: overvåge det, teste failover og dimensionere snapshot-vinduet. Hvis den person ikke findes i dit team, er de ærlige muligheder en managed service eller Memcached. ElastiCache eller MemoryDB flytter arbejdet over til udbyderen og lægger det på fakturaen i stedet, hvilket normalt er den rette afvejning for et lille team.
3. Hvad er licens- og kontinuitetsrisikoen? I marts 2024 skiftede Redis fra BSD-licensen til en source-available dual-model (RSALv2 og SSPLv1), hvilket fik Linux Foundation til at forke den sidste BSD-udgivelse (7.2.4) som Valkey. I maj 2025 tilføjede Redis 8 AGPLv3 — en OSI-godkendt open source-licens — ved siden af de source-available muligheder, så Redis udgives nu igen under en tri-licens, og Salvatore Sanfilippo var vendt tilbage til virksomheden året før. Forken bestod alligevel: AWS markerer selv, at Redis 8.0 Community Edition er AGPLv3 (en copyleft-licens, som mange organisationer ikke tillader), mens Memcached forbliver BSD, og de anbefaler nu Valkey til nye ElastiCache-workloads (AWS: Sammenlign Redis og Memcached). Episoden er en påmindelse om, at Redis er en afhængighed med en kommerciel ejer og en licens, der allerede har ændret sig under pres. Memcached har været BSD hele vejen igennem uden en sådan historik. For de fleste teams er det ikke en hindring. For alle, der indlejrer en cache i et produkt, de videredistribuerer — hvor AGPL-copyleft-klausulen bider — er det et spørgsmål, der skal besvares, før koden skrives, og Valkey er den tilladende udvej, der er værd at kende til.
Time-to-value taler normalt for at starte enkelt. Memcached er hurtigere at sætte op, og som exit-omkostningstesten viser, er det billigt at skifte til Redis senere. Det omvendte er ikke tilfældet.
Ikke nødvendigvis. Ved små værdier er de tæt på hinanden pr. operation, og Redis leverer en gennemstrømning på omkring 100.000 forespørgsler i sekundet for en enkelt instans på hardware i basisklassen. Memcached er multithreaded, så på en maskine med mange kerner, der håndterer store, simple værdier, flytter den mere data pr. sekund. Redis vinder, hvor dens datatyper erstatter flere applikations-roundtrips med én kommando.
Ja, når kravet reelt er en cache. Flygtige data, simple værdier, intet behov for persistens og rigeligt med kerner: Memcached er enklere at køre, billigere i hukommelsesforbrug og har næsten ingen operationel kompleksitet.
Ja, og det er den nemmeste retning, hvilket er hele pointen med exit-cost-testen. Redis understøtter de fleste af de kommandoer, som Memcached gør, så i praksis peger du blot klienten om og lader cachen genopfylde. At gå den anden vej betyder, at man skal omskrive datatype-operationer til flere Memcached-kommandoer plus behandling på applikationssiden.
Nej. Memcached er en flygtig in-memory cache: Genstarter du den, er indholdet væk. Redis bevarer data via RDB-snapshots, point-in-time dumps til disk eller en AOF-log, der afspiller hver skrivekommando ved opstart.
Memcached, når man ser på infrastrukturomkostningerne, takket være lavere hukommelsesforbrug pr. element og enkelheden ved en enkelt instans. Redis koster normalt mere, når replikering og persistens er aktiveret. Regnestykket ændrer sig, hvis Redis aflaster dine applikationsservere eller din database, da den besparelse kan opveje forskellen i cache-udgifter.
Redis understøtter clustering indbygget med master- og replika-noder samt automatisk failover. Memcached distribuerer på klientsiden ved hjælp af en sharding-algoritme, som du selv implementerer. Managed services tilbyder begge dele – og for nye implementeringer bruger ElastiCache og Memorystore nu som standard Valkey-forken med BSD-licens, hvilket generelt er den fornuftige vej for teams uden en dedikeret platform-ingeniør.
I stigende grad, ja – det er grunden til, at denne sammenligning har fået et tredje navn siden 2024. Valkey er Linux Foundations BSD-licenserede fork af Redis 7.2.4, som er API-kompatibel og nu standarden hos de store managed services. Hvis din eneste tøven omkring Redis er licensen, fjerner Valkey den uden at ændre måden, du skriver mod cachen på.
Skal du beslutte, hvilken cache din arkitektur skal bygges på? Vi hjælper ingeniørteams med at vælge infrastruktur, som de har råd til at køre, og – lige så vigtigt – har råd til at udskifte senere. Tal med vores team om, hvor dit system er på vej hen.

Webudvikler på Imaginær sky, der er begejstret for Node.js og alt relateret til back-end udvikling.

CEO @ Imaginary Cloud og medforfatter af bogen Product Design Process. Jeg nyder mad, vin og Krav Maga (ikke nødvendigvis i denne rækkefølge).
People who read this post, also found these interesting: