KeyDB als [potentiële] vervanger voor Redis

Op Habr zijn er geen recensies over de 'snellere alternatieven voor Redis' - KeyDB. Na voldoende recente ervaring met het gebruik ervan, wil ik deze leemte aanvullen.

KeyDB als [potentiële] vervanger voor Redis

De achtergrond is vrij banaal: op een dag werd er tijdens een grote toestroom van verkeer een aanzienlijke degradatie van de prestaties van de applicatie (namelijk de responstijd) geregistreerd. Op dat moment was het helaas niet mogelijk om een normale diagnose uit te voeren, dus plannen we later een reeks belastingstests. Na deze tests ontdekten we de bottleneck, die de databasecache in Redis was. Zoals vaak het geval is, kon het probleem niet onmiddellijk en op de juiste manier worden opgelost door de ontwikkelaars (door de logica van de werking te wijzigen). Daarom werd nieuwsgierigheid en de wens om de situatie op een alternatieve manier op te lossen geactiveerd. Zo is dit artikel ontstaan.

Problemen

Over Redis in het algemeen

Zoals velen weten, is Redis een single-threaded database. Om precies te zijn, is het dat in de context van het werken met gebruikersgegevens. Want vanaf versie vier van Redis zijn de operationele, interne processen vertaald voor parallelle uitvoering. Desondanks heeft deze wijziging slechts een klein deel van de belasting geraakt, aangezien het grootste deel van het werk op gebruikersgegevens ligt.

Over dit onderwerp zijn ontelbare meningen verdeeld, maar de ontwikkelaars van Redis willen ten koste van alles geen volledige paralelisatie doorvoeren, verwijzend naar hoe dit de applicatie zou compliceren en de overhead zou verhogen, evenals het aantal bugs zou vergroten. Hun standpunt is als volgt: als je problemen hebt met single-threaded werking — heb je architecturale problemen met de applicatie en moet je iets aan de architectuur veranderen. Onder de gebruikers is er echter ook een 'andere kant' — van degenen die vastzitten aan één kern en beweren dat Redis zelf de bottleneck creëert. In het geval van echt zware belasting - vroeg of laat - kom je onvermijdelijk met dit probleem in aanraking, wat aanzienlijke beperkingen oplegt aan de architectuur en/of gedwongen complicaties daarin.

Ik ga geen oordeel vellen over welk standpunt dan ook. In plaats daarvan deel ik onze specifieke case en hoe we het hebben opgelost.

Onze case

Bij een van onze projecten stuitten we erop dat het ontwikkelteam een extreem agressieve caching van gegevens uit de database (PostgreSQL) had ingesteld via Redis. Dit was de enige manier waarop PostgreSQL tijdens scherpe verkeerspieken werd gered, en daardoor ook de applicatie.

Na een reeks belastingstests analyseerden we de situatie en ontdekten we dat Redis vastliep op één core (wat ‘in de rij’ wordt genoemd), waarna er een vrij snelle degradatie van de applicatie volgde. Het ‘verdrinken’ volgde een geometrische progressie: zodra de prestatiegrens van Redis werd bereikt, stopte alles met werken.

Het zag er ongeveer zo uit:

KeyDB als [potentiële] vervanger voor Redis

Vanuit New Relic werd het probleem duidelijk geïdentificeerd:

KeyDB als [potentiële] vervanger voor Redis

En hier zijn de statistieken van de operatie krijgen in Redis:

KeyDB als [potentiële] vervanger voor Redis

Nadat we het probleem in detail aan de ontwikkeling hadden overgebracht, bleek dat 'het probleem op dit moment niet kan worden opgelost'. Zo begon de zoektocht naar een oplossing aan de exploitatiezijde, en het antwoord was de eerder genoemde KeyDB.

