Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 13027|Odpověď: 0

StackOverflow je tak velký, jaká je jeho architektura?

[Kopírovat odkaz]
Zveřejněno 11.04.2018 17:33:18 | | | |
Abychom vám usnadnili pochopení, o čem tento článek je, začněme změnou průměrné denní statistiky Stack Overflow. Následující údaje pocházejí ze statistik k 12. listopadu 2013:

  • Load balancer přijal 148 084 833 HTTP požadavků
  • Z toho bylo 36 095 312 naložených stránek
  • K odeslání se používá 833 992 982 627 bajtů (776 GB) HTTP provozu
  • Celkem bylo přijato 286 574 644 032 bajtů (267 GB) dat
  • Celkem bylo odesláno 1 125 992 557 312 bajtů (1 048 GB) dat
  • 334 572 103 SQL dotazů (včetně pouze HTTP požadavků)
  • 412 865 051 žádostí o Redis
  • 3 603 418 požadavků na Tag Engine
  • SQL dotazy trvaly 558 224 585 ms (155 hodin)
  • Trvalo to 99 346 916 ms (27 hodin) na žádosti o Redis
  • Na žádost o tag engine jsem strávil 132 384 059 ms (36 hodin)
  • Zpracování ASP.Net procesu trvalo 2 728 177 045 ms (757 hodin)



Následující data ukazují změny ve statistikách k 9. únoru 2016, takže můžete porovnat:

  • HTTP požadavky přijaté load balancerem: 209 420 973 (+61 336 090)
  • 66 294 789 (+30 199 477), z nichž se stránka načítá
  • HTTP data odeslaná: 1 240 266 346 053 (+406 273 363 426) bajtů (1,24 TB)
  • Celkové množství přijatých dat: 569 449 470 023 (+282 874 825 991) bajtů (569 GB)
  • Celkové množství odeslaných dat: 3 084 303 599 266 (+1 958 311 041 954) bajtů (3,08 TB)
  • SQL dotazy (pouze z HTTP požadavků): 504 816 843 (+170 244 740)
  • Návštěvy keše Redis: 5 831 683 114 (+5 418 818 063)
  • Elastic vyhledávání: 17 158 874 (nesledováno v roce 2013)
  • Požadavky na tag engine: 3 661 134 (+57 716)
  • Kumulativní čas potřebný k provedení SQL dotazů: 607 073 066 (+48 848 481) ms (168 hodin)
  • Doba spotřebování cache v Redisu: 10 396 073 (-88 950 843) ms (2,8 hodiny)
  • Čas spotřebovaný požadavky Tag enginu: 147 018 571 (+14 634 512) ms (40,8 hodin)
  • Čas spotřebovaný na zpracování ASP.Net: 1 609 944 301 (-1 118 232 744) ms (447 hodin)
  • 22,71 (-5,29) ms 49 180 275 vydavatelských stran průměrný čas vykreslování (z toho 19,12 ms je spotřebováno v ASP.Net)
  • 11,80 (-53,2) ms 6 370 076 první stránky průměrný čas vykreslování (z toho 8,81 ms je spotřebováno ve ASP.Net)



Možná vás zajímá, proč ASP.Net zpracovává o 61 milionů více požadavků denně, ale zároveň zkracuje dobu zpracování o 757 hodin (ve srovnání s rokem 2013). Je to hlavně díky vylepšením, které jsme provedli na našich serverech začátkem roku 2015, a také díky spoustě práce na optimalizaci výkonu přímo v aplikaci. Nezapomeňte: výkon je stále prodejní argument. Pokud vás více zajímají konkrétní hardwarové detaily, nebojte se, konkrétní hardwarové detaily serverů používaných k provozu těchto stránek poskytnu ve formě přílohy v příštím článku (tento odkaz aktualizuji, až přijde čas).

Co se tedy za poslední dva roky změnilo? Nic moc, jen výměna některých serverů a síťového vybavení. Zde je přehled serverů, které dnes používáte k provozu vašeho webu (všimněte si, jak se od roku 2013 změnily)

  • 4 servery Microsoft SQL Server (z nichž 2 používají nový hardware)
  • 11 IIS webových serverů (nový hardware)
  • 2 Redis servery (nový hardware)
  • 3 servery Tag Engine (2 z nich používají nový hardware)
  • 3 Elasticsearch servery (stejné jako výše)
  • 4 HAProxy servery pro vyvažování zátěže (2 přidány pro podporu CloudFlare)
  • 2 síťová zařízení (jádro Nexus 5596 + 2232TM Fabric Extender, všechna zařízení upgradována na 10Gbps šířku pásma)
  • 2 x Fortinet 800C firewall (nahrazuje Cisco 5525-X ASA)
  • 2 směrovače Cisco ASR-1001 (nahrazuje směrovače Cisco 3945)
  • 2 Cisco ASR-1001-x routery (NOVĚ!) )



