Distribuirani sustavi: kada biste ih trebali graditi i kako ih skalirati. Detaljni vodič.

Fotografiju Jeremy McKnight na Unsplash

Uvijek me upadne koliko mlađih programera pati od sindroma prevare kada su počeli stvarati svoj proizvod.

Shvaćam, postoji puno nevjerojatnih primjera vrhunskih tvrtki s nevjerojatno složenim distribuiranim sustavima koji mogu riješiti milijarde zahtjeva, graciozno nadograditi stotine aplikacija bez ikakvog zastoja, oporaviti se od katastrofe u sekundi, puštati svakih 60 minuta i imati brzinu svjetlosti reakcijska vremena s bilo kojeg mjesta na svijetu.

Ova očekivanja mogu biti prilično neodoljiva kada započinjete s projektom. No, kao što mnogi od vas već znaju, većina ovih tvrtki započela je s minimalnim održivim sustavom i vrlo lošom tehnologijom. Postoji jednostavan razlog za to: nisu im trebali dok su započeli. Trošenje više vremena na dizajn vašeg sustava umjesto na kodiranje moglo bi u stvari dovesti do vašeg neuspjeha.

Ovaj je članak korak po korak kako voditi. Pokazat ću vam kako smo u Visageu započeli s najsitnijim sustavom ikad i izgradili osnovni skalabilni distribucijski sustav visoke dostupnosti. Ovo je prava studija slučaja za uklanjanje vaših kompleksa ako nikada niste imali priliku to učiniti sami.

Kad sam prvi put stigao u Visage kao CTO, bio sam jedini inženjer. Nisam znao ništa o tehnološkom paketu, ali pridružio sam se jer mi se jako svidjela ideja da se mogu zaposliti bez internih regrutovanja ili HR službe. To je bila suštinska ideja Visagea: crowdsourcing koji pokreće puno nevidljivih regrutova koji rade zajedno na vašim ulogama potpomognute umjetnom inteligencijom koja bi u nekoliko dana tražila za vas najprikladniji talent. Onda se izravno družite s njima, nijedan srednji čovjek.

"Gužva" u crowdsourcingu momentalno je pokrenula moj inženjerski mozak: bit će puno ljudi koji rade istovremeno, očekujući dobre performanse bilo gdje u svijetu. Sviđao mi se izazov.

Ali sistemski mudre, stvari su bile loše, stvarno loše. To sam pronašao kad sam stigao:

  • Kompromitirani primjerak Wordpressa koji ima stotine zastarjelih neispravnih dodataka koji se pokreću u VM-u na zajedničkom poslužitelju
  • Kompromitirani poštanski sandučići
  • Sranje s Google dokumentima i proračunskim tablicama.

I to je sasvim normalno. Opet nije bilo tehničkog člana u momčadi, a očekivao sam ovako nešto. Ipak, tim se fokusirao na poslovnu priliku i činilo se da proizvod djeluje čarobno, dok sve radi ručno! (Lažno dok ne napravite). A to je bilo stvarno nevjerojatno

Naš prvi sustav (Da, isisao je, ali učinio je to posao)!

Ne iznenađuje da je moj prvi zadatak bio ponovno stvoriti VM, ponovno instalirati ažuriranu verziju Wordpressa, provjeriti je li svatko promijenio svoje lozinke, uspostavio pravila o zaporkama i uklonio desetke zlonamjernog softvera na računalima tvrtke ... ali prijeđimo na razmatranje sustava.

Od Wordpressa do web aplikacije

Vaš prvi fokus na početku stvaranja proizvoda moraju biti podaci. Podaci su važni za vrijednost vaše tvrtke. To će biti ono što svakodnevno koristite za donošenje odluka i ono što pokažete svojim investitorima kako bi pokazali napredak.

Morate shvatiti svoje podatke, a prikupljanje podataka iz različitih izvora u različitim formatima bit će ogroman gubitak vremena. Wordpress može biti vrlo dobar izbor u mnogim slučajevima štedeći dosta inženjerskog vremena, ali za svoje potrebe Visage tim je morao instalirati fantastične dodatke koji se više nisu održavali. Kao rezultat toga, nismo imali kontrolu nad generiranim podatkovnim modelom, a podaci koji nisu mogli odgovarati modelu bili su raštrkani u desecima dokumenata i proračunskih tablica.

