Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Den moderna webben är nästan otänkbar utan medieinnehåll: nästan varje mormor har en smartphone, alla är på sociala nätverk och driftstopp i underhållet är kostsamt för företag. Här är en utskrift av företagets historia Badoo om hur hon organiserade leveransen av foton med hjälp av en hårdvarulösning, vilka prestandaproblem hon stötte på i processen, vad som orsakade dem och hur dessa problem löstes med en mjukvarulösning baserad på Nginx, samtidigt som feltolerans säkerställdes på alla nivåer (video). Vi tackar författarna till Olegs berättelse Sannis Efimova och Alexandra Dymova, som delade med sig av sina erfarenheter på konferensen Upptid dag 4.

— Låt oss börja med en liten introduktion om hur vi lagrar och cachar bilder. Vi har ett lager där vi lagrar dem och ett lager där vi cachelagrar bilderna. Samtidigt, om vi vill uppnå en hög trickhastighet och minska belastningen på lagring, är det viktigt för oss att varje foto av en enskild användare finns på en cachningsserver. Annars skulle vi behöva installera lika många gånger fler diskar som vi har fler servrar. Vår trickrate är runt 99%, det vill säga vi minskar belastningen på vår lagring med 100 gånger, och för att göra detta, för 10 år sedan, när allt detta byggdes, hade vi 50 servrar. Därför behövde vi i princip 50 externa domäner som dessa servrar betjänar för att kunna visa dessa foton.

Naturligtvis uppstod frågan omedelbart: om en av våra servrar går ner och blir otillgänglig, vilken del av trafiken förlorar vi? Vi tittade på vad som fanns på marknaden och bestämde oss för att köpa en hårdvara så att den skulle lösa alla våra problem. Valet föll på lösningen från F5-nätverksföretaget (som för övrigt nyligen köpte NGINX, Inc): BIG-IP Local Traffic Manager.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Vad den här hårdvaran (LTM) gör: det är en järnrouter som gör järnredundans för sina externa portar och låter dig dirigera trafik baserat på nätverkstopologin, på vissa inställningar och gör hälsokontroller. Det var viktigt för oss att den här hårdvaran kunde programmeras. Följaktligen skulle vi kunna beskriva logiken i hur fotografier av en specifik användare serverades från en specifik cache. Vad ser det ut som? Det finns en hårdvara som tittar på Internet på en domän, en IP, gör ssl-avlastning, analyserar http-förfrågningar, väljer ett cachenummer från IRule, vart den ska gå och låter trafik gå dit. Samtidigt gör den hälsokontroller, och i händelse av att någon maskin var otillgänglig gjorde vi på den tiden så att trafiken gick till en backupserver. Ur konfigurationssynpunkt finns det naturligtvis några nyanser, men i allmänhet är allt ganska enkelt: vi registrerar ett kort, korrespondens med ett visst nummer till vår IP på nätverket, vi säger att vi kommer att lyssna på portar 80 och 443 säger vi att om servern inte är tillgänglig måste du skicka trafik till backupen, i det här fallet den 35:e, och vi beskriver en massa logik om hur den här arkitekturen ska demonteras. Det enda problemet var att språket som hårdvaran programmerades på var Tcl. Om någon minns detta alls... detta språk är mer skrivbart än ett språk som är bekvämt för programmering:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Vad fick vi? Vi fick en hårdvara som säkerställer hög tillgänglighet för vår infrastruktur, dirigerar all vår trafik, ger hälsofördelar och bara fungerar. Dessutom fungerar det ganska länge: under de senaste 10 åren har det inte förekommit några klagomål om det. I början av 2018 skickade vi redan cirka 80 80 bilder per sekund. Detta är någonstans runt XNUMX gigabit trafik från båda våra datacenter.

Dock…

I början av 2018 såg vi en ful bild på listorna: tiden det tog att skicka bilder hade ökat klart. Och det slutade passa oss. Problemet är att detta beteende bara var synligt under trafikstoppen - för vårt företag är detta natten från söndag till måndag. Men resten av tiden betedde sig systemet som vanligt, inga tecken på misslyckande.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Ändå måste problemet lösas. Vi identifierade möjliga flaskhalsar och började eliminera dem. Först och främst utökade vi förstås externa upplänkar, genomförde en fullständig granskning av interna upplänkar och hittade alla möjliga flaskhalsar. Men allt detta gav inget uppenbart resultat, problemet försvann inte.