Co potřebujeme, aby Stack Overflow fungoval? Od roku 2013 se toho moc nezměnilo, ale díky optimalizacím a novému hardwaru zmíněnému výše nyní potřebujeme jen jeden webový server. Tuto situaci jsme už neúmyslně otestovali a několikrát úspěšně. Upozornění: Řekl jsem jen, že to funguje, ne že je to dobrý nápad. Ale pokaždé, když se to stane, je to docela zajímavé.

Teď, když máme základní čísla o nápadech na škálování serverů, pojďme se podívat, jak jsme vytvořili tyto zajímavé webové stránky. Jen málo systémů existuje zcela nezávisle (a naše nejsou výjimkou) a bez komplexního pohledu, který tyto části integruje, je význam plánování architektury výrazně snížen. Naším cílem je pochopit celkovou situaci. V budoucnu bude mnoho článků, které se budou podrobně věnovat jednotlivým oblastem. Tento článek je pouze shrnutím logické struktury klíčového hardwaru a následující článek bude obsahovat konkrétní detaily o tomto hardwaru.

Pokud chcete vidět, jak tento hardware dnes vypadá, zde je pár fotek, které jsem pořídil skříni A (skříň B je přesně stejná jako ona) při upgradu serveru v únoru 2015:



Nyní se pojďme podívat na architektonické uspořádání. Následuje shrnutí logické architektury hlavních existujících systémů:



Základní principy

Zde jsou některé běžné principy, které není třeba postupně zavádět:

  • Všechno má zálohy na redundantní systém.
  • Všechny servery a síťová zařízení mají alespoň dvě připojení s šířkou pásma 10Gbps.
  • Všechny servery mají dva zdroje energie, které dodávají energii přes dvě sady UPS, dva generátory za nimi a dva napájecí napájecí zdroje síťového napětí.
  • Všechny servery mají zálohu umístěnou v racku A a racku B.
  • Všechny servery a služby mají dvojitě redundantní zálohy v samostatném datovém centru (v Coloradu), i když pokrývám hlavně New York.
  • Všechno má zálohy na redundantní systém.


internet

Nejprve musíte najít naši webovou stránku, což je DNS záležitost. Hledání webových stránek je rychlé, takže ho nyní předáváme CloudFlare, protože mají DNS servery v každém koutě světa. DNS záznamy aktualizujeme přes API a ty jsou zodpovědné za "správu" DNS. Nicméně v našich zlověstných myslích máme stále vlastní DNS servery kvůli hluboce zakořeněným problémům s důvěrou. Když je apokalypsa apokalyptická – možná kvůli GPL, Punyonu nebo problémům s cacheováním – a lidé stále chtějí programovat, aby odvedli pozornost, přecházíme na vlastní DNS servery.

Jakmile váš prohlížeč najde naše úkryt, HTTP provoz od našich čtyř poskytovatelů internetu (Level 3, Zayo, Cogent a Lightower v New Yorku) vstupuje do jednoho ze čtyř našich pokročilých routerů. Používáme Border Gateway Protocol (BGP, velmi standardní protokol) pro peer-to-peer provoz od poskytovatelů sítí, abychom jej kontrolovali a poskytli nejefektivnější způsob přístupu k našim službám. Směrovače ASR-1001 a ASR-1001-X jsou rozděleny do dvou skupin, z nichž každá by měla používat aktivní a aktivní režim pro zpracování provozu od obou poskytovatelů sítě – zde jsou zálohy zbytečné. Ačkoliv mají všechny stejnou fyzickou šířku pásma 10Gbps, provoz zvenčí je stále nezávislý na provozu z externí VLAN a je připojen k vyvažování zátěže zvlášť. Po průchodu provozu routerem se dostanete k load balanceru.

Myslím, že je čas zmínit, že máme MPLS s šířkou pásma 10Gbps mezi oběma datovými centry, i když to přímo nesouvisí s webovými službami. Tuto technologii využíváme k provádění replikace mimo pracoviště a rychlému obnovování dat pro řešení určitých nouzových situací. "Ale Nicku, v tomhle není žádná zbytečná záležitost!" No, z technického hlediska máte pravdu (v pozitivním smyslu), na této úrovni jde opravdu o jediný bod selhání. Ale počkejte! Prostřednictvím poskytovatele sítě máme také dvě další OSPF trasy pro failover (MPLS je první volba, a tyto jsou z důvodu nákladů druhá a třetí). Každé z výše zmíněných zařízení bude připojeno k datovému centru v Coloradu podle potřeby, aby se v případě failoveru vyrovnal síťový provoz. Samozřejmě jsme mohli tyto dvě sady zařízení propojit, takže by vznikly čtyři sady cest, ale na to zapomeňme, pojďme dál.

Vyvažování zátěže (HAProxy)

Load balancing je implementován pomocí HAProxy 1.5.15, běžícího na CentOS 7 (naše oblíbená verze Linuxu). A přidat TLS (SSL) protokol zabezpečeného přenosu na HAProxy. Sledujeme také HAProxy 1.7, který okamžitě poskytne podporu pro protokol HTTP/2.

Na rozdíl od jiných serverů s duálními 10Gbps LACP připojeními má každý load balancer dvě 10Gbps připojení: jedno pro externí síť a druhé pro DMZ. Tyto servery mají 64GB nebo více paměti, aby efektivněji zvládly SSL protokolovou vrstvu. Když můžeme více TLS relací v paměti ukládat a znovu použít, spotřebováváme méně výpočetních zdrojů při připojení ke stejnému klientovi. To znamená, že můžeme obnovovat sezení rychleji a levněji. Paměť je tak levná, že je to snadná volba.

Samotné vyvažování zátěže je snadné nastavit. Posloucháme různé weby na více různých IP adresách (hlavně kvůli správě certifikátů a DNS) a pak směrujeme provoz na různé backendy (hlavně na základě hlaviček hostů). Jediné, co zde děláme, je omezit rychlost a scrapovat některé informace z hlaviček (z webové vrstvy) pro přihlášení do systémových logů HAProxy, čímž můžeme zaznamenávat výkonnostní metriky pro každý požadavek. Podrobněji o tom zmíníme později.

Webová vrstva (IIS 8.5, ASP.Net MVC 5.2.3 a .Net 4.6.1)

Load balancing rozděluje provoz mezi 9 serverů nazývaných primárním webovým serverem (01-09) a 2 vývojovými webovými servery (10-11, naše testovací prostředí). Hlavní server provozuje Stack Overflow, Careers a všechny stránky Stack Exchange, zatímco meta.stackoverflow.com a meta.stackexchange.com běží na dvou dalších serverech. Hlavní aplikace Q&A je multi-tenant, což znamená, že jedna aplikace zpracovává všechny požadavky z Q&A webu. Jinými slovy, můžeme spustit celou aplikaci Q&A v jednom souboru aplikací na jednom serveru. Jiné aplikace jako Careers, API v2, Mobile API atd. jsou nezávislé. Tady je, co vidíte v IIS pro master a dev servery:



Zde je rozložení webové vrstvy Stack Overflow, jak je vidět v Opserveru (našem interním monitorovacím dashboardu):



A tady je spotřeba zdrojů těchto webových serverů:



Podrobněji se budu věnovat v dalším článku o tom, proč poskytujeme tolik zdrojů, se zaměřením na rolling build, volnost a redundanci.

Servisní vrstva (IIS, ASP.Net MVC 5.2.3, . NET 4.6.1 a HTTP. SYS)

Vedle webové vrstvy je servisní vrstva. Běží také na IIS 2012 ve Windows 8.5R2. Tato vrstva provozuje některé interní služby, které podporují webovou vrstvu a další interní systémy produkčního prostředí. Dvě hlavní služby jsou: "Stack Server", který spouští tagový engine a je založen na http.sys (nikoli IIS); Providence API (založené na IIS). Zajímavost: musel jsem korelovat oba procesy, abych se připojil k různým socketům, protože Stack Server často přistupoval k L2 a L3 cache při obnovování seznamu problémů v dvouminutových intervalech.

Stroje provozující tyto služby jsou kritické pro tagový engine a backend API, takže musí být redundantní, ale ne devětkrát redundantní. Například všechny články a jejich tagy načítáme z databáze každých n minut (aktuálně 2 minuty), což není málo. Nechceme tuto operaci načítání opakovat 9krát na webové vrstvě, 3krát je pro nás dostatečně bezpečné. Používáme také různé hardwarové konfigurace pro tyto servery, abychom lépe optimalizovali výpočetní a načítací charakteristiky tagového enginu a elastických indexových úloh (které také běží v této vrstvě). "Tag engine" je poměrně složité téma, které bude rozebráno v samostatném článku. Základní princip je, že když přistupujete k adrese /questions/tagged/java, navštívíte tagovací engine, abyste získali otázky, které s ní odpovídají. Engine zajišťuje veškeré párování tagů kromě /search, takže všude, včetně nové navigace, získává data právě přes tuto službu.

