KeyDB als [potentiële] vervanging voor Redis

Er waren geen beoordelingen over een “snellere alternatief voor Redis” op Habr — SleutelDBOmdat ik inmiddels de nodige ervaring heb opgedaan met het gebruik ervan, wil ik deze lacune graag opvullen.

KeyDB als [potentiële] vervanging voor Redis

De achtergrond is vrij triviaal: ooit, met een grote toestroom aan dataverkeer, werd een aanzienlijke verslechtering van de applicatieprestaties (namelijk de responstijd) geregistreerd. Helaas was het toen niet mogelijk om een ​​normale diagnose te stellen van wat er aan de hand was, dus werden er vervolgens een reeks belastingstests gepland. Na de implementatie ervan kon een knelpunt worden gedetecteerd: de databasecache in Redis. Zoals vaak gebeurt, kon het probleem niet direct en op de juiste manier worden opgelost – door de ontwikkelaars (door de werklogica aan te passen). Daarom ontstond nieuwsgierigheid en de wens om de situatie via een omweg te overwinnen. Zo is dit artikel ontstaan.

Problemen

Over Redis in het algemeen

Zoals velen weten, is Redis een single-threaded database. Om preciezer te zijn, dit is het geval in de context van het werken met gebruikersgegevens. Immers, sinds de vierde versie, de service, de interne werking van Redis vertaald naar parallelle uitvoering. Deze wijziging had echter slechts betrekking op een klein deel van de werklast, aangezien het grootste deel van het werk wordt gedaan met gebruikersgegevens.

Er zijn talloze lansen gebroken over dit onderwerp, maar de Redis-ontwikkelaars willen koppig geen volledige parallelliteit implementeren. Ze wijzen erop hoe complex het de applicatie zal maken en de overheadkosten zal verhogen, en bovendien een aantal bugs zal toevoegen. Hun standpunt is als volgt: als je een single-core-probleem tegenkomt, heb je problemen met de applicatiearchitectuur en moet er iets aan worden veranderd. Onder gebruikers is er echter ook een "ander kamp" - degenen die vastzitten aan één core en beweren dat Redis een bottleneck voor zichzelf creëert. Bij echt grote belastingen is een botsing met dit probleem vroeg of laat onvermijdelijk, wat aanzienlijke beperkingen aan de architectuur oplegt en/of complicaties daarin forceert.

Ik zal deze of gene mening niet beoordelen. In plaats daarvan deel ik ons ​​specifieke geval en hoe we dat hebben opgelost.

Onze zaak

In een van de projecten kwamen we erachter dat het ontwikkelteam extreem agressieve caching van gegevens uit de database (PostgreSQL) via Redis had ingesteld. Dit was de enige manier om PostgreSQL zelf, en daarmee de applicatie, te redden van de ondergang tijdens plotselinge pieken in het dataverkeer.

Na een reeks belastingstests analyseerden we de situatie en ontdekten dat Redis beperkt was tot één core (de zogenaamde "shelf"), waarna de applicatie vrij snel degradeerde. De "choking" verliep volgens een geometrische progressie: zodra Redis zijn prestatielimiet bereikte, stopte alles met werken.

Het zag er ongeveer zo uit:

KeyDB als [potentiële] vervanging voor Redis

New Relic heeft het probleem duidelijk geïdentificeerd:

KeyDB als [potentiële] vervanging voor Redis

En hier zijn de statistieken voor de operatie get in Redis:

KeyDB als [potentiële] vervanging voor Redis

Nadat het probleem gedetailleerd aan de afdeling ontwikkeling was gemeld, bleek dat "het probleem momenteel niet opgelost kon worden". Dus begon de zoektocht naar een oplossing aan de operationele kant, en het antwoord was de al genoemde KeyDB.

Voordat we het echter gaan bekijken, is het belangrijk om te vermelden dat het project gebruikmaakt van standalone Redis, aangezien de clusteroplossing op basis van Sentinel aanzienlijk slechter presteert qua latentie. Een van de voor de hand liggende oplossingen was om meerdere cachereplica's te creëren: en de applicatie overal heen te laten gaan met balancering! Na overleg met de ontwikkelaars moesten we deze optie echter laten varen vanwege het actieve en complexe mechanisme van cache-invalidatie in de applicatie. Hetzelfde probleem deed zich voor bij cache-sharding.

