KeyDB som [potentiel] erstatning for Redis

Der var ikke nogen anmeldelser af "en hurtigere alternativ til Redis" på Habr, KeyDB. Efter at have fået en del friskt erfaring med brugen af det, ønsker jeg at udfylde dette hul.

KeyDB som [potentiel] erstatning for Redis

Baggrunden er ret banal: en dag, hvor der var et stort trafikoverløb, blev der registreret en betydelig nedgang i applikationens ydeevne (specifikt - svartid). På det tidspunkt var det desværre ikke muligt at udføre en ordentlig diagnose af, hvad der skete, derfor planlagde vi efterfølgende en række belastningstest. Efter at have gennemført dem, opdagede vi flaskehalsen, som viste sig at være Redis-databasens cache. Som det ofte er tilfældet, kunne problemet ikke løses straks og på den rigtige måde - af udviklerne (ved at ændre arbejdslogikken). Derfor blev nysgerrigheden vakt, og ønsket om at tackle situationen på en alternativ måde. Sådan kom denne artikel til.

Problematikken

Om Redis generelt

Som mange ved, er Redis en enkelttrådet database. Hvis vi skal være præcise, gælder det i konteksten af at arbejde med brugerdatasæt. For med den fjerde version blev Redis’ service- og interne operationer overført til parallelt udførelse. Ikke desto mindre påvirkede denne ændring kun en lille del af belastningen, da det meste arbejde falder på brugerdatasættene.

Der er skrevet utallige artikler om dette emne, men udviklerne af Redis ønsker ihærdigt ikke at implementere fuld parallelisme og nævner, hvor meget det vil komplisere applikationen og øge overheaden, samt tilføje flere fejl. Deres position er, at hvis du står over for et problem med enkeltkerneydelse - så har du problemer med applikationens arkitektur, og der er behov for at ændre noget i den. Blandt brugerne, dog, er der også "den anden lejr" - fra dem, der er stødt på en enkelt kerne og hævder, at Redis selv skaber flaskehalsen. I tilfælde af virkelig store belastninger - vil man før eller senere uundgåeligt støde på dette problem, hvilket sætter betydelige begrænsninger på arkitekturen og/eller nødvendige komplikationer i den.

Jeg vil ikke vurdere hverken det ene eller det andet synspunkt. I stedet vil jeg dele vores specifikke tilfælde og hvordan vi har løst det.

Vores case

I et af vores projekter stødte vi på, at udviklingsteamet havde indstillet en ekstremt aggressiv caching af data fra databasen (PostgreSQL) via Redis. Dette var den eneste måde, der under pludselige trafikstorme reddede PostgreSQL fra at gå ned, og dermed også applikationen.

Efter en række belastningstest gennemførte vi en analyse af situationen og opdagede, at Redis blev begrænset af et enkelt kerne (det man kalder «i bunken»), hvorefter der fulgte en ret hurtig nedgang i applikationens ydeevne. «Kvælningen» havde en geometrisk progression: så snart Redis nåede sin ydeevnegrænse, stoppede alt med at fungere.

Det så cirka således ud:

KeyDB som [potentiel] erstatning for Redis

Fra New Relic var problemet entydigt identificeret:

KeyDB som [potentiel] erstatning for Redis

Og her er statistikken for operationen get i Redis:

KeyDB som [potentiel] erstatning for Redis

Efter at problemet blev præsenteret i alle detaljer for udviklingen, viste det sig, at «problemet kan ikke løses lige nu». Så begyndte søgningen efter en løsning på driftsiden, og svaret blev den allerede nævnte KeyDB.

Inden vi går i gang med dens gennemgang, skal det nævnes, at der i projektet anvendes standalone Redis, da den klyngebaserede løsning baseret på Sentinel klarer sig meget dårligere med hensyn til latency. En af de åbenlyse løsninger var at oprette flere replikaer af cachen: så kunne applikationen hente data fra alle steder med load balancing! Dog, efter at have drøftet det med udviklerne, blev vi nødt til at forkaste denne mulighed på grund af den aktive og komplekse cache invalidationsmekanisme i applikationen. Den samme problematik gjaldt også for caching-sharding.

Kort gennemgang af KeyDB

I søgningen efter en mulig løsning på problemet opdagede vi en applikation ved navn KeyDB. Dette er en fork af Redis, udviklet af et canadisk firma og distribueres under en fri BSD-licens. Projektet er ret ungt: det har eksisteret siden begyndelsen af 2019. Historien er, at forfatterne også engang stødte på begrænsningerne i Redis... og besluttede at lave deres egen fork. Desuden løste den ikke bare kendte problemer, men fik også yderligere funktioner, der kun er tilgængelige i enterprise-versionen af Redis.

For dem, der ønsker at lære mere om KeyDB, findes der en god introduktionsartikel på Medium, som præsenterer databasen og korte benchmarks, der sammenligner den med sin «forælder» — Redis.

For us, KeyDB initially attracted attention as a potential solution to our issues, and we were also interested in some additional features. Using KeyDB promised the following advantages:

  • full multithreading support;
  • complete and absolute compatibility with Redis (this was particularly important for us, as making any modifications on the application side was not possible), which also promised a smooth migration;
  • an integrated backup mechanism in S3 storage;
  • easy-to-implement active replication;
  • simple clustering and sharding without Sentinel and other auxiliary software.