Cache a publikování/odběr (Redis)

Používali jsme Redis na některých místech a má pevnou stabilitu. Ačkoliv je až 160 miliard operací měsíčně, CPU na instanci nepřesahuje 2 %, což je obvykle méně:



Redis používáme pro cache systémy na úrovni L1/L2. Úroveň "L1" je HTTP cache, která funguje na webovém serveru nebo v podobné aplikaci. Úroveň "L2" slouží k získávání dat přes Redis po selhání předchozí cache úrovně. Naše data jsou uložena ve formátu Protobuf, implementovaném prostřednictvím protobuf-dot-net napsaného Marcem Gravelem. Pro klienta Redis jsme použili knihovnu StackExchange.Redis, což je open-source knihovna vyvinutá interně. Pokud webový server nezasáhne ani L1, tak L2 cache, načítá data ze svých datových zdrojů (databázové dotazy, API volání atd.) a uloží výsledky do lokální cache a Redis. Další server může chybět v L1 cache při načítání stejných dat, ale data získá v L2/Redis, čímž odpadá potřeba databázových dotazů nebo volání API.

Provozujeme také spoustu Q&A webů, z nichž každý má svou vlastní L1/L2 cache: klíč jako prefix v L1 cache a databázové ID v L2/Redis cache. Tomuto tématu se budeme věnovat v budoucích článcích.

Kromě dvou hlavních Redis serverů (jeden master a jeden slave), které provozují všechny instance lokality, jsme také nastavili instanci pro strojové učení (hlavně kvůli paměti) na dvou dalších dedikovaných slave serverech. Tato skupina serverů slouží k poskytování služeb, jako je doporučování otázek na domovské stránce a lepší párování úloh. Tato platforma se jmenuje Providence a Kevin Montrose o ní psal.

Hlavní server Redis má 256 GB RAM (asi 90 GB využito) a server Providence má 384 GB paměti (asi 125 GB využito).

Redis není určen pouze pro cache, má také mechanismus pro publikování a odběr, kdy jeden server může publikovat zprávu a ostatní odběratelé ji mohou přijímat (včetně Redis od downstream klientů na serveru). Tento mechanismus používáme k vymazání L1 cache na jiných službách, abychom udrželi konzistenci cache na webovém serveru. Ale má to ještě jedno důležité využití: websockety.

Websockety (NetGain)

Websockets používáme k posílání aktualizací v reálném čase uživatelům, jako jsou oznámení v horním panelu, hlasování, nová navigace, nové odpovědi, komentáře a další.

Samotný socket server běží na webové vrstvě a používá nativní sockety. Jedná se o velmi malou aplikaci založenou na naší open-source knihovně: StackExchange.NetGain. V době špičky jsme měli asi 500 000 současných připojení přes websocket, což je hodně prohlížečů. Zajímavost: některé z těchto prohlížečů jsou otevřené už přes 18 měsíců a budete muset najít někoho, kdo zjistí, jestli tito vývojáři ještě žijí. Následující graf ukazuje vzorec souběžnosti websocketů tento týden:



Proč používat websockety? V našem měřítku je to mnohem efektivnější než průzkumy. Tímto způsobem můžeme jednoduše posílat více dat s menšími zdroji a být pro uživatele více v reálném čase. Tento přístup však není bez problémů: dočasné porty, vyčerpané soubory na load balancerech jsou velmi zajímavé a o nich si povíme později.

Vyhledávání (Elasticsearch)

Spoiler: Tady není moc důvodů k nadšení. Webová vrstva používá Elasticsearch 1.4 a implementuje ultralehký, vysoce výkonný StackExchange.Elastic klienta. Na rozdíl od většiny věcí neplánujeme tuto část open source, protože to zpřístupňuje velmi malou podmnožinu API, které potřebujeme používat. Jsem si jistý, že zveřejnění této zprávy převáží ztrátu a jen by to vývojáře zmátlo. Používáme elastic:/search na těchto místech k výpočtu souvisejících otázek a dáváme doporučení při kladení otázek.

Každý Elastic cluster (jeden pro každé datové centrum) obsahuje 3 uzly, z nichž každý má svůj vlastní index. Stránka Careers má také další indexy. Méně standardní součástí naší konfigurace v elastických kruzích je, že náš cluster tří serverů je o něco výkonnější než obvyklá konfigurace: každý server používá SSD úložiště, 192GB paměti, duální síť s šířkou pásma 10Gbps.