Dakle, osim ako postoji proizvod koji već zadovoljava 90% vaših potreba, razmislite o idealnom modelu podataka i dizajnirajte i implementirajte minimalni održivi proizvod (MVP) koji će moći zadržati sve vaše podatke.

Onda pomislite API. Vaša aplikacija mora imati API, bit će kritična kada je na kraju prodate. Nemojte ga odmah povećavati, nego kodirajte s skalabilnošću na umu. Učinite svoj API bez državljanstva i kao RESTful što je moguće moguće jer će svi očekivati ​​da će ga moći pitati pomoću standardnih HTTP metoda.

U našem slučaju odabrali smo NodeJS jer bi većina našeg koda bila upravo obrada ulaza i izlaza. NodeJS ne blokira i dolazi s knjižnicom koja je prikladna za oblikovanje API-ja: ExpressJS.

Ako trebate web mjesto s kupcem, imate nekoliko mogućnosti. Prvo možete stvoriti sloj na vašem poslužitelju aplikacija koji će generirati vaše stranice ili možete izgraditi Javascript aplikaciju s jednom stranicom koju će poslužiti statički web hosting poslužitelj.

U Visageu smo otišli na drugu opciju i odlučili stvoriti jednu aplikaciju za korisnike i jednu za administratore. To je jednostavno zato što bismo imali mnogo veća očekivanja od korisnika nego što nam je bilo potrebno za administratore i željeli smo obje baze podataka jednostavno koristiti (također kasnije, za CORS razmatranja). Ovako je izgledao naš sustav:

Svi podaci na jednom mjestu

Već rano delegirajte pohranu osjetljivih podataka

Ako nije važno za vaše poslovanje, nema valjanog razloga za pohranu osjetljivih osobnih podataka u vaše sustave. Sigurnost je složena stvar i ako svakodnevno mijenjate svoj kôd dok ne nađete na tržištu proizvoda, on će se slomiti. Pretpostavimo da bi bilo tko zloban namjerom mogao prekršiti vašu prijavu ako je stvarno to želio.

Ovdje je ključno da se ne posjeduju podaci koji bi hakeru bili vrlo dobri. Nitko ne pljačka banku koja nema novca. Ako dizajnirate SaaS proizvod, vjerojatno vam je potrebna autentifikacija i mrežno plaćanje. Postoji puno trećih strana koje se možete integrirati s tim će se baviti na puno bolji način nego što ste možda mogli.

Na primjer, Auth0 je najpoznatija treća strana koja tretira provjeru autentičnosti. Stripe je također dobra opcija za online plaćanje. Posvetit će sve svoje resurse i najbolje timove sigurnosnog inženjeringa na planeti da vaše podatke čuvaju - ili nemaju posao.

Stvarni znak na automobilu u San Franciscu

Usluge u oblaku su vam najbolji prijatelji

U tom smo trenutku imali način pohranjivanja svih naših podataka, provjere autentičnosti, internetskog plaćanja i web aplikacije koju su klijenti mogli koristiti zajedno s API-jem koji bismo mogli prodati partnerima za različite slučajeve upotrebe. Naša je baza korisnika rasla i postalo je očito da žele moći pristupiti aplikaciji u bilo kojem trenutku. Pa je vrijeme bilo za razmišljanje o skalabilnosti i dostupnosti.

Oslanjali smo se na jedan poslužitelj, ali mogao je obraditi samo toliko zahtjeva, a promjena poslužitelja ili puštanje nove verzije značilo bi skidanje aplikacije tijekom izdanja. Naši sljedeći prioriteti bili su: izravnavanje opterećenja, automatsko skaliranje, evidentiranje, replikacija i automatizirane sigurnosne kopije. Naravno, ako ste jedini inženjer u svojoj tvrtki, pokušati rješavanje svih ovih pitanja biti potpuno ludilo.

Srećom živimo u vremenu kada samo jedan inženjer koji ima dobro zaokružen oblik može lako izgraditi takav sustav u nekoliko dana koristeći Cloud usluge poput Amazon Web Services, Google Cloud Services ili Azure. Odlučili smo premjestiti naše sustave na AWS jer je u to vrijeme bilo najcjelovitije rješenje i imali smo 2 godine besplatnih kredita.

Zbog toga ću uglavnom razgovarati o AWS rješenjima u ovom postu, ali postoje slične usluge i na ostalim platformama. Ovo je ujedno i vrijeme koje smo odabrali za pokretanje modula u Docker spremnicima iz puno različitih razloga koji neće biti obuhvaćeni u ovom postu (možete pročitati ovaj članak za više informacija: https://medium.freecodecamp.org / Amazon-fargate-zbogom-infrastrukture-3b66c7e3e413).

Način na koji se odlučite pokrenuti aplikacije ovisi o vašem načinu upotrebe, poput fleksibilnosti koja vam treba u odnosu na vrijeme koje možete potrošiti na upravljanje svojom infrastrukturom.

Nema dobrog ili lošeg odgovora.

Možete odlučiti spremiti sve svoje module i koristiti sustav upravljanja spremnikom poput ECS / EKS u AWS ili Kubernetesov motor u GCP-u. Ako ne, i ne želite se samostalno baviti stvarima poput automatskog skaliranja i balansiranja opterećenja, možete koristiti Elastic Beanstalk ili App Engine.

Ako želite ići bez servera, možete kombinirati i korištenje Lambda funkcija i API Gateway. Odlučili smo ići za ECS. Rasporedili smo 3 slučaja u 3 zone dostupnosti, balansiranje opterećenja, postavili automatsko skaliranje ovisno o upotrebi CPU-a, integrirali sve zapisnike naših spremnika s Cloudwatchom i postavili metrike za gledanje pogrešaka, vanjskih poziva i vremena odgovora API-ja.

Velika dostupnost: Jeste li znali da žirafe gotovo nikad ne spavaju? 99% produžetka

Za našu bazu podataka koristili smo MongoDB, jer je naš model dobro prilagođen za NoSQL bazu podataka i njezinu visoku konzistentnost. Odlučili smo iskoristiti MongoDB Atlas i primijenili 3 replike kako bismo omogućili veliku dostupnost. Među ostalim uslugama, Atlas pruža automatsko skaliranje, automatizirane sigurnosne kopije i omogućava vam besprijekorno vraćanje u vremenu u slučaju katastrofe.

Također smo odlučili ugostiti sve naše statičke web datoteke u S3 i koristili Cloudfront kao CDN tako da se naše JS aplikacije mogu brzo učitati bilo gdje u svijetu i poslužiti ih onoliko puta koliko je zatraženo. Cloudflare je također dobra opcija i nudi DDOS zaštitu van okvira.

Radi jednostavnosti, odlučili smo koristiti Route 53 kao naš DNS koristeći njihove servere imena za sve naše domene. Ovo je jedan od mojih najdražih servisa na AWS-u. To vam olakšava život. Svaki put kada želite nešto poslužiti putem naziva domene, bilo da se radi o EC2 instanci, elastičnom IP-u, balansiranju opterećenja, distribuciji Cloudfronta ili bilo čemu drugom, privatno ili javno, potrebno vam je nekoliko minuta jer je tako dobro integriran sa svim druge usluge.

Kombinirajte to s Upraviteljem certifikata koji vam omogućuje da besplatno dobijete SSL certifikate (uključeni zamjenski znakovi) besplatno u nekoliko minuta i da ih implementirate na sve svoje poslužitelje označavanjem okvira, a imate najbrži i najpouzdaniji način da omogućite HTTPS na svim svojim modulima. Zbogom “Šifrirajmo” SSL certifikate koje sam morao obnavljati i instalirati na svoje poslužitelje svaka 3 mjeseca ili tako dalje .

Počevši izgledati pristojno

Odlučite se za strategiju predmemoriranja

Svi mrze upravljanje predmemorijom, keširanje se može dogoditi na mnogim različitim slojevima, a probleme vezane uz predmemoriju teško je reproducirati i moguće je uklanjanje pogrešaka u noćnoj mori.

Nažalost, performanse distribuiranih sustava uvelike se oslanjaju na dobru strategiju predmemoriranja. Postoji mnogo dobrih članaka o dobroj strategiji predmemoriranja pa neću ulaziti u mnoge pojedinosti. Samo znate da ako su vaši statički resursi web teški, vjerojatno ćete htjeti iskoristiti predmemoriju svog korisničkog preglednika tako što pametno koristite zaglavlje upravljanja predmemorijom.

Ako se stranice vašeg korisnika sučelja generiraju na aplikacijskim poslužiteljima, upotrebljavajte proxy za predmemoriranje poput Squid. Najvažnije je da postoji velika vjerojatnost da ćete svakoga dana postavljati iste zahtjeve svojoj bazi podataka. Da biste smanjili učitavanje baze podataka i uštedjeli na vremenu prijenosa podataka, koristite sustav za spremanje memorijskih objekata poput memoriranog za objekte koji se često koriste i rijetko se ažuriraju.

Počeli smo razmišljati o upotrebi memcachea jer smo često iznova i iznova tražili iste profile kandidata i ponude za posao. Primjena na uređaju koji je optimiziran za memoriju povećala je našu performansu API-ja za više od 30% kada prosječno primjenjujemo sva vremena odgovora na zahtjeve. Memcached je distribuiran i tako da se može pokrenuti na različitim poslužiteljima, ali i dalje djeluje kao da je to samo jedan veliki memorijski prostor za pohranu vaših predmeta.

cache, cache posvuda

Lokacija, lokacija, lokacija

Sada imamo distribuirani sustav koji nema ni jednu točku kvara (ako uzmete u obzir AWS ELBs i raspoređeni memorirani memorijski prijenos) i može se automatski skalirati gore i dolje. Koristimo i predmemoriranje da smanjimo mrežni prijenos podataka. Izgleda prilično dobro. U tom trenutku vjerojatno želite izvršiti reviziju svojih trećih strana da biste vidjeli hoće li oni prihvatiti teret kao i vi.

No ipak, neki se korisnici žalili kako im je aplikacija malo sporija, pogotovo kada prenose datoteke. Zapravo, čak i ako su naše statičke web datoteke spremljene u cijelom svijetu (ljubaznošću CDN-a), svi su naši poslužitelji aplikacija raspoređeni samo na zapadu SAD-a. Korisnici iz Istočne Azije iskusili su znatno veće kašnjenje, posebno za velike prijenos podataka.

Rješenje je bilo jednostavno: rasporediti isti ECS klaster na novu regiju u Aziji zajedno s novim balansom opterećenja i pouzdati se u Route 53 Geoproximity Routing kako bi korisnike usmjeravao do „najbližeg“ balansiranog opterećenja. MongoDB Atlas također vam omogućuje raspoređivanje replika po regijama, tako da nije bilo potrebno dodatno raditi.

I evo nas! Naš distribuirani sustav je spreman.

Zaključak

Iako je distribuirani sustav koji ovdje vidite pojednostavljen za ovaj post, pregledali smo dijelove koje ćete najvjerojatnije vidjeti u mnogim modernim web aplikacijama. Ostale teme povezane s, ali nisu obuhvaćene, jesu arhitektura mikroservisa, pohrana i enkripcija datoteka, pooštravanje baze podataka, planirani zadaci, asinhrono paralelno računanje ... možda u sljedećem postu!

Moja glavna stvar je: ne pokušavajte izgraditi savršen sustav kada pokrenete svoj proizvod. Većina vaših dizajnerskih izbora ovisit će o tome što vaš proizvod radi i tko ga koristi. Znat ćete samo da kada dođete do tržišta proizvoda i počnete imati dobar pregled baze korisnika, a to može potrajati i mjesecima, godinama.

Usredotočite se na pronalaženje onoga što ljudima treba i pokušajte iznaći rješenje za njihov problem, čak i ako ima puno ručnih koraka. Zatim razmislite o načinima za automatizaciju, trošite svoje vrijeme na kodiranje i uništavanje i koristite treće strane tamo gdje to ima smisla.

Ne mjerijte, ali uvijek mislite, kodajte i ne planirajte skaliranje. Izgradite svoj sustav korak po korak, ne bavite se problemima u dizajnu sustava na temelju značajki koje još nisu sazrele, a na kraju uvijek pokušajte pronaći najbolje kompromisno razdoblje između vremena koje ćete potrošiti i dobiti u radu, novcu i sniženim rizik.

Ako vam se ovaj članak svidio i bilo vam je korisno, pritisnite tipku za clap i pratite me za više članaka o arhitekturi i razvoju!