More than 3,000 stars and numerous contributors on GitHub also looked promising. The application is actively developed and supported, as evidenced by commits, discussions in issues, and closed (merged) PRs. The response from the main maintainer has always been friendly and prompt. In general, there were plenty of arguments in favor.

Migration and results

Even though the migration project was somewhat of an adventure (due to the novelty of KeyDB), there was not much to lose. After all, rolling back the changes is quite quick and simple — fortunately, the entire infrastructure is deployed in Kubernetes, and built-in mechanisms Rolling Update effectively solve such tasks.

In summary, we prepared Helm templates, switched the application in the test environment to the new database, and rolled it all out, handing it over to the client's QA department.

Testing commenced, lasting about a week, and we did not delve into the details. We only know that the client checked the standard Redis functionality using the PHP driver phpredis, and also conducted QA testing of the user interface. After that, we received the green light: no side effects were found when using the new software. In other words, from the application's perspective, nothing has changed at all..

It is worth noting that we did not change anything in the config either: literally — we simply replaced the used image. The same goes for monitoring and exporting metrics to Prometheus: the most widely used one works perfectly with KeyDB without any modifications. Thus, it can be confidently said that from an operational standpoint, this was an ideal migration.

Takket være alt dette kan du efter at have skiftet applikationen til den nye DBMS lade den være i dens nuværende form som en "stabiliserende foranstaltning" for at køre i produktion i et stykke tid. Men hvis du ønsker at se en præstationsforøgelse (eller overhovedet nogen ændringer), skal du huske, at som standard parameteren KeyDB, der er ansvarlig for multithreading (server-threads), er lig med én, hvilket betyder, at DBMS fungerer helt som Redis..

Efter skiftet, testningen og lidt tid med den nye applikation (med KeyDB) besluttede vi at gentage belastningstestningen med de samme parametre, der blev brugt til Redis. Hvad blev resultaterne?

Ifølge grafen for CPU-forbrug blev det straks tydeligt, at problemerne med "taget" i ét kerne blev fjernet: processen begyndte at bruge de tilgængelige ressourcer:

KeyDB som [potentiel] erstatning for Redis

Og senere prøvede jeg at "presse" applikationen ganske meget og så forbruget op til tre kerner...

Ifølge New Relic opførte webapplikationen sig generelt betydeligt mere passende med samme belastning. Der blev stadig observeret en vis degradering af præstationen, men sammenlignet med den tilsvarende graf ovenfor kan du selv vurdere det betydelige fremskridt:

KeyDB som [potentiel] erstatning for Redis

Latency-målingen for den nye database (KeyDB) blev også dårligere, men forblev inden for acceptable grænser:

KeyDB som [potentiel] erstatning for Redis

Det viser sig tydeligt på den næste graf, at antallet af anmodninger til selve KeyDB er det samme:

KeyDB som [potentiel] erstatning for Redis

Sammenfattende på disse syntetiske tests kan det siges, at både Redis og KeyDB viser betydelig præstationsdegradering i latency (40 ms+) med en betydelig stigning i antal parallelle forbindelser (1000+). I vores tilfælde lykkedes det webapplikationen at "nedbringe" latencien for Redis selv ved et lavere antal forbindelser (400+), selvom denne belastning forblev acceptabel for KeyDB.

Konklusioner

I dette eksempel er styrken ved Open Source-fællesskabet tydeligt at se i udviklingen af projekter, som det er interesseret i. På internettet har jeg stødt på en fremragende udsagn, hvis overordnede mening var følgende: "En stor virksomhed laver et interessant produkt, åbner nogle af dets funktioner, men efterlader den vigtigste del som betalingsfunktion. Fællesskabet bruger det, men så er der nogen, der vifter med hånden og laver en fork, der implementerer de betalte funktioner og gør dem disponible for alle." Dette er præcis situationen med KeyDB.

Når det kommer til selve migrationen, som forløb overraskende glat, modtog vi ikke så meget en betydelig stigning i ydeevne, som man kunne forvente ved at se på forfatternes diagrammer af KeyDB... Men dette er kun vores tilfælde, som kan have mange afvigelser, herunder og især den berygtede applikationsarkitektur (for eksempel det enorme antal kommandoer get i Redis i stedet for mere effektive aggregerede forespørgsler mget…). Ikke desto mindre har vi opnået positive resultater, samt en række nyttige funktioner, som vi stadig skal implementere i den nærmeste fremtid.

Generelt ser KeyDB lovende ud: som vi får praktisk erfaring med denne DBMS (som vi stadig kun skal opnå!) og udviklingen af selve projektet, vil vi overveje dets anvendelse i andre situationer.

Men denne artikel bør ikke betragtes som en guide (og slet ikke et opfordring) til at fjerne Redis til fordel for KeyDB. På trods af vores positive erfaring er det åbenlyst, at det ikke er en sølvkugle. Tilfældet var meget specifikt: specifikt for at løse et akut problem i en situation, hvor det skulle gøres hurtigt og med minimale omkostninger, har denne løsning været berettiget. Vil KeyDB være nyttigt i dit tilfælde? I det mindste ved du nu, at en sådan potentiel mulighed eksisterer.

P.S.

Læs også på vores blog:

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster