eliminarea întreruperilor de procesare a sarcinilor prin înlocuirea RabbitMQ cu Apache Kafka fără timp de nefuncționare

scalarea infrastructurii backend pentru a gestiona hiper-creșterea este una dintre numeroasele provocări interesante de a lucra la DoorDash. La mijlocul anului 2019, ne-am confruntat cu provocări semnificative de scalare și întreruperi frecvente care implică telina și RabbitMQ, două tehnologii care alimentează sistemul care gestionează activitatea asincronă, permițând funcționalități critice ale platformei noastre, inclusiv Checkout de comenzi și misiuni Dasher.

am rezolvat rapid această problemă cu un sistem simplu de procesare asincronă a sarcinilor bazat pe Apache Kafka, care ne-a oprit întreruperile în timp ce continuam să repetăm o soluție robustă. Versiunea noastră inițială a implementat cel mai mic set de caracteristici necesare pentru a găzdui o mare parte din sarcinile de țelină existente. Odată ajunși în producție, am continuat să adăugăm suport pentru mai multe funcții de țelină, abordând în același timp problemele noi care au apărut atunci când folosim Kafka.

problemele cu care ne-am confruntat folosind telina și RabbitMQ

RabbitMQ și telina au fost piese critice ale infrastructurii noastre care au alimentat peste 900 de sarcini asincrone diferite la DoorDash, inclusiv plata comenzilor, Transmiterea comenzilor comercianților și procesarea locației Dasher. Problema cu care s-a confruntat DoorDash a fost că RabbitMQ a scăzut frecvent din cauza încărcării excesive. Dacă procesarea sarcinilor a scăzut, DoorDash a scăzut efectiv și comenzile nu au putut fi finalizate, rezultând pierderi de venituri pentru comercianții și Dasherii noștri și o experiență slabă pentru consumatorii noștri. Ne-am confruntat cu probleme pe următoarele fronturi:

  • disponibilitate: întreruperi cauzate de disponibilitatea redusă a cererii.
  • scalabilitate: RabbitMQ nu a putut scala odată cu creșterea afacerii noastre.
  • observabilitate: RabbitMQ a oferit valori limitate, iar lucrătorii de țelină au fost Opaci.
  • eficiență operațională: repornirea acestor componente a fost un proces manual consumator de timp.

de ce sistemul nostru de procesare a sarcinilor asincrone nu era foarte disponibil

cea mai mare problemă cu care ne-am confruntat au fost întreruperile și au apărut adesea atunci când cererea era la vârf. RabbitMQ ar merge în jos din cauza sarcinii, putinei conexiune excesivă, și din alte motive. Comenzile ar fi oprite și ar trebui să repornim sistemul nostru sau, uneori, chiar să aducem un broker complet nou și să eșuăm manual pentru a ne recupera de la întrerupere.