Echter, voordat we met de review beginnen, is het vermeldenswaard dat in het project standalone Redis wordt gebruikt, omdat de clusteroplossing op basis van Sentinel veel slechter presteert qua latency. Een van de voor de hand liggende oplossingen was het creëren van meerdere cache-replicas: laat de applicatie maar overal naartoe gaan met load balancing! Maar na overleg met de ontwikkelaars waren we genoodzaakt deze optie af te wijzen vanwege het actieve en complexe mechanisme voor cache-invalidatie in de applicatie. Hetzelfde probleem gold voor de sharding van de cache.

Een korte review van KeyDB

Op zoek naar een mogelijke oplossing voor het probleem ontdekten we een applicatie genaamd KeyDB. Dit is een fork van Redis, ontwikkeld door een Canadese onderneming en wordt verspreid onder de vrije BSD-licentie. Het project is vrij jong: het bestaat sinds begin 2019. Het verhaal is dat de auteurs ook ooit tegen de beperkingen van Redis aanliepen… en besloten hun eigen fork te maken. Bovendien loste het niet alleen bekende problemen op, maar kreeg het ook extra functionaliteiten die alleen beschikbaar zijn in de enterprise-versie van Redis.

Voor degenen die meer willen weten over KeyDB is er een goed inleidend artikel op Medium, dat de DBMS voorstelt en korte benchmarks biedt die het vergelijken met zijn 'ouder' – Redis.

Allereerst trok het potentiële oplossing van onze problemen met KeyDB onze aandacht, en we waren ook geïnteresseerd in enkele extra functies. Het gebruik van KeyDB beloofde de volgende voordelen:

  • volledige multithreaded ondersteuning;
  • volledige en absolute compatibiliteit met Redis (voor ons was dit bijzonder belangrijk, aangezien het niet mogelijk was om wijzigingen aan de applicatiezijde aan te brengen), wat ook een probleemloze migratie beloofde;
  • een ingebouwd back-upmechanisme in S3-opslag;
  • eenvoudige active-replicatie implementatie;
  • eenvoudige clustering en sharding zonder Sentinel en andere ondersteunende software.

Meer dan 3000 sterren en talloze bijdragers op GitHub zagen er ook veelbelovend uit. De applicatie wordt actief ontwikkeld en onderhouden, wat duidelijk blijkt uit de commits, interacties in issues en ook gesloten (geaccepteerde) PR's. De respons van de hoofdmaintainer is altijd vriendelijk en snel. Al met al waren er genoeg argumenten.

Migratie en resultaten

Ondanks dat het migratieproject een zekere gok was (vanwege de nieuwheid van KeyDB), viel er weinig te verliezen. Het was immers snel en eenvoudig om wijzigingen terug te draaien — gelukkig is de gehele infrastructuur uitgerold in Kubernetes, en de ingebouwde mechanismen Rolling Update oplossen dergelijke taken uitstekend.

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

De testen begonnen, die ongeveer een week duurden en waarin we niet in detail zijn gegaan. We weten alleen dat de klant de standaardfunctionaliteiten van Redis met behulp van de PHP-driver phpredis, evenals de QA-test van de gebruikersinterface, heeft gecontroleerd. Daarna kregen we groen licht: er werden geen bijwerkingen geconstateerd bij het gebruik van de nieuwe software. Dat wil zeggen, vanuit het perspectief van de applicatie is er helemaal niets veranderd..

Het is vermeldenswaard dat we ook in de configuratie niets hebben gewijzigd: letterlijk — we hebben gewoon het gebruikte image vervangen. Hetzelfde geldt voor monitoring en het exporteren van metrics naar Prometheus: de meest voorkomende daarvan werkt uitstekend met KeyDB en zonder enige aanpassingen. Zo kunnen we gerust zeggen dat het qua exploitatie gewoon een ideale verhuizing is.

Dankzij dit alles kan, na de overstap van de applicatie naar de nieuwe DBMS, alles zoals het is worden gelaten om enige tijd in de praktijk te functioneren als een "stabiliserende maatregel". Echter, als je een prestatiewinst (of überhaupt enige verandering) wilt zien, moet je niet vergeten dat standaard de KeyDB-parameter, die verantwoordelijk is voor multithreading (server-threads), gelijk is aan één, wat betekent dat de DBMS precies zo werkt als Redis..