En annan möjlig flaskhals var prestandan för själva fotocacharna. Och vi bestämde att problemet kanske ligger hos dem. Jo, vi utökade prestandan – främst nätverksportar på fotocacher. Men återigen sågs ingen tydlig förbättring. Till slut ägnade vi stor uppmärksamhet åt själva LTM:s prestanda, och här såg vi en sorglig bild på graferna: belastningen på alla CPU:er börjar gå smidigt, men kommer sedan plötsligt till en platå. Samtidigt slutar LTM att svara adekvat på hälsokontroller och upplänkar och börjar slumpmässigt stänga av dem, vilket leder till allvarlig prestandaförsämring.

Det vill säga vi har identifierat källan till problemet, identifierat flaskhalsen. Det återstår att bestämma vad vi ska göra.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Det första, mest uppenbara vi kan göra är att på något sätt modernisera själva LTM. Men det finns några nyanser här, eftersom den här hårdvaran är ganska unik, du kommer inte att gå till närmaste stormarknad och köpa den. Detta är ett separat kontrakt, ett separat licenskontrakt, och det kommer att ta mycket tid. Det andra alternativet är att börja tänka själv, komma på din egen lösning med dina egna komponenter, helst med hjälp av ett open access-program. Allt som återstår är att bestämma exakt vad vi ska välja för detta och hur mycket tid vi kommer att lägga på att lösa det här problemet, eftersom användarna inte fick tillräckligt med foton. Därför måste vi göra allt detta mycket, mycket snabbt, kan man säga i går.

Eftersom uppgiften lät som att "göra något så snabbt som möjligt och använda hårdvaran som vi har", var det första vi tänkte att helt enkelt ta bort några inte särskilt kraftfulla maskiner från fronten, sätta Nginx där, som vi vet hur man arbeta och försöka implementera samma logik som hårdvaran brukade göra. Det vill säga att vi faktiskt lämnade vår hårdvara, installerade ytterligare 4 servrar som vi var tvungna att konfigurera, skapade externa domäner för dem, liknande hur det var för 10 år sedan... Vi tappade lite i tillgänglighet om dessa maskiner föll, men ännu mindre, de löste problemet med våra användare lokalt.

Följaktligen förblir logiken densamma: vi installerar Nginx, den kan göra SSL-avlastning, vi kan på något sätt programmera routinglogiken, hälsokontroller i konfigurationerna och helt enkelt duplicera logiken som vi hade tidigare.

Låt oss sitta ner och skriva inställningar. Först verkade det som att allt var väldigt enkelt, men tyvärr är det väldigt svårt att hitta manualer för varje uppgift. Därför rekommenderar vi inte att bara googla "hur man konfigurerar Nginx för foton": det är bättre att hänvisa till den officiella dokumentationen, som visar vilka inställningar som bör röras. Men det är bättre att välja den specifika parametern själv. Tja, då är allt enkelt: vi beskriver servrarna som vi har, vi beskriver certifikaten... Men det mest intressanta är faktiskt själva routinglogiken.

Först verkade det för oss att vi helt enkelt beskrev vår plats, matchade numret på vår fotocache i den, använde våra händer eller en generator för att beskriva hur många uppströms vi behöver, i varje uppströms anger vi servern till vilken trafiken ska go och en backupserver - om huvudservern inte är tillgänglig:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Men förmodligen, om allt var så enkelt, skulle vi helt enkelt gå hem och inte säga något. Tyvärr, med standardinställningarna för Nginx, som i allmänhet gjordes under många års utveckling och inte är helt lämpliga för det här fallet... ser konfigurationen ut så här: om någon uppströmsserver har ett begärandefel eller timeout, så ser Nginx alltid ut byter trafik till nästa. Dessutom, efter det första felet, inom 10 sekunder kommer servern också att stängas av, både av misstag och av timeout - detta kan inte ens konfigureras på något sätt. Det vill säga, om vi tar bort eller återställer timeout-alternativet i uppströmsdirektivet, kommer servern att stängas av, även om Nginx inte kommer att behandla denna begäran och kommer att svara med något inte särskilt bra fel.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

För att undvika detta gjorde vi två saker:

a) de förbjöd Nginx att göra detta manuellt - och tyvärr är det enda sättet att göra detta att helt enkelt ställa in inställningarna för max fel.

b) vi kom ihåg att vi i andra projekt använder en modul som låter oss göra bakgrundshälsokontroller - därför gjorde vi ganska frekventa hälsokontroller så att stilleståndstiden vid en olycka skulle vara minimal.

Tyvärr är inte detta allt heller, eftersom de första två veckorna av detta schema bokstavligen visade att TCP-hälsokontroll också är en opålitlig sak: på uppströmsservern kanske det inte är Nginx, eller Nginx i D-tillstånd, och i i detta fall kommer kärnan att acceptera anslutningen, hälsokontrollen kommer att passera, men kommer inte att fungera. Därför ersatte vi omedelbart detta med hälsokontroll http, gjorde en specifik, som, om den returnerar 200, så fungerar allt i det här skriptet. Du kan göra ytterligare logik - till exempel, när det gäller cachning av servrar, kontrollera att filsystemet är korrekt monterat:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Och detta skulle passa oss, förutom att för tillfället upprepade kretsen helt vad hårdvaran gjorde. Men vi ville göra det bättre. Tidigare hade vi en backupserver, och det är förmodligen inte så bra, för om du har hundra servrar, då är det osannolikt att en backupserver klarar belastningen när flera misslyckas samtidigt. Därför bestämde vi oss för att distribuera reservationen över alla servrar: vi gjorde helt enkelt en annan separat uppströms, skrev alla servrar där med vissa parametrar i enlighet med belastningen de kan tjäna, la till samma hälsokontroller som vi hade tidigare:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Eftersom det är omöjligt att gå till en annan uppströms inom en uppströms, var det nödvändigt att se till att om huvuduppströmmen, där vi helt enkelt spelade in den korrekta, nödvändiga fotocachen, inte var tillgänglig, gick vi helt enkelt igenom error_page till reserv, från där vi gick till backupen uppströms:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Och genom att bokstavligen lägga till fyra servrar, är detta vad vi fick: vi ersatte en del av belastningen - vi tog bort den från LTM till dessa servrar, implementerade samma logik där, med hjälp av standard hårdvara och mjukvara, och fick omedelbart bonusen att dessa servrar kan skalas, eftersom de helt enkelt kan leverera så mycket som behövs. Det enda negativa är att vi har tappat hög tillgänglighet för externa användare. Men i det ögonblicket var vi tvungna att offra detta, eftersom det var nödvändigt att omedelbart lösa problemet. Så vi tog bort en del av belastningen, det var ungefär 40 % vid den tiden, LTM kändes bra, och bokstavligen två veckor efter att problemet började, började vi skicka inte 45k förfrågningar per sekund, utan 55k. Faktum är att vi växte med 20 % - det här är helt klart den trafik som vi inte gav till användaren. Och efter det började man fundera på hur man skulle lösa det återstående problemet - att säkerställa hög extern tillgänglighet.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Vi hade en paus där vi diskuterade vilken lösning vi skulle använda för detta. Det fanns förslag för att säkerställa tillförlitlighet med hjälp av DNS, med hjälp av några hemskrivna skript, dynamiska routingprotokoll... det fanns många alternativ, men det blev redan klart att för verkligen pålitlig leverans av foton måste du införa ett annat lager som kommer att övervaka detta. Vi kallade dessa maskiner för fotodirektörer. Programvaran vi litade på var Keepalived:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Till att börja med, vad består Keepalved av? Det första är VRRP-protokollet, allmänt känt för nätverkare, placerat på nätverksutrustning som ger feltolerans till den externa IP-adress som klienter ansluter till. Den andra delen är IPVS, IP virtuell server, för att balansera mellan fotoroutrar och säkerställa feltolerans på denna nivå. Och för det tredje - hälsokontroller.