pe scufundări mai adânc în problemele de disponibilitate, am găsit următoarele sub-probleme:

  • telina permite utilizatorilor să programeze sarcini în viitor, cu o numărătoare inversă sau ETA. Utilizarea noastră grea a acestor numărători inverse a dus la creșteri vizibile ale încărcăturii brokerului. Unele dintre întreruperile noastre au fost direct legate de o creștere a sarcinilor cu numărători inverse. În cele din urmă am decis să restricționăm utilizarea numărătorilor inverse în favoarea unui alt sistem pe care l-am avut în vigoare pentru programarea lucrărilor în viitor.
  • exploziile bruște de trafic ar lăsa RabbitMQ într-o stare degradată în care consumul de sarcini a fost semnificativ mai mic decât se aștepta. Din experiența noastră, acest lucru ar putea fi rezolvat doar cu un RabbitMQ bounce. RabbitMQ are un concept de control al fluxului în care va reduce viteza conexiunilor care se publică prea repede, astfel încât cozile să poată ține pasul. Controlul debitului a fost adesea, dar nu întotdeauna, implicat în aceste degradări ale disponibilității. Când intră controlul fluxului, editorii îl văd efectiv ca latență a rețelei. Latența rețelei ne reduce timpii de răspuns; dacă latența crește în timpul traficului de vârf, încetinirile semnificative pot duce la această cascadă pe măsură ce cererile se acumulează în amonte.
  • lucrătorii noștri web python uwsgi au avut o caracteristică numită harakiri care a fost activată pentru a ucide orice proces care a depășit un timeout. În timpul întreruperilor sau încetinirilor, harakiri a dus la o conexiune cu brokerii RabbitMQ, deoarece procesele au fost ucise și repornite în mod repetat. Cu mii de lucrători web care rulează la un moment dat, orice încetinire care a declanșat harakiri ar contribui, la rândul său, și mai mult la încetinire prin adăugarea de sarcină suplimentară la RabbitMQ.
  • în producție am experimentat mai multe cazuri în care prelucrarea sarcinilor în consumatorii de țelină sa oprit, chiar și în absența unei sarcini semnificative. Eforturile noastre de investigare nu au dat dovadă de constrângeri de resurse care ar fi oprit procesarea, iar muncitorii au reluat procesarea odată ce au fost respinși. Această problemă nu a fost niciodată cauzată de rădăcină, deși suspectăm o problemă la lucrătorii de țelină înșiși și nu la RabbitMQ.

în general, toate aceste probleme de disponibilitate au fost inacceptabile pentru noi, deoarece fiabilitatea ridicată este una dintre prioritățile noastre cele mai înalte. Deoarece aceste întreruperi ne-au costat foarte mult în ceea ce privește comenzile pierdute și credibilitatea, aveam nevoie de o soluție care să abordeze aceste probleme cât mai curând posibil.

de ce soluția noastră moștenită nu a scalat

următoarea cea mai mare problemă a fost scala. DoorDash crește rapid și am ajuns rapid la limitele soluției noastre existente. Trebuia să găsim ceva care să țină pasul cu creșterea noastră continuă, deoarece soluția noastră moștenită avea următoarele probleme:

lovind limita de scalare verticală

foloseam cea mai mare soluție RabbitMQ cu un singur nod disponibilă pentru noi. Nu a existat nici o cale de a scala vertical mai departe și am început deja să împingem acel nod la limitele sale.

modul High Availability ne-a limitat capacitatea

datorită replicării, modul primar-secundar High Availability (HA) a redus debitul în comparație cu opțiunea single node, lăsându-ne chiar mai puțin spațiu pentru cap decât soluția single node. Nu ne-am putut permite să tranzacționăm pentru disponibilitate.

În al doilea rând, modul HA primar-secundar nu a redus, în practică, severitatea întreruperilor noastre. Failovers a luat mai mult de 20 de minute pentru a finaliza și ar obține adesea blocat necesită intervenție manuală. Mesajele au fost adesea pierdute și în acest proces.

am rămas rapid fără spațiu de trecere, deoarece DoorDash a continuat să crească și să împingă procesarea sarcinilor noastre la limitele sale. Aveam nevoie de o soluție care să se poată scala orizontal pe măsură ce nevoile noastre de procesare au crescut.

cum telina și RabbitMQ au oferit observabilitate limitată

cunoașterea a ceea ce se întâmplă în orice sistem este fundamentală pentru asigurarea disponibilității, scalabilității și integrității sale operaționale.

pe măsură ce navigam pe problemele prezentate mai sus, am observat că:

  • eram limitați la un mic set de valori RabbitMQ disponibile pentru noi.
  • am avut vizibilitate limitată în lucrătorii telina ei înșiși.

trebuia să putem vedea metrici în timp real ale fiecărui aspect al sistemului nostru, ceea ce însemna că limitările de observabilitate trebuiau abordate și ele.

provocările eficienței operaționale