Een snel overzicht van KeyDB

Op zoek naar een mogelijke oplossing voor het probleem ontdekten we een applicatie genaamd KeyDBDit is een fork van Redis, ontwikkeld door Canadees bedrijf en gedistribueerd onder een free BSD-licentie. Het project is vrij jong: het bestaat al sinds begin 2019. De geschiedenis ervan is zo dat de auteurs ook ooit de beperkingen van Redis tegenkwamen... en besloten hun eigen fork te maken. Bovendien loste het niet alleen de bekende problemen op, maar kreeg het ook extra functies die alleen beschikbaar zijn in de enterpriseversie van Redis.

Voor degenen die meer willen leren over KeyDB, is er een goede inleidend artikel op Medium, waarin de DBMS en korte benchmarks worden gepresenteerd, waarin deze worden vergeleken met zijn ‘moedersysteem’ Redis.

Allereerst werden we aangetrokken door KeyDB vanwege de potentiële oplossing voor onze problemen, en tegelijkertijd waren we geïnteresseerd in een aantal extra functies. Het gebruik van KeyDB beloofde de volgende voordelen:

  • volledige multithreading verkrijgen;
  • volledige en absolute compatibiliteit met Redis (dit was voor ons vooral belangrijk, omdat het niet mogelijk was om wijzigingen aan te brengen in de applicatie), wat ook een probleemloze migratie beloofde;
  • ingebouwd back-upmechanisme naar S3-opslag;
  • eenvoudig te implementeren actieve replicatie;
  • eenvoudige clustering en sharding zonder Sentinel en andere hulp-software.

Meer dan 3 sterren en veel bijdragers op GitHub zagen er ook bemoedigend uit. De applicatie wordt actief ontwikkeld en ondersteund, wat duidelijk zichtbaar is in commits, communicatie in issues en gesloten (geaccepteerde) PR's. De reactie van de hoofdbeheerder is op alle fronten altijd vriendelijk en snel. Over het algemeen waren er genoeg argumenten.

Migratie en resultaten

Hoewel het migratieproject een beetje een gok was (vanwege de nieuwigheid van KeyDB), was er niets te verliezen. Het terugdraaien van wijzigingen gaat immers vrij snel en eenvoudig – gelukkig is de volledige infrastructuur geïmplementeerd in Kubernetes en werken de ingebouwde mechanismen Rollende update zulke problemen perfect oplossen.

In het algemeen hebben we Helm-sjablonen voorbereid, de applicatie in de testomgeving overgezet naar de nieuwe database en alles uitgerold. Vervolgens hebben we het overgedragen aan de QA-afdeling van de klant.

Het testen begon, wat ongeveer een week duurde en we zijn niet in details getreden. We weten alleen dat de klant de standaardfuncties voor Redis heeft getest met behulp van de PHP-driver. phpredis, en voerden ook QA-tests uit van de gebruikersinterface. Daarna kregen we groen licht: er werden geen bijwerkingen gevonden bij het gebruik van de nieuwe software. Dat wil zeggen, vanuit het oogpunt van de applicatie is er helemaal niets veranderd.

Het is belangrijk om op te merken dat we ook niets aan de configuratie hebben gewijzigd: we hebben letterlijk alleen de gebruikte afbeelding vervangen. Hetzelfde geldt voor het monitoren en exporteren van metrics naar Prometheus: de meest voorkomende daarvan Werkt perfect met KeyDB en zonder enige aanpassingen. Vanuit operationeel oogpunt is dit dus een ideale stap.

Dankzij dit alles kunt u, na het overschakelen van de applicatie naar een nieuw DBMS, deze laten zoals hij is en een tijdje in de strijd blijven als een "stabilisatiemaatregel". Als u echter een productiviteitsverhoging wilt zien (of überhaupt veranderingen), mag u niet vergeten dat standaard KeyDB-parameter verantwoordelijk voor multithreading (server-threads), is gelijk aan één, dat wil zeggen, Het DBMS werkt precies hetzelfde als Redis.