Låt oss börja med den första delen: VRRP – hur ser det ut? Det finns en viss virtuell IP, som har en post i dns badoocdn.com, där klienter ansluter. Någon gång i tiden har vi en IP-adress på en server. Keepalive-paket körs mellan servrarna via VRRP-protokollet, och om mastern försvinner från radarn - servern har startat om eller något annat, plockar backupservern automatiskt upp denna IP-adress - inga manuella åtgärder krävs. Skillnaden mellan master och backup är främst prioriterad: ju högre den är, desto större är chansen att maskinen blir en master. En mycket stor fördel är att du inte behöver konfigurera IP-adresser på själva servern, det räcker med att beskriva dem i konfigurationen, och om IP-adresserna behöver några anpassade routingregler så beskrivs detta direkt i konfigurationen, med hjälp av samma syntax som beskrivs i VRRP-paketet. Du kommer inte att stöta på några okända saker.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Hur ser detta ut i praktiken? Vad händer om en av servrarna misslyckas? Så fort mastern försvinner slutar vår backup ta emot annonser och blir automatiskt en master. Efter en tid reparerade vi mastern, startade om, höjde Keepalived - annonser kommer med högre prioritet än säkerhetskopian, och säkerhetskopian vänder automatiskt tillbaka, tar bort IP-adresser, inga manuella åtgärder behöver göras.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Därmed har vi säkerställt feltoleransen för den externa IP-adressen. Nästa del är att på något sätt balansera trafiken från den externa IP-adressen till fotoroutrarna som redan avslutar den. Allt är ganska klart med balanseringsprotokollen. Detta är antingen en enkel round-robin, eller lite mer komplexa saker, wrr, list-anslutning och så vidare. Detta beskrivs i grunden i dokumentationen, det finns inget speciellt. Men leveransmetoden... Här ska vi titta närmare på varför vi valde en av dem. Dessa är NAT, Direct Routing och TUN. Faktum är att vi omedelbart planerade att leverera 100 gigabit trafik från sajterna. Om du uppskattar behöver du 10 gigabit-kort, eller hur? 10 gigabit-kort på en server är redan utanför ramarna för åtminstone vårt koncept med "standardutrustning". Och sedan kom vi ihåg att vi inte bara ger bort lite trafik, vi ger bort bilder.

Vad är speciellt? — Enorma skillnad mellan inkommande och utgående trafik. Inkommande trafik är mycket liten, utgående trafik är mycket stor:

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Om du tittar på dessa grafer kan du se att för tillfället får regissören cirka 200 MB per sekund, det här är en mycket vanlig dag. Vi ger tillbaka 4,500 1 MB per sekund, vårt förhållande är ungefär 22/22. Det är redan klart att för att fullt ut kunna tillhandahålla utgående trafik till XNUMX arbetarservrar behöver vi bara en som accepterar denna anslutning. Det är här den direkta routingalgoritmen kommer till vår hjälp.

Vad ser det ut som? Vår fotodirektör, enligt hans tabell, överför anslutningar till fotoroutrar. Men fotoroutrar skickar returtrafik direkt till Internet, skickar den till klienten, den går inte tillbaka genom fotodirektören, så med ett minimum antal maskiner säkerställer vi fullständig feltolerans och pumpning av all trafik. I konfigurationerna ser det ut så här: vi anger algoritmen, i vårt fall är det en enkel rr, tillhandahåller den direkta routingmetoden och börjar sedan lista alla riktiga servrar, hur många av dem vi har. Vilket kommer att avgöra denna trafik. Om vi ​​har en eller två servrar till där, eller flera servrar, uppstår ett sådant behov - vi lägger bara till det här avsnittet i konfigurationen och oroar oss inte för mycket. Från sidan av riktiga servrar, från sidan av fotoroutern, kräver denna metod den mest minimala konfigurationen, den är perfekt beskriven i dokumentationen och det finns inga fallgropar där.

Det som är särskilt trevligt är att en sådan lösning inte innebär en radikal omkonstruktion av det lokala nätverket; detta var viktigt för oss; vi var tvungna att lösa detta med minimala kostnader. Om man tittar på IPVS admin kommando utdata, så får vi se hur det ser ut. Här har vi en viss virtuell server, på port 443, lyssnar, accepterar anslutningen, alla fungerande servrar listas och du kan se att anslutningen är, ge eller ta, densamma. Om vi ​​tittar på statistiken på samma virtuella server så har vi inkommande paket, inkommande anslutningar, men absolut inga utgående. Utgående anslutningar går direkt till klienten. Okej, vi kunde obalansera det. Nu, vad händer om en av våra fotoroutrar misslyckas? När allt kommer omkring är järn järn. Det kan komma i kärnpanik, det kan gå sönder, strömförsörjningen kan brinna ut. Något. Det är därför som hälsokontroller behövs. De kan vara så enkla som att kontrollera hur porten är öppen, eller något mer komplext, upp till några hemskrivna skript som till och med kontrollerar affärslogiken.

Vi stannade någonstans i mitten: vi har en https-förfrågan till en specifik plats, skriptet anropas, om det svarar med ett 200:e svar tror vi att allt är bra med den här servern, att den är levande och kan slås på ganska lätt.

Hur ser det här igen ut i praktiken? Låt oss stänga av servern för underhåll - flasha BIOS, till exempel. I loggarna har vi omedelbart en timeout, vi ser den första raden, sedan efter tre försök markeras den som "misslyckad", och den tas helt enkelt bort från listan.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Ett andra beteendealternativ är också möjligt, när VS helt enkelt är inställd på noll, men om fotot returneras fungerar det inte bra. Servern kommer upp, Nginx startar där, hälsokontroll förstår omedelbart att anslutningen fungerar, att allt är bra, och servern visas i vår lista, och belastningen börjar omedelbart appliceras på den. Inga manuella åtgärder krävs från tjänstgöringsadministratören. Servern startade om på natten - övervakningsavdelningen ringer oss inte om detta på natten. De informerar dig om att detta hände, allt är bra.

Så, på ett ganska enkelt sätt, med hjälp av ett litet antal servrar, löste vi problemet med extern feltolerans.

Allt som återstår att säga är att allt detta naturligtvis måste övervakas. Separat bör det noteras att Keepalivede, som programvara skriven för länge sedan, har en massa sätt att övervaka det, både med kontroller via DBus, SMTP, SNMP och standard Zabbix. Dessutom vet han själv hur man skriver bokstäver för nästan varje nysning, och för att vara ärlig, någon gång tänkte vi till och med stänga av det, eftersom han skriver många bokstäver för alla trafikväxlar, påslagningar, för varje IP-anslutning, och så vidare . Naturligtvis, om det finns många servrar, kan du överväldiga dig själv med dessa bokstäver. Vi övervakar nginx på fotoroutrar med standardmetoder, och hårdvaruövervakning har inte försvunnit. Vi skulle naturligtvis råda två saker till: för det första externa hälsokontroller och tillgänglighet, för även om allt fungerar, faktiskt, kanske användare inte får bilder på grund av problem med externa leverantörer eller något mer komplext. Det är alltid värt att ha någonstans på ett annat nätverk, i Amazon eller någon annanstans, en separat maskin som kan pinga dina servrar från utsidan, och det är också värt att använda antingen anomalidetektering, för de som vet hur man gör knepig maskininlärning, eller enkel övervakning , åtminstone för att spåra om förfrågningarna har minskat kraftigt, eller tvärtom, ökat. Det kan också vara användbart.

Låt oss sammanfatta: vi har faktiskt ersatt den järnklädda lösningen, som vid något tillfälle slutade passa oss, med ett ganska enkelt system som gör allt på samma sätt, det vill säga det ger avslutning av HTTPS-trafik och ytterligare smart routing med nödvändiga hälsokontroller. Vi har ökat stabiliteten i detta system, det vill säga vi har fortfarande hög tillgänglighet för varje lager, plus att vi har bonusen att det är ganska enkelt att skala allt på varje lager, eftersom det är standardhårdvara med standardmjukvara, dvs. , har vi förenklat diagnostisering av möjliga problem.

Vad slutade vi med? Vi hade ett problem under januarilovet 2018. Under de första sex månaderna när vi tog det här systemet i drift utökade vi det till all trafik för att ta bort all trafik från LTM, vi växte bara i trafik i ett datacenter från 40 gigabit till 60 gigabit, och samtidigt för hela 2018 år kunde skicka nästan tre gånger fler bilder per sekund.

Hur Badoo uppnådde förmågan att rendera 200 XNUMX bilder per sekund

Källa: will.com

Lägg en kommentar