ne-am confruntat, de asemenea, cu mai multe probleme cu RabbitMQ de operare:

  • de multe ori a trebuit să failover nodul nostru RabbitMQ la unul nou pentru a rezolva degradarea persistentă am observat. Această operațiune a fost manuală și consumatoare de timp pentru inginerii implicați și adesea trebuia făcută noaptea târziu, în afara orelor de vârf.
  • nu au existat experți In-House telina sau RabbitMQ la DoorDash pe care să ne putem baza pentru a ajuta la elaborarea unei strategii de scalare pentru această tehnologie.

timpul de inginerie petrecut pentru operarea și întreținerea RabbitMQ nu a fost durabil. Aveam nevoie de ceva care să răspundă mai bine nevoilor noastre actuale și viitoare.

soluții potențiale la problemele noastre cu telina și RabbitMQ

cu problemele prezentate mai sus, am luat în considerare următoarele soluții:

  • schimbați brokerul de telina de la RabbitMQ la Redis sau Kafka. Acest lucru ne-ar permite să continuăm să folosim telina, cu un magazin de date diferit și potențial mai fiabil.
  • adauga multi-broker de sprijin pentru aplicația noastră Django astfel încât consumatorii ar putea publica la n diferite brokeri bazate pe orice logica ne-am dorit. Procesarea sarcinilor va fi împărțită pe mai mulți brokeri, astfel încât fiecare broker va experimenta o fracțiune din sarcina inițială.
  • Upgrade la versiuni mai noi de țelină și RabbitMQ. Versiunile mai noi de telina și RabbitMQ au fost de așteptat să remedieze problemele de fiabilitate, cumpărându-ne timp, deoarece extrageam deja componente din monolitul nostru Django în paralel.
  • migrați la o soluție personalizată susținută de Kafka. Această soluție necesită mai mult efort decât celelalte opțiuni pe care le-am enumerat, dar are și un potențial mai mare de a rezolva fiecare problemă pe care o aveam cu soluția moștenită.

fiecare opțiune are argumente pro și contra:

opțiune Pro contra
Redis ca broker
  • disponibilitate îmbunătățită cu ElasticCache și suport multi-AZ
  • îmbunătățirea observabilității brokerului cu elasticcache ca broker
  • îmbunătățirea eficienței operaționale
  • experiența operațională internă și expertiza cu Redis
  • un swap broker este drept ca opțiune acceptată în telina
  • harakiri connection putinei nu degradează semnificativ performanța Redis
  • incompatibil cu modul Redis pus în cluster
  • Redis singur nod nu scară orizontal
  • nu îmbunătățiri telina observabilitate
  • această soluție nu abordează problema observată în cazul în care lucrătorii telina oprit sarcini de procesare
Kafka ca broker
  • Kafka poate fi foarte disponibil
  • Kafka este scalabil orizontal
  • observabilitate îmbunătățită cu Kafka ca broker
  • eficiență operațională îmbunătățită
  • DoorDash a avut expertiza Kafka internă
  • un swap broker este drept ca opțiune acceptată în telina
  • harakiri connection putinei nu degradează în mod semnificativ performanța Kafka
  • Kafka nu este susținută de telina încă
  • nu abordează problema observată în cazul în care lucrătorii telina opri sarcinile de procesare
  • nu există îmbunătățiri telina observabilitate
  • în ciuda experienței in-house, nu am operat Kafka la scară la DoorDash.
brokeri multipli
  • disponibilitate îmbunătățită
  • scalabilitate orizontală
  • fără îmbunătățiri ale observabilității
  • fără îmbunătățiri ale eficienței operaționale
  • nu abordează problema observată în cazul în care lucrătorii de țelină opresc sarcinile de procesare
  • -conexiune indusă putinei
upgrade versiuni
  • s-ar putea îmbunătăți problema în cazul în care RabbitMQ devine blocat într-o stare degradată
  • s-ar putea îmbunătăți problema în cazul în care lucrătorii telina se blochează
  • ne-ar putea cumpăra spațiu pentru a implementa o strategie pe termen mai lung
  • nu este garantat să remediem Erorile observate
  • nu va rezolva imediat problemele noastre cu disponibilitatea, scalabilitatea, observabilitatea și eficiența operațională
  • versiunile mai noi ale RabbitMQ și telina necesită versiuni mai noi ale Python.
  • nu abordează problema cu conexiunea indusă de harakiri putinei
