$FOGO se simte ca este modelat în jurul ideii că viteza nu ar trebui să fie o afirmație cosmetică, deoarece dacă blocurile sunt într-adevăr rapide și timpul de execuție poate procesa muncă independentă în același timp, atunci aplicația devine adevărata bottleneck și acea schimbare este locul unde povestea SVM devine interesantă, deoarece timpul de execuție întreabă practic fiecare dezvoltator aceeași întrebare în momentul în care utilizatorii reali sosesc, care este dacă tranzacțiile lor sunt de fapt independente sau dacă, din întâmplare, au proiectat un blocaj comun pe care toată lumea trebuie să-l atingă.
Execuția paralelă sună simplă atunci când este explicată ca tranzacții care rulează împreună, dar detaliul practic care schimbă totul este că funcționează doar atunci când două tranzacții nu se luptă pentru aceeași stare, iar pe SVM starea nu este un blob invizibil pe care lanțul îl interpretează cum vrea, starea este explicită și concretă, iar fiecare tranzacție trebuie să declare ce va citi și ce va scrie, ceea ce înseamnă că lanțul poate programa lucrări cu încredere atunci când acele declarații nu se suprapun, și înseamnă, de asemenea, că lanțul nu te poate salva de propriul tău aranjament atunci când forțezi totul să se suprapună.
Aceasta este partea pe care majoritatea comentariilor de suprafață o ratează, deoarece oamenii vorbesc de parcă performanța trăiește la nivelul lanțului, dar pe Fogo, în momentul în care începi să modelezi o aplicație, performanța devine ceva ce proiectezi în modul în care conturile și datele sunt separate, și acesta este motivul pentru care două aplicații pe același lanț pot părea complet diferite sub stres, cu una rămânând lină în timp ce cealaltă devine ciudat blocată, chiar dacă ambele stau pe același mediu rapid de execuție.
Am observat că atunci când constructorii vin din obiceiuri de execuție secvențială, ei aduc un instinct care se simte sigur, dar devine costisitor pe SVM, care este instinctul de a păstra un obiect de stare central care este actualizat de fiecare acțiune, deoarece face ca raționamentul despre sistem să pară curat, facilitează analiza și face ca codul să se simtă ca și cum ar avea o sursă unică de adevăr, dar pe un lanț SVM același design devine un throttling tăcut, deoarece fiecare acțiune a utilizatorului încearcă acum să scrie în același loc, așa că, chiar dacă timpul de execuție este pregătit să execute în paralel, aplicația ta a creat o singură bandă în care totul trebuie să intre.
Ce se schimbă pe Fogo este că aranjamentul stării încetează să fie doar stocare și începe să fie politica de concurență, deoarece fiecare cont scris devine un fel de blocare, iar când pui prea mult în spatele unei singure blocări nu încetinești doar un component mic, ci colapsezi paralelismul pentru întregul flux, iar lanțul nu trebuie să fie congestionat pentru a simți asta, deoarece designul contractului tău generează congestia forțând utilizatori nelegat să se ciocnească pe același set de scriere.
FOGO pentru un motiv care nu are nimic de-a face cu numerele de clasament și totul de-a face cu modul în care lanțul presează în tăcere constructorii să își dezvolte arhitectura, deoarece atunci când construiești pe un L1 bazat pe SVM nu alegi doar un mediu mai rapid, alegi un model de execuție care recompensează un design bun al stării și expune un design prost al stării fără milă.
Fogo se simte ca și cum este modelat în jurul ideii că viteza nu ar trebui să fie o afirmație cosmetică, deoarece dacă blocurile sunt cu adevărat rapide și timpul de execuție poate procesa lucrări independente în același timp, atunci aplicația devine adevăratul bottleneck, iar acel schimb este locul unde povestea SVM devine interesantă, deoarece timpul de execuție întreabă practic fiecare dezvoltator aceeași întrebare în momentul în care sosesc utilizatorii reali, care este dacă tranzacțiile lor sunt de fapt independente sau dacă au proiectat accidental o blocare comună pe care toată lumea trebuie să o atingă.
Execuția paralelă sună simplă atunci când este explicată ca tranzacții care rulează împreună, dar detaliul practic care schimbă totul este că funcționează doar atunci când două tranzacții nu se luptă pentru aceeași stare, iar pe SVM starea nu este un blob invizibil pe care lanțul îl interpretează cum vrea, starea este explicită și concretă, iar fiecare tranzacție trebuie să declare ce va citi și ce va scrie, ceea ce înseamnă că lanțul poate programa lucrări cu încredere atunci când acele declarații nu se suprapun, și înseamnă, de asemenea, că lanțul nu te poate salva de propriul tău aranjament atunci când forțezi totul să se suprapună.
Aceasta este partea pe care majoritatea comentariilor de suprafață o ratează, deoarece oamenii vorbesc de parcă performanța trăiește la nivelul lanțului, dar pe Fogo, în momentul în care începi să modelezi o aplicație, performanța devine ceva ce proiectezi în modul în care conturile și datele sunt separate, și acesta este motivul pentru care două aplicații pe același lanț pot părea complet diferite sub stres, cu una rămânând lină în timp ce cealaltă devine ciudat blocată, chiar dacă ambele stau pe același mediu rapid de execuție.
Am observat că atunci când constructorii vin din obiceiuri de execuție secvențială, ei aduc un instinct care se simte sigur, dar devine costisitor pe SVM, care este instinctul de a păstra un obiect de stare central care este actualizat de fiecare acțiune, deoarece face ca raționamentul despre sistem să pară curat, facilitează analiza și face ca codul să se simtă ca și cum ar avea o sursă unică de adevăr, dar pe un lanț SVM același design devine un throttling tăcut, deoarece fiecare acțiune a utilizatorului încearcă acum să scrie în același loc, așa că, chiar dacă timpul de execuție este pregătit să execute în paralel, aplicația ta a creat o singură bandă în care totul trebuie să intre...
Ce se schimbă pe Fogo Oficial este că aranjamentul stării încetează să fie doar stocare și începe să fie politica de concurență, deoarece fiecare cont scris devine un fel de blocare, iar când pui prea mult în spatele unei singure blocări nu încetinești doar un component mic, ci colapsezi paralelismul pentru întregul flux, iar lanțul nu trebuie să fie congestionat pentru a simți asta, deoarece designul contractului tău generează congestia forțând utilizatori nelegat să se ciocnească pe același set de scriere.
Cea mai utilă modalitate de a gândi despre aceasta este de a trata fiecare bucată scrisă de stare ca pe o decizie despre cine este permis să progreseze în același timp, iar obiectivul de design devine reducerea coliziunilor inutile, ceea ce nu înseamnă eliminarea completă a stării comune, deoarece o parte din starea comună este esențială, dar înseamnă a fi disciplinat cu privire la ceea ce trebuie să fie comun și ceea ce a fost doar comun din comoditate, deoarece comoditatea este locul unde execuția paralelă moare în tăcere.
Pe Fogo, tiparele care mențin aplicațiile să se simtă rapide sunt rareori complicate, dar sunt stricte, deoarece necesită ca un dezvoltator să separe agresiv starea utilizatorului, să izoleze starea specifică pieței în loc să împingă totul printr-un singur obiect protocolar global și să înceteze să scrie în conturi comune care sunt în mare parte acolo pentru urmărire și vizibilitate, deoarece acele metrici derivate pot exista fără a deveni parte din calea critică de scriere pentru fiecare tranzacție.
Când mă uit la designurile prietenoase cu paralelism de succes, ele tind să trateze acțiunile utilizatorilor ca fiind în mare parte locale, unde un utilizator atinge propria sa stare și o felie îngustă de stare comună care este cu adevărat necesară, iar felia comună este structurată într-un mod care nu forțează utilizatori nelegat să se conteste, motiv pentru care separarea pe utilizator nu este doar un truc de organizare drăguț, ci este o strategie de printe, iar separarea pe piață nu este doar o alegere de arhitectură curată, ci este diferența dintre o piață activă care trage totul în jos și mai multe piețe care curg independent.
Capcana ascunsă este că dezvoltatorii scriu adesea stare comună deoarece doresc adevărul global instantaneu, cum ar fi totalurile globale ale comisioanelor, contorii globali de volum, trackerii globali de activitate, tablourile de lideri globale sau metricile globale ale protocolului, iar problema nu este că acele metrici sunt proaste, problema este că atunci când le actualizezi în aceeași tranzacție ca fiecare acțiune a utilizatorului, injectezi o scriere comună în fiecare cale, așa că fiecare cale acum intră în conflict, și dintr-o dată ai construit o aplicație secvențială în interiorul unui timp de execuție paralel, și nu contează cât de rapid este Fogo, deoarece propriul tău design forțează lanțul să trateze lucrările independente ca lucrări dependente.
Ce schimbă execuția paralelă, într-un sens foarte practic, este că constructorii sunt împinși să separe starea corectă de starea de raportare și sunt împinși să actualizeze starea de raportare pe o cadentă diferită, sau să o scrie în segmente shardate, sau să o deriveze din traseele de evenimente, deoarece odată ce încetezi să forțezi fiecare tranzacție să scrie în același cont de raportare, timpul de execuție poate finalmente programa lucrări reale în paralel, iar aplicația începe să se simtă ca și cum ar aparține unui lanț SVM în loc să ruleze doar pe unul.
Aceasta devine și mai vizibilă în aplicațiile de tip trading, unde postura Fogo face ca discuția să pară ancorată, deoarece tradingul concentrează activitatea, iar concentrarea creează contestație, iar contestația este dușmanul execuției paralele, așa că dacă un sistem de trading este proiectat în jurul unei stări centrale de carte de comenzi care trebuie mutată pentru fiecare interacțiune, lanțul va serializa acele interacțiuni indiferent cât de rapide sunt blocurile, iar experiența utilizatorului se va degrada exact atunci când contează cel mai mult, motiv pentru care constructorii sunt forțați în designuri mai dificile, dar mai bune, unde componentele cele mai fierbinți sunt minimizate, unde starea este partitionată, unde căile de decontare sunt îngustate, și unde părțile care nu trebuie să fie mutate la fiecare acțiune sunt eliminate din calea critică.
Aceeași logică apare în aplicațiile în timp real pe care oamenii presupun că vor fi ușor pe un lanț rapid, cum ar fi sistemele interactive care se actualizează frecvent, deoarece abordarea naivă este de a menține o stare mondială unică și de a o muta constant, dar pe @Fogo Oficial aceasta devine un punct de coliziune garantat, deoarece fiecare participant încearcă să atingă același obiect scris, așa că abordarea mai bună este să izolezi starea pe participant, să localizezi zonele comune în loc să le globalizezi, și să tratezi agregatele globale ca fiind ceva care este actualizat într-un mod mai controlat, deoarece în momentul în care încetezi să faci fiecare acțiune să scrie în același obiect comun, timpul de execuție poate începe să ruleze multe acțiuni împreună, și acesta este locul unde viteza percepută devine reală.
În stilul logic de înaltă frecvență, care este locul unde lanțurile cu latență mică sunt adesea judecate aspru, execuția paralelă face ca defectele de design să fie imposibil de ascuns, deoarece atunci când mulți actori trimit acțiuni rapid, orice stare scrisă comună devine un câmp de bătălie, iar în loc să construiești un sistem în care multe fluxuri progresează independent, construiești un sistem în care toată lumea se grăbește pentru aceeași blocare, iar rezultatul nu este doar o aplicație mai lentă, ci este o dinamică de piață diferită, deoarece ordonarea devine dominată de contestație mai degrabă decât de strategie, motiv pentru care cele mai bune design-uri tind să izoleze scrierile, să reducă mutația comună și să trateze componentele contestate ca fiind înguste și deliberate, mai degrabă decât largi și accidentale.
Aplicațiile bogate în date arată aceeași schemă într-un mod mai liniștit, deoarece majoritatea consumatorilor de date trebuie doar să citească, iar citirile nu sunt problema, dar atunci când fluxurile consumatorilor încep să scrie date comune pentru comoditate, cum ar fi stamparea valorilor în conturi globale sau actualizarea cache-urilor partajate, ele otrăvesc paralelismul fără un câștig real, iar abordarea mai bună este să lași consumatorii să citească date comune și să scrie doar deciziile lor, deoarece odată ce păstrezi scrierile comune confinate la fluxuri de actualizare dedicate, protejezi concurența pentru toți ceilalți.
Compromisul pe care Fogo îl cere implicit dezvoltatorilor să accepte este că arhitectura prietenoasă cu paralelismul nu este gratuită, deoarece odată ce îți sharduiești starea și separi conturile, gestionezi mai multe componente, raționezi despre mai multe margini și construiești sisteme unde concurența este reală mai degrabă decât teoretică, ceea ce înseamnă că testarea trebuie să fie mai strictă, căile de actualizare trebuie să fie mai atente, iar observabilitatea trebuie să fie mai bună, dar recompensa este că aplicația poate scala în modul în care un timp de execuție SVM este proiectat să suporte, unde acțiunile independente progresează cu adevărat împreună în loc să aștepte în spatele unui bottleneck global.
Greșeala care distruge cea mai mare parte a avantajului paralel este nu o eroare avansată, ci una simplă, care constă în crearea unui singur cont scris comun pe care fiecare tranzacție îl atinge, iar pe un lanț precum Fogo, acea greșeală este deosebit de costisitoare, deoarece cu cât lanțul devine mai rapid, cu atât este mai vizibil că propriul tău design este limitarea, iar acea vizibilitate nu este o eșec a lanțului, ci este lanțul care dezvăluie ce este cu adevărat arhitectura.