Stejná aplikační doména jako Stack Server (ano, .Net Core nás tu ovlivnil) hostí také tagový engine, který také používá Elasticsearch pro kontinuální indexování. Zde používáme malý trik, například použití ROWVERSION v SQL Serveru (zdroj dat) k porovnání s dokumentem "last place" v Elastic. Protože je zřejmě sekvenční, je pro nás snadné procházet a indexovat obsah, pokud je po poslední návštěvě upraven.

Hlavním důvodem, proč používáme Elasticsearch místo technologií jako je SQL full-text search, je jeho škálovatelnost a nákladová efektivita. SQL je na CPU poměrně drahý, zatímco Elastic je mnohem levnější a v poslední době přináší spoustu nových funkcí. Proč nepoužít Solr? Musíme prohledávat napříč sítí (s více indexy současně) a Solr tento scénář v době našich rozhodnutí nepodporuje. Důvod, proč jsme ještě nepoužili 2.x, je ten, že typy se v 2.x hodně změnily, což znamená, že musíme vše znovu indexovat, pokud chceme upgradovat. Prostě nemám dost času plánovat změny požadavků a migrace.

Databáze (SQL Server)

SQL Server používáme jako jediný zdroj pravdy. Veškerá data v Elastic a Redis pocházejí ze SQL Serveru. Máme dva SQL Server clustery a jsme nakonfigurováni pomocí skupin dostupnosti AlwaysOn. Každý cluster má primární server v New Yorku (který přebírá téměř veškerou zátěž) a replika server, kromě repliky serveru v Coloradu (naše datové centrum pro obnovu po havárii). Všechny kopírovací operace jsou asynchronní.

První cluster tvoří sada serverů Dell R720xd, každý s 384GB paměti, PCIe SSD s kapacitou 4TB a dvěma 12jádrovými procesory. Patří sem Stack Overflow, Sites (to je špatný název, vysvětlím to později), PRIZM a databáze Mobile.

Druhý cluster tvoří sada serverů Dell R730xd, každý s 768GB paměti, PCIe SSD s 6TB místa a dvěma 8jádrovými procesory. Tento cluster obsahuje všechny ostatní databáze, včetně Careers, Open ID, Chat, logů výjimek a dalších Q&A stránek (např. Super User, Server Fault atd.).

Na databázové vrstvě chceme udržet využití CPU na velmi nízké úrovni, i když v praxi bude využití CPU mírně vyšší, pokud dojde k plánovaným problémům s cachováním (které právě řešíme). V současnosti jsou primárními servery NY-SQL02 a 04 a repliky serverů 01 a 03, které jsme dnes právě restartovali kvůli upgradu na SSD. Takto si vedli za posledních 24 hodin:



Naše používání SQL je velmi jednoduché. Jednoduché znamená rychle. I když některé dotazovací příkazy mohou být zvrácené, naše interakce se SQL samotným probíhá poměrně přirozeně. Máme některé starší Linq2Sql, ale všechny naše nové vývoje používají Dapper, náš open-source micro-ORM framework, který používá POCO. Vysvětlím to jinak: Stack Overflow má ve své databázi jen jednu uloženou proceduru a já ji zruším a nahradím kódem.

Knihovna

Tak si to rozmyslíme, tady jsou věci, které vám mohou pomoci přímo. Některé z nich jsem už zmínil, ale dám vám seznam mnoha open-source .Net knihoven, které udržujeme a které všichni používají. Otevíráme je jako open source, protože nemají základní obchodní hodnotu, ale mohou pomoci vývojářům po celém světě. Doufám, že je teď můžete využít:

  • Dapper (.Net Core) – Vysoce výkonný mikro-ORM framework pro ADO.Net
  • StackExchange.Redis – Vysoce výkonný klient Redis
  • MiniProfiler – lehký profiler, který používáme na každé stránce (podporuje také Ruby, Go a Node)
  • Výjimečné – Pro logování chyb v SQL, JSON, MySQL atd
  • Jil – Vysoce výkonná JSON serializace a deserializátor
  • Sigil – .Net CIL Generation Helper (používáno, když C# není dostatečně rychlý)
  • NetGain – Vysoce výkonný websocket server
  • Opserver – Monitorovací dashboard, který přímo dotazuje většinu systémů a dokáže získávat informace z Orionu, Bosunu nebo WMI
  • Bosun – Monitorovací systém na pozadí, napsaný v Go






Předchozí:enum enum kontroluje, zda je hodnota zahrnuta v enum
Další:Jak rychle najít MB
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com