soluție personalizată Kafka
  • Kafka poate fi extrem de disponibil
  • Kafka este scalabil orizontal
  • observabilitate îmbunătățită cu kakfa ca broker
  • eficiență operațională îmbunătățită
  • expertiza Kafka in-house
  • o schimbare broker este drept-Foward
  • harakiri conexiune putinei nu degradează în mod semnificativ performanța Kafka
  • abordează problema observată în cazul în care lucrătorii telina opri sarcini de procesare
  • necesită mai mult de lucru pentru a pune în aplicare decât toate celelalte opțiuni
  • în ciuda experienței in-house, nu am operat Kafka la scară la DoorDash

strategia noastră pentru onboarding Kafka

având în vedere uptime sistemul nostru necesar, am conceput strategia de onboarding bazată pe următoarele principii pentru a maximiza beneficiile de fiabilitate în cel mai scurt timp. Această strategie a implicat trei etape:

  • lovind terenul de funcționare: Am vrut să valorificăm elementele de bază ale soluției pe care o construiam pe măsură ce iteram pe alte părți ale acesteia. Comparăm această strategie cu conducerea unei mașini de curse în timp ce schimbăm o nouă pompă de combustibil.
  • Opțiuni de proiectare pentru o adoptare perfectă de către dezvoltatori: am vrut să minimalizăm efortul irosit din partea tuturor dezvoltatorilor care ar fi putut rezulta din definirea unei interfețe diferite.
  • lansare incrementală cu timp de nefuncționare zero: În loc ca o versiune mare strălucitoare să fie testată în sălbăticie pentru prima dată, cu șanse mai mari de eșecuri, ne-am concentrat pe expedierea unor caracteristici independente mai mici, care ar putea fi testate individual în sălbăticie pe o perioadă mai lungă de timp.

lovirea terenului alergând

trecerea la Kafka a reprezentat o schimbare tehnică majoră în stiva noastră, dar una extrem de necesară. Nu am avut timp de pierdut, deoarece în fiecare săptămână pierdeam afaceri din cauza instabilității soluției noastre RabbitMQ moștenite. Prima și cea mai importantă prioritate a noastră a fost crearea unui produs minim viabil (MVP) care să ne aducă stabilitate interimară și să ne ofere spațiul necesar pentru a itera și a ne pregăti pentru o soluție mai cuprinzătoare, cu o adoptare mai largă.

MVP-ul nostru a fost format din producători care au publicat nume complet calificate pentru sarcini (FQN) și argumente murate către Kafka în timp ce consumatorii noștri au citit acele mesaje, au importat sarcinile din FQN și le-au executat sincron cu argumentele specificate.

arhitectura Minimal Viable Product(MVP) pe care am decis să o construim a inclus un stat interimar în care vom publica sarcini care se exclud reciproc atât moștenirii (linii punctate roșii), cât și noilor sisteme (linii solide verzi), înainte de starea finală în care vom opri publicarea sarcinilor către RabbitMQ.1

Figura 1: Arhitectura Minimal Viable Product(MVP) pe care am decis să o construim a inclus un stat interimar în care vom publica sarcini care se exclud reciproc atât moștenirii (linii punctate roșii), cât și noilor sisteme (linii solide verzi), înainte de starea finală în care vom opri publicarea sarcinilor către RabbitMQ.

Opțiuni de proiectare pentru o adoptare fără sudură de către dezvoltatori

uneori, adoptarea dezvoltator este o provocare mai mare decât dezvoltarea. Am făcut acest lucru mai ușor prin implementarea unui înveliș pentru adnotarea @task a țelinei, care a direcționat dinamic trimiterile DE SARCINI către oricare sistem bazat pe steaguri de caracteristici configurabile dinamic. Acum, aceeași interfață ar putea fi utilizată pentru a scrie sarcini pentru ambele sisteme. Cu aceste decizii în vigoare, echipele de ingineri nu au trebuit să facă nicio muncă suplimentară pentru a se integra cu noul sistem, cu excepția implementării unui singur steag de caracteristici.

am vrut să ne lansăm sistemul imediat ce MVP-ul nostru a fost gata, dar nu a acceptat încă toate aceleași caracteristici ca telina. Telina permite utilizatorilor să configureze sarcinile lor cu parametrii în adnotare sarcina lor sau atunci când își prezintă sarcina lor. Pentru a ne permite să lansăm mai rapid, am creat o listă albă de parametri compatibili și am ales să susținem cel mai mic număr de funcții necesare pentru a susține majoritatea sarcinilor.

am intensificat rapid volumul de sarcini la MVP bazat pe Kafka, începând mai întâi cu sarcini cu risc scăzut și cu prioritate scăzută. Unele dintre acestea erau sarcini care se desfășurau în afara orelor de vârf, ceea ce explică vârfurile metricii descrise mai sus.

Figura 2: Am crescut rapid volumul de sarcini la MVP bazat pe Kafka, începând mai întâi cu sarcini cu risc scăzut și cu prioritate redusă. Unele dintre acestea erau sarcini care se desfășurau în afara orelor de vârf, ceea ce explică vârfurile metricii descrise mai sus.

după cum se vede în Figura 2, cu cele două decizii de mai sus, am lansat MVP-ul nostru după două săptămâni de dezvoltare și am obținut o reducere de 80% a sarcinii RabbitMQ încă o săptămână după lansare. Ne-am ocupat rapid de problema principală a întreruperilor și, pe parcursul proiectului, am susținut din ce în ce mai multe caracteristici ezoterice pentru a permite executarea sarcinilor rămase.

lansare incrementală, timp de nefuncționare zero

capacitatea de a comuta clusterele Kafka și de a comuta între RabbitMQ și Kafka dinamic fără impact asupra afacerii a fost extrem de importantă pentru noi. Această abilitate ne-a ajutat, de asemenea, într-o varietate de operațiuni, cum ar fi întreținerea clusterului, vărsarea încărcăturii și migrațiile treptate. Pentru a implementa acest rollout, am folosit steaguri de caracteristici dinamice atât la nivelul de transmitere a mesajelor, cât și la partea de consum a mesajelor. Costul de a fi pe deplin dinamic aici a fost să menținem flota noastră de muncitori la capacitate dublă. Jumătate din această flotă era dedicată RabbitMQ, iar restul lui Kafka. Conducerea flotei de muncitori la capacitate dublă a fost cu siguranță o taxă pe infrastructura noastră. La un moment dat, chiar am creat un cluster Kubernetes complet nou doar pentru a găzdui toți lucrătorii noștri.

în faza inițială de dezvoltare, această flexibilitate ne-a servit bine. Odată ce am avut mai multă încredere în noul nostru sistem, am analizat modalități de a reduce sarcina pe infrastructura noastră, cum ar fi rularea mai multor procese consumatoare pe mașină lucrătoare. Pe măsură ce am tranziționat diverse subiecte, am reușit să începem reducerea numărului de lucrători pentru RabbitMQ, menținând în același timp o capacitate mică de rezervă.

nicio soluție nu este perfectă, iterați după cum este necesar

cu MVP-ul nostru în producție, am avut spațiul necesar pentru a itera și lustrui produsul nostru. Am clasat fiecare caracteristică lipsă de țelină după numărul de sarcini care au folosit-o pentru a ne ajuta să decidem care dintre ele să implementăm mai întâi. Caracteristicile utilizate de doar câteva sarcini nu au fost implementate în soluția noastră personalizată. În schimb, am rescris acele sarcini pentru a nu utiliza acea caracteristică specifică. Cu această strategie, am mutat în cele din urmă toate sarcinile de pe telina.

utilizarea Kafka a introdus, de asemenea, noi probleme care aveau nevoie de atenția noastră:

  • blocarea capului de linie care a dus la întârzieri în procesarea sarcinilor
  • implementările au declanșat reechilibrarea partițiilor care a dus și la întârzieri

problema de blocare a capului de linie a Kafka

subiectele Kafka sunt partiționate astfel încât un singur consumator (pe grup de consumatori) citește mesaje pentru partițiile sale atribuite în ordinea în care au sosit. Dacă un mesaj dintr-o singură partiție durează prea mult pentru a fi procesat, acesta va bloca consumul tuturor mesajelor din spatele acestuia în acea partiție, așa cum se vede în Figura 3, de mai jos. Această problemă poate fi deosebit de dezastruoasă în cazul unui subiect cu prioritate ridicată. Vrem să putem continua să procesăm mesajele într-o partiție în cazul în care se întâmplă o întârziere.

în problema de blocare a capului Kafka, un mesaj lent într-o partiție (în roșu) blochează toate mesajele din spatele ei de a fi procesate. Alte partiții vor continua să proceseze așa cum era de așteptat.

Figura 3: În problema de blocare a capului de linie a lui Kafka, un mesaj lent într-o partiție (în roșu) blochează toate mesajele din spatele ei de la procesare. Alte partiții vor continua să proceseze așa cum era de așteptat.

în timp ce paralelismul este, fundamental, o problemă Python, conceptele acestei soluții sunt aplicabile și altor limbi. Soluția noastră, descrisă în Figura 4, de mai jos, a fost de a găzdui un proces Kafka-consumator și mai multe procese de execuție a sarcinilor pe lucrător. Procesul Kafka-consumator este responsabil pentru preluarea mesajelor de la Kafka și plasarea lor pe o coadă locală care este citită de procesele de execuție a sarcinilor. Continuă să consume până când coada locală atinge un prag definit de utilizator. Această soluție permite ca mesajele din partiție să curgă și un singur proces de execuție a sarcinilor va fi blocat de mesajul lent. Pragul limitează, de asemenea, numărul de mesaje în timpul zborului din coada locală (care se pot pierde în cazul unui accident de sistem).

Figura 4: Lucrătorul nostru Kafka care nu blochează constă dintr-o coadă de mesaje locale și două tipuri de procese: un proces Kafka-consumator și mai multe procese task-executor. În timp ce un consumator kafka poate citi din mai multe partiții, pentru simplitate vom descrie doar una. Această diagramă arată că un mesaj cu procesare lentă (în roșu) blochează doar un singur task-executor până la finalizare, în timp ce alte mesaje din spatele acestuia în partiție continuă să fie procesate de alți task-executori.

Figura 4: lucrătorul nostru Kafka care nu blochează constă dintr-o coadă de mesaje locale și două tipuri de procese: un proces Kafka-consumator și mai multe procese task-executor. În timp ce un consumator kafka poate citi din mai multe partiții, pentru simplitate vom descrie doar una. Această diagramă arată că un mesaj cu procesare lentă (în roșu) blochează doar un singur task-executor până la finalizare, în timp ce alte mesaje din spatele acestuia în partiție continuă să fie procesate de alți task-executori.

perturbarea implementărilor

implementăm aplicația noastră Django de mai multe ori pe zi. Un dezavantaj al soluției noastre pe care l-am observat este că o implementare declanșează o reechilibrare a alocărilor de partiții în Kafka. În ciuda utilizării unui grup de consumatori diferit pe subiect pentru a limita domeniul de reechilibrare, implementările au provocat încă o încetinire momentană a procesării mesajelor, deoarece consumul de sarcini a trebuit să se oprească în timpul reechilibrării. Încetinirile pot fi acceptabile în majoritatea cazurilor atunci când efectuăm versiuni planificate, dar pot fi catastrofale atunci când, de exemplu, facem o versiune de urgență pentru remedierea rapidă a unei erori. Consecința ar fi introducerea unei încetiniri a procesării în cascadă.

versiunile mai noi ale Kafka și ale clienților susțin reechilibrarea cooperativă incrementală, ceea ce ar reduce masiv impactul operațional al unei reechilibrări. Actualizarea clienților noștri pentru a sprijini acest tip de reechilibrare ar fi soluția noastră de alegere în viitor. Din păcate, reechilibrarea cooperativă incrementală nu este încă acceptată în clientul nostru Kafka ales.

cheie victorii

odată cu încheierea acestui proiect, am realizat îmbunătățiri semnificative în ceea ce privește uptime, scalabilitate, observabilitate, și descentralizare. Aceste victorii au fost cruciale pentru a asigura creșterea continuă a afacerii noastre.

fără întreruperi repetate

am oprit întreruperile repetate aproape imediat ce am început să lansăm această abordare personalizată Kafka. Întreruperile au dus la experiențe extrem de slabe ale utilizatorilor.

  • implementând doar un mic subset al celor mai utilizate caracteristici de țelină din MVP-ul nostru, am reușit să livrăm codul de lucru la producție în două săptămâni.
  • cu MVP în loc am fost capabili de a reduce în mod semnificativ sarcina pe RabbitMQ și țelină așa cum am continuat să se întărească soluția noastră și să pună în aplicare noi caracteristici.

procesarea sarcinilor nu mai era factorul limitativ pentru creștere

cu Kafka în centrul arhitecturii noastre, am construit un sistem de procesare a sarcinilor care este foarte disponibil și scalabil orizontal, permițând DoorDash și clienților săi să își continue creșterea.

observabilitate sporită masiv

deoarece aceasta a fost o soluție personalizată, am reușit să coacem mai multe valori la aproape fiecare nivel. Fiecare coadă, lucrător și sarcină a fost pe deplin observabilă la un nivel foarte granular în mediile de producție și dezvoltare. Această observabilitate crescută a fost un câștig uriaș nu numai în sensul producției, ci și în ceea ce privește productivitatea dezvoltatorilor.

descentralizare operațională

cu îmbunătățirile de observabilitate, am reușit să templatizăm alertele noastre ca module Terraform și să atribuim în mod explicit proprietarii fiecărui subiect și, implicit, tuturor celor peste 900 de sarcini.

Un ghid de operare detaliat pentru sistemul de procesare a sarcinilor face ca informațiile să fie accesibile tuturor inginerilor pentru a depana problemele operaționale cu subiectele și lucrătorii lor, precum și pentru a efectua operațiuni generale de gestionare a clusterului Kafka, după cum este necesar. Operațiunile de zi cu zi sunt autoservite, iar sprijinul este rareori necesar din partea echipei noastre de infrastructură.

concluzie

pentru a rezuma, am atins plafonul abilității noastre de a scala RabbitMQ și a trebuit să căutăm alternative. Alternativa cu care am mers a fost o soluție personalizată bazată pe Kafka. Deși există unele dezavantaje în utilizarea Kafka, am găsit o serie de soluții, descrise mai sus.

când fluxurile de lucru critice se bazează foarte mult pe procesarea sarcinilor asincrone, asigurarea scalabilității este de cea mai mare importanță. Când întâmpinați probleme similare, nu ezitați să vă inspirați din strategia noastră, care ne-a acordat 80% din rezultat cu 20% din efort. Această strategie, în cazul general, este o abordare tactică pentru a atenua rapid problemele de fiabilitate și a cumpăra timp extrem de necesar pentru o soluție mai robustă și strategică.

mulțumiri

autorii ar dori să-i mulțumească lui Clement Fang, Corry Haines, Danial Asif, Jay Weinstein, Luigi Tagliamonte, Matthew Anger, Shaohua Zhou și Yun-Yu Chen pentru contribuția la acest proiect.

fotografie de tian kuan pe Unsplash

Lasă un răspuns

Adresa ta de email nu va fi publicată.