Na enige tijd de nieuwe applicatie (met KeyDB) te hebben omgeschakeld, getest en gebruikt, besloten we de belastingtests te herhalen met dezelfde parameters als voor Redis. Wat waren de resultaten?

Uit de grafiek van het CPU-verbruik bleek meteen dat de problemen met het 'plafond' van één kern waren opgelost: het proces begon de beschikbare bronnen te gebruiken:

KeyDB als [potentiële] vervanging voor Redis

En later heb ik de applicatie flink geprobeerd te 'martelen' en zag ik een verbruik van wel drie cores...

Volgens New Relic begon de webapplicatie als geheel, met dezelfde belasting, merkbaar beter te presteren. Er werd nog steeds enige prestatieverslechtering waargenomen, maar door de vergelijkbare grafiek hierboven te vergelijken, kunt u de significante vooruitgang zelf beoordelen:

KeyDB als [potentiële] vervanging voor Redis

De latentie van de nieuwe database (KeyDB) nam ook toe, maar bleef binnen acceptabele grenzen:

KeyDB als [potentiële] vervanging voor Redis

Uit de volgende grafiek blijkt duidelijk dat het aantal verzoeken aan KeyDB zelf vergelijkbaar is:

KeyDB als [potentiële] vervanging voor Redis

Samenvattend kunnen we stellen dat zowel Redis als KeyDB een significante prestatievermindering in latentie (40 ms+) laten zien bij een significante toename van het aantal parallelle verbindingen (1000+). In ons geval slaagde de webapplicatie erin de latentie van Redis te "verlagen", zelfs met een lager aantal verbindingen (400+), hoewel een dergelijke belasting voor KeyDB acceptabel bleef.

Bevindingen

Dit voorbeeld laat duidelijk de macht van de open source-community zien bij het ontwikkelen van projecten waarin ze geïnteresseerd is. Ik kwam een ​​geweldige uitspraak tegen op internet, waarvan de algemene betekenis als volgt was: "Een groot bedrijf creëert een interessant product, maakt een aantal functies open, maar laat het belangrijkste deel betaald. De community gebruikt het en gebruikt het, en dan geeft iemand het op en maakt een fork, implementeert diezelfde betaalde functies erin en maakt ze beschikbaar voor iedereen." KeyDB is precies zo'n geval.

Als we het over de migratie zelf hebben, die verrassend eenvoudig verliep, kregen we geen zo veel een aanzienlijke prestatieverbetering, die mag worden verwacht als je kijkt naar de grafieken van de auteurs van KeyDB... Dit is echter alleen ons specifieke geval, waarin er veel afwijkingen kunnen zijn, waaronder die welke verband houden met de beruchte applicatiearchitectuur (bijvoorbeeld een enorm aantal opdrachten get in Redis in plaats van de efficiëntere optie voor geaggregeerde query's mget…). Desondanks zijn we erin geslaagd positieve resultaten te behalen, en daarmee ook veel nuttige functies die we pas in de nabije toekomst zullen implementeren.

Over het geheel genomen ziet KeyDB er veelbelovend uit. Naarmate we meer praktische ervaring opdoen met dit DBMS (en dat valt nog te winnen!) en het project zelf zich ontwikkelt, zullen we de mogelijkheid overwegen om het in andere situaties in te zetten.

Dit artikel moet echter niet worden gezien als een handleiding (laat staan ​​een oproep) om Redis volledig te verlaten ten gunste van KeyDB. Ondanks onze positieve ervaring is het duidelijk dat dit geen wondermiddel is. De casus was zeer specifiek: specifiek voor het oplossen van een acuut probleem in een situatie waarin het snel en met minimale kosten moest gebeuren, was deze oplossing gerechtvaardigd. Is KeyDB in uw geval nuttig? Nu weet u in ieder geval dat zo'n potentiële mogelijkheid bestaat.

PS

Lees ook op onze blog:

Bron: www.habr.com

Koop betrouwbare hosting voor sites met DDoS-bescherming, VPS VDS-servers 🔥 Koop betrouwbare websitehosting met DDoS-bescherming, VPS- en VDS-servers | ProHoster