Na de overstap, testen en enige tijd leven op de nieuwe applicatie (met KeyDB) hebben we besloten om de loadtesting opnieuw uit te voeren met dezelfde parameters die voor Redis werden gebruikt. Wat waren de resultaten?..

In de grafiek van CPU-gebruik was meteen te zien dat de problemen met de "limiet" naar één kern waren opgelost: het proces begon de beschikbare middelen te gebruiken:

KeyDB als [potentiële] vervanger voor Redis

En later heb ik geprobeerd de applicatie behoorlijk stevig te "martelen" en zag ik een gebruik tot wel drie kernen...

Volgens New Relic gedroeg de webapplicatie zich in het algemeen, met dezelfde belasting, veel adequater. Er was nog steeds enige prestatieverslechtering waarneembaar, echter, als je vergelijkt met de vergelijkbare grafiek hierboven, kun je zelf de significante vooruitgang beoordelen:

KeyDB als [potentiële] vervanger voor Redis

De latentie van de nieuwe database (KeyDB) verslechterde ook, maar bleef binnen aanvaardbare waarden:

KeyDB als [potentiële] vervanger voor Redis

In de volgende grafiek is goed te zien dat het aantal verzoeken naar KeyDB vergelijkbaar is:

KeyDB als [potentiële] vervanger voor Redis

Samenvattend bij deze synthetische tests kan worden gezegd dat zowel Redis als KeyDB aanzienlijke prestatieverslechtering vertonen in termen van latentie (40 ms+) bij een significante stijging van het aantal gelijktijdige verbindingen (1000+). In ons geval kon de webapplicatie de latentie van Redis verlagen met een lager aantal verbindingen (400+), hoewel een dergelijke belasting voor KeyDB acceptabel bleef.

Conclusies

In dit voorbeeld is de kracht van de Open Source-gemeenschap duidelijk zichtbaar in de ontwikkeling van projecten waarin zij geïnteresseerd is. Op het internet kwam ik een geweldige uitspraak tegen, waarvan de algemene strekking als volgt was: „Een groot bedrijf creëert een interessant product, maakt een deel van de functies openbaar, maar laat het belangrijkste gedeelte betaald. De gemeenschap maakt er gebruik van, en vervolgens zwaait iemand met de hand en maakt een fork, waarin die betaalde functies worden geïmplementeerd en voor iedereen geopend.” Dat is precies het geval met KeyDB.

Als we het hebben over de migratie zelf, die verrassend soepel verliep, hebben we niet gekregen zo veel substantieel prestatieverbetering die men zou kunnen verwachten, kijkend naar de grafieken van de auteurs van KeyDB… Dit is echter slechts onze specifieke situatie, waarin vele afwijkingen kunnen zijn, waaronder de beruchte applicatiearchitectuur (bijvoorbeeld een enorme hoeveelheid opdrachten krijgen in Redis in plaats van het meer efficiënte alternatief van geaggregeerde verzoeken mget…). Desalniettemin zijn er positieve resultaten behaald, samen met een aantal nuttige functies die we binnenkort zullen implementeren.

Over het geheel genomen ziet KeyDB er veelbelovend uit: naarmate we praktische ervaring opdoen met deze DBMS (waarvan we nog veel moeten verwerven!) en de ontwikkeling van het project zelf, zullen we de mogelijkheid overwegen om het ook in andere situaties toe te passen.

Dit artikel moet echter niet worden beschouwd als een handleiding (en al helemaal geen oproep) om overal Redis in te ruilen voor KeyDB. Ondanks onze positieve ervaring is het duidelijk dat dit geen zilveren kogel is. De situatie was behoorlijk specifiek: het was specifiek gericht op het snel oplossen van een dringend probleem met minimale kosten, en dat heeft zich bewezen. Zal KeyDB nuttig zijn in jouw geval? In ieder geval weet je nu dat zo'n potentiële mogelijkheid bestaat.

P.S.

Lees ook op onze blog:

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster