KeyDB ca [potențială] alternativă la Redis

Pe Habr nu s-au găsit recenz i "alternativă mai rapidă la Redis" — KeyDB. Obținând experiența necesară în utilizarea sa, am dorit să completez această lacună.

KeyDB ca [potențială] alternativă la Redis

Povestea de fundal este destul de banală: odată, în momentul unui aflux mare de trafic, a fost observată o degradare semnificativă a performanței aplicației (mai exact — a timpului de răspuns). Din păcate, atunci nu am reușit să facem o diagnosticare corectă a celor întâmplate, așa că am planificat ulterior o serie de teste de stres. După efectuarea lor, am reușit să descoperim punctul slab, care s-a dovedit a fi cache-ul bazei de date în Redis. Așa cum se întâmplă adesea, problema nu putea fi rezolvată pe loc și pe calea corectă — prin intervenția dezvoltatorilor (modificarea logicii de funcționare). De aceea, a început curiozitatea și dorința de a aborda situația pe o cale ocolitoare. Așa a apărut acest articol.

Problematica

Despre Redis în general

După cum știe toată lumea, Redis este o bază de date unithread. Așa că, dacă dorim mai multă precizie, este așa în contextul lucrului cu datele utilizatorilor. Deoarece din versiunea a patra, operațiunile interne și de serviciu ale Redis am tradus au execuție paralelă. Cu toate acestea, această modificare a afectat doar o mică parte din sarcină, deoarece majoritatea activității se concentrează pe datele utilizatorilor.

Despre acest subiect s-au scris o multitudine de articole, dar dezvoltatorii Redis sunt hotărâți să nu implementeze o paralelism complet, menționând cât de mult va complica aplicația și va crește costurile indirecte, precum și va adăuga mai multe erori. Poziția lor este următoarea: dacă te confrunți cu problema monocore — ai probleme cu arhitectura aplicației și trebuie să schimbi ceva în ea. În rândul utilizatorilor, totuși, există și „un alt grup” — cei care au ajuns la un singur nucleu și susțin că Redis își creează singuri un gât de sticlă. În caz de încărcări foarte mari — mai devreme sau mai târziu — inevitabil se va confrunta cu această problemă, ceea ce impune restricții semnificative asupra arhitecturii și/sau complicații forțate în aceasta.

Nu voi evalua o opinie sau alta. În schimb, voi împărtăși cazul nostru specific și modul în care l-am rezolvat.

Cazul nostru

În unul dintre proiecte, ne-am confruntat cu problema că echipa de dezvoltare a configurat un caching extrem de agresiv al datelor din baza de date (PostgreSQL) prin intermediul Redis. Acesta a fost singurul mod prin care, în timpul vârfurilor bruște de trafic, am reușit să salvăm PostgreSQL și, ca urmare, aplicația.

După o serie de teste de încărcare, am efectuat o analiză a situației și am descoperit că Redis se împotmolea într-un singur nucleu (așa-numitul „în banc”), după care urma o degradare destul de rapidă a aplicației. „Sufocarea” avea o progresie geometrică: odată ce se atingea limita de performanță la Redis, totul se oprea.

Asta arăta aproximativ așa:

KeyDB ca [potențială] alternativă la Redis

Din partea New Relic, problema a fost clar identificată:

KeyDB ca [potențială] alternativă la Redis

Iată statistica operației get în Redis:

KeyDB ca [potențială] alternativă la Redis

După ce am transmis problema în toate detaliile echipei de dezvoltare, s-a descoperit că „îndreptarea problemei nu este posibilă în acest moment”. Astfel a început căutarea unei soluții pe partea de operare, iar răspunsul a fost deja menționatul KeyDB.

Cu toate acestea, înainte de a începe revizuirea sa, merită menționat că în proiect este utilizat Redis standalone, deoarece soluția de cluster bazată pe Sentinel se dovedește a fi semnificativ inferioară în ceea ce privește latența. Una dintre soluțiile evidente ar fi fost crearea mai multor replici ale cache-ului: și astfel aplicația ar putea accesa din toate colțurile cu echilibrare! Totuși, după o discuție cu dezvoltatorii, am fost nevoiți să abandonăm această opțiune din cauza mecanismului activ și complex de invalidare a cache-ului din aplicație. Aceeași problemă se aplica și în cazul shard-ului cache-ului.

O revizuire rapidă a KeyDB

În căutarea unei posibile soluții pentru problemă, am descoperit o aplicație numită KeyDB. Acesta este un fork al Redis, dezvoltat de o companie canadiană și distribuit sub o licență liberă BSD. Proiectul este destul de tânăr: există din începutul anului 2019. Povestea sa este că autorii s-au confruntat și ei la un moment dat cu limitările Redis… și au decis să facă propriul fork. În plus, nu doar că a rezolvat problemele cunoscute, ci a adus și funcții suplimentare, care sunt disponibile doar în versiunea enterprise a Redis.

Pentru cei care doresc să se familiarizeze mai bine cu KeyDB, există un bun articol introductiv pe Medium, care prezintă SGBD-ul și benchmark-uri scurte, comparându-l cu „părintele” său — Redis.

În primul rând, ceea ce ne-a atras la KeyDB a fost soluția potențială pentru problemele noastre, dar, de asemenea, au fost interesante și unele caracteristici suplimentare. Utilizarea KeyDB promitea următoarele avantaje:

  • obținerea unei multiprocesare complete;
  • compatibilitate totală și absolută cu Redis (pentru noi, acest aspect a fost deosebit de important, deoarece nu era posibil să facem modificări din partea aplicației), ceea ce promitea, de asemenea, o migrație fără probleme;
  • un mecanism de backup încorporat în stocarea S3;
  • replicarea activă, ușor de implementat;
  • clusterizarea și shardarea simple fără Sentinel și alte software-uri auxiliare.

Peste 3.000 de stele și mulți contribuitori pe GitHub păreau, de asemenea, încurajatoare. Aplicația este dezvoltată și întreținută activ, ceea ce se vede clar din commit-uri, comunicările în probleme, precum și din PR-urile închise (acceptate). Răspunsul din partea principalului menținător este întotdeauna prietenos și prompt. În general, s-au dovedit a fi suficiente argumente.

Migrarea și rezultatele

Chiar și în ciuda faptului că proiectul de migrare a fost o adevărată aventură (datorită noutății KeyDB), nu aveam multe de pierdut. Deoarece revenirea la modificări este destul de rapidă și simplă - din fericire, întreaga infrastructură este desfășurată în Kubernetes, iar mecanismele încorporate Rolling Update rezolvă excelent astfel de sarcini.

În general, am pregătit template-uri Helm, am comutat aplicația în mediu de testare pe noua bază de date și am lansat totul, predându-l în departamentul QA al clientului.

A început testarea, care a durat aproximativ o săptămână, fără a ne adânci în detalii. Știm doar că clientul a verificat funcțiile standard de lucru cu Redis utilizând driverul PHP phpredis, precum și a efectuat teste QA ale interfeței utilizatorului. După aceasta, am primit undă verde: nu au fost descoperite efecte secundare în utilizarea noului software. Cu alte cuvinte, din punct de vedere al aplicației, nu s-a schimbat nimic..

Merită menționat că nu am modificat nimic în configurație: pur și simplu am înlocuit imaginea utilizată. Același lucru este valabil și pentru monitorizarea și exportul metodelor către Prometheus: cel mai răspândit dintre ele funcționează excelent cu KeyDB și fără nicio modificare. Astfel, putem spune cu încredere că, din punct de vedere operațional, acesta este un transfer ideal.

Datorită tuturor acestor aspecte, după trecerea aplicației la noua SGBD, nu este necesar să se facă alte modificări, iar ca «măsură de stabilizare» — se poate lăsa în acea formă să funcționeze în producție pentru o vreme. Totuși, dacă doriți să vedeți o creștere a performanței (sau, în general, vreo schimbare), trebuie să nu uitați că implicit parametrul KeyDB care răspunde de multitasking (server-threads), este egal cu unu, adică SGBD-ul funcționează exact la fel ca Redis.

După migrare, testare și o perioadă de utilizare a noului aplicație (cu KeyDB), am decis să repetem testarea de încărcare cu aceleași parametrii folosiți pentru Redis. Care au fost rezultatele?..

Din graficul consumului de CPU, a devenit imediat evident că au fost eliminate problemele cu «plafonul» pe un singur nucleu: procesul a început să utilizeze resursele disponibile:

KeyDB ca [potențială] alternativă la Redis

Și ulterior am încercat să «stresc» considerabil aplicația și am observat un consum de până la trei nuclee...

Conform New Relic, aplicația web, având aceeași încărcare, a început să se comporta semnificativ mai adecvat. O anumită degradare a performanței a fost totuși observată, însă, comparând cu graficul similar de mai sus, puteți evalua singuri progresul semnificativ:

KeyDB ca [potențială] alternativă la Redis

Indicatorul de latență al noii baze de date (KeyDB) a scăzut, de asemenea, dar a rămas în limitele acceptabile:

KeyDB ca [potențială] alternativă la Redis

Din următorul grafic se poate observa clar că numărul de cereri către KeyDB este similar:

KeyDB ca [potențială] alternativă la Redis

Concluzionând aceste teste sintetice, se poate spune că atât Redis, cât și KeyDB au demonstrat o degradare semnificativă a performanței în latență (40 ms+) la o creștere considerabilă a numărului de conexiuni paralele (1000+). În cazul nostru, aplicația web a reușit să «reduce» latența lui Redis chiar și cu un număr mai mic de conexiuni (400+), deși pentru KeyDB o astfel de încărcare a rămas acceptabilă.

Conclusions

În acest exemplu se poate observa puterea comunității Open Source în dezvoltarea proiectelor de care este interesată. Pe internet am întâlnit o afirmație excelentă, sensul general fiind următorul: „O mare companie creează un produs interesant, face unele funcții deschise, dar cea mai importantă parte o lasă plătită. Comunitatea folosește, folosește, iar apoi cineva se va hotărî și va face un fork, implementând acele funcții plătite și deschizându-le pentru toți.” Iată că KeyDB este acest caz.

Când vine vorba de migrarea în sine, care a decurs surprinzător de ușor, nu am obținut atât de semnificativ un salt în performanță, așa cum s-ar aștepta, uitându-ne la graficele autorilor KeyDB… Totuși, acesta este doar cazul nostru particular, în care pot exista multe abateri, inclusiv cele legate de faimoasa arhitectură a aplicației (de exemplu, un număr uriaș de comenzi get în Redis în loc de o variantă mai performantă de interogări agregate mget…). Cu toate acestea, s-au obținut rezultate pozitive, împreună cu multe funcții utile pe care vom începe să le implementăm în viitorul apropiat.

În general, KeyDB pare promițător: pe măsură ce obținem experiență practică cu această SGBD (iar aceasta este încă în așteptare!) și pe măsură ce proiectul avansează, vom lua în considerare aplicarea sa și în alte situații.

Totuși, nu ar trebui să consideri acest articol ca un ghid (și cu atât mai puțin - un apel) la acțiune pentru o renunțare generalizată la Redis în favoarea KeyDB. În ciuda experienței noastre pozitive, este evident că nu este o panaceu. Cazul nostru a fost destul de specific: pentru a rezolva rapid o problemă imediată, acest tip de soluție s-a dovedit a fi justificat. Va fi KeyDB util în cazul tău? Cel puțin, acum știi că există această posibilitate potențială.

P.S.

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster