Je verzamelt dus statistieken. Zoals we zijn. We verzamelen ook statistieken. Natuurlijk noodzakelijk voor het bedrijfsleven. Vandaag zullen we het hebben over de allereerste link van ons monitoringsysteem: een statsd-compatibele aggregatieserver
Uit onze eerdere artikelen (
Bewering 1. Github, de ontwikkelaar van het project, stopte met de ondersteuning ervan: het publiceren van patches en fixes, het accepteren van de onze en (niet alleen de onze) PR. De afgelopen maanden (ergens februari-maart 2018) is de activiteit hervat, maar daarvoor was er bijna 2 jaar volledige rust. Daarnaast wordt het project ontwikkeld
Bewering 2. Nauwkeurigheid van berekeningen. Brubeck verzamelt in totaal 65536 waarden voor aggregatie. In ons geval kunnen voor sommige statistieken tijdens de aggregatieperiode (30 seconden) veel meer waarden binnenkomen (1 op de piek). Als gevolg van deze bemonstering lijken de maximale en minimale waarden nutteloos. Bijvoorbeeld zoals dit:
Zoals het was
Hoe het had moeten zijn
Om dezelfde reden worden bedragen doorgaans verkeerd berekend. Voeg hier een bug toe met een 32-bit float-overflow, die de server doorgaans naar een segfault stuurt wanneer hij een ogenschijnlijk onschuldige metriek ontvangt, en alles wordt geweldig. De bug is overigens nog niet opgelost.
En tenslotte Claim X. Op het moment dat we dit schrijven zijn we klaar om het te presenteren aan alle 14 min of meer werkende statistische implementaties die we hebben kunnen vinden. Laten we ons voorstellen dat een enkele infrastructuur zo sterk is gegroeid dat het accepteren van 4 miljoen MPS niet langer voldoende is. Of zelfs als het nog niet is gegroeid, maar de cijfers al zo belangrijk voor je zijn dat zelfs korte dips van 2 tot 3 minuten in de hitlijsten al kritiek kunnen worden en periodes van onoverkomelijke depressie onder managers kunnen veroorzaken. Omdat de behandeling van depressie een ondankbare taak is, zijn er technische oplossingen nodig.
Ten eerste fouttolerantie, zodat een plotseling probleem op de server geen psychiatrische zombie-apocalyps op kantoor veroorzaakt. Ten tweede, opschalen om meer dan 4 miljoen MPS te kunnen accepteren, zonder diep in de Linux-netwerkstack te graven en rustig “in de breedte” te groeien tot de vereiste omvang.
Omdat we ruimte hadden voor schaalvergroting, besloten we te beginnen met fouttolerantie. "OVER! Fouttolerantie! Het is simpel, we kunnen het”, dachten we en lanceerden twee servers, met op elke server een kopie van brubeck. Om dit te doen, moesten we verkeer met statistieken naar beide servers kopiëren en hier zelfs voor schrijven
Als je een beetje over het probleem nadenkt en tegelijkertijd sneeuw opgraaft met een schop, dan kan het volgende voor de hand liggende idee in je opkomen: je hebt statistieken nodig die in de gedistribueerde modus kunnen werken. Dat wil zeggen, een die synchronisatie tussen knooppunten in tijd en statistieken implementeert. “Natuurlijk bestaat zo’n oplossing waarschijnlijk al”, zeiden we en gingen naar Google…. En ze vonden niets. Na het doornemen van de documentatie voor verschillende statistieken (
En toen herinnerden we ons de 'speelgoed'-statistieken - bioyino, die was geschreven tijdens de Just for Fun-hackathon (de naam van het project werd vóór de start van de hackathon door het script gegenereerd) en beseften dat we dringend onze eigen statistieken nodig hadden. Waarvoor?
- omdat er te weinig statsd-klonen in de wereld zijn,
- omdat het mogelijk is om de gewenste of bijna de gewenste fouttolerantie en schaalbaarheid te bieden (inclusief het synchroniseren van geaggregeerde statistieken tussen servers en het oplossen van het probleem van het verzenden van conflicten),
- omdat het mogelijk is om statistieken nauwkeuriger te berekenen dan Brubeck,
- omdat u zelf meer gedetailleerde statistieken kunt verzamelen, die brubeck ons praktisch niet heeft verstrekt,
- omdat ik de kans kreeg om mijn eigen hyperperformance gedistribueerde schaallab-applicatie te programmeren, die de architectuur van een andere soortgelijke hyperfor niet volledig zal herhalen... nou ja, dat is alles.
Waar moet je op schrijven? Natuurlijk, in Roest. Waarom?
- omdat er al een prototypeoplossing bestond,
- omdat de auteur van het artikel Rust destijds al kende en er graag iets in wilde schrijven voor productie met de mogelijkheid om het in open-source te zetten,
- omdat talen met GC voor ons niet geschikt zijn vanwege de aard van het ontvangen verkeer (bijna realtime) en GC-pauzes praktisch onaanvaardbaar zijn,
- omdat je maximale prestaties nodig hebt die vergelijkbaar zijn met C
- omdat Rust ons onbevreesde gelijktijdigheid biedt, en als we het in C/C++ zouden gaan schrijven, zouden we nog meer kwetsbaarheden, bufferoverflows, racecondities en andere enge woorden hebben binnengehaald dan brubeck.
Er was ook een argument tegen Rust. Het bedrijf had geen ervaring met het maken van projecten in Rust, en nu zijn we ook niet van plan het in het hoofdproject te gebruiken. Daarom waren er ernstige angsten dat niets zou lukken, maar we besloten een gokje te wagen en het te proberen.
Verstreken tijd...
Eindelijk, na verschillende mislukte pogingen, was de eerste werkende versie klaar. Wat is er gebeurd? Dit is wat er gebeurde.
Elk knooppunt ontvangt zijn eigen set metrieken en verzamelt deze, en voegt geen metrieken samen voor de typen waarvoor de volledige set nodig is voor de uiteindelijke aggregatie. De knooppunten zijn met elkaar verbonden door een soort gedistribueerd slotprotocol, waarmee je de enige kunt selecteren (hier riepen we) die het waard is om statistieken naar de Grote te sturen. Dit probleem wordt momenteel opgelost door
UDP-pakketten met statistieken zijn onevenwichtig tussen knooppunten op netwerkapparatuur via een eenvoudige Round Robin. Uiteraard parseert de netwerkhardware de inhoud van pakketten niet en kan daarom veel meer dan 4 miljoen pakketten per seconde ophalen, om nog maar te zwijgen van meetgegevens waar het helemaal niets van weet. Als we er rekening mee houden dat de statistieken niet één voor één in elk pakket voorkomen, verwachten we op dit punt geen prestatieproblemen. Als een server crasht, detecteert het netwerkapparaat dit snel (binnen 1-2 seconden) en verwijdert het de gecrashte server uit de rotatie. Als resultaat hiervan kunnen passieve (d.w.z. niet-leider) knooppunten praktisch aan en uit worden gezet zonder dat er tekenen van dalingen op de kaarten optreden. Het maximum dat we verliezen, maakt deel uit van de statistieken die op de laatste seconde binnenkwamen. Een plotseling verlies/uitschakeling/wissel van een leider zal nog steeds een kleine anomalie veroorzaken (het interval van 30 seconden is nog steeds niet gesynchroniseerd), maar als er communicatie tussen knooppunten is, kunnen deze problemen worden geminimaliseerd, bijvoorbeeld door het verzenden van synchronisatiepakketten .
Iets over de interne structuur. De applicatie is uiteraard multithreaded, maar de threading-architectuur is anders dan die gebruikt in brubeck. De draden in Brubeck zijn hetzelfde: elk van hen is verantwoordelijk voor zowel het verzamelen als aggregeren van informatie. Bij bioyino zijn de werknemers verdeeld in twee groepen: degenen die verantwoordelijk zijn voor het netwerk en degenen die verantwoordelijk zijn voor de aggregatie. Door deze indeling kunt u de applicatie flexibeler beheren, afhankelijk van het type metriek: waar intensieve aggregatie vereist is, kunt u aggregators toevoegen, waar er veel netwerkverkeer is, kunt u het aantal netwerkstromen toevoegen. Op dit moment werken we op onze servers in 8 netwerk- en 4 aggregatiestromen.
Het tellen (verantwoordelijk voor aggregatie) is behoorlijk saai. Buffers gevuld door netwerkstromen worden verdeeld over telstromen, waar ze vervolgens worden ontleed en geaggregeerd. Op verzoek worden statistieken gegeven voor verzending naar andere knooppunten. Dit alles, inclusief het verzenden van gegevens tussen knooppunten en het werken met Consul, wordt asynchroon uitgevoerd en draait op het framework
Veel meer problemen tijdens de ontwikkeling werden veroorzaakt door het netwerkgedeelte dat verantwoordelijk was voor het ontvangen van statistieken. Het belangrijkste doel van het scheiden van netwerkstromen in afzonderlijke entiteiten was de wens om de tijd die een stroom doorbrengt te verkorten geen om gegevens uit de socket te lezen. Opties die gebruik maken van asynchrone UDP en reguliere recvmsg verdwenen snel: de eerste verbruikt te veel CPU van de gebruikersruimte voor gebeurtenisverwerking, de tweede vereist te veel contextwisselingen. Daarom wordt het nu gebruikt
Noot
In de standaardinstellingen is de buffergrootte behoorlijk groot ingesteld. Als u plotseling besluit de server zelf te proberen, kunt u tegen het feit aanlopen dat na het verzenden van een klein aantal statistieken deze niet in Graphite aankomen en in de netwerkstreambuffer achterblijven. Om met een klein aantal statistieken te werken, moet u bufsize en task-queue-size op kleinere waarden instellen in de configuratie.
Eindelijk enkele kaarten voor kaartliefhebbers.
Statistieken over het aantal binnenkomende statistieken voor elke server: meer dan 2 miljoen MPS.
Een van de knooppunten uitschakelen en binnenkomende statistieken opnieuw distribueren.
Statistieken over uitgaande statistieken: slechts één knooppunt verzendt altijd: de raid-baas.
Statistieken van de werking van elk knooppunt, rekening houdend met fouten in verschillende systeemmodules.
Detaillering van binnenkomende statistieken (statistieknamen zijn verborgen).
Wat zijn we van plan met dit alles hierna te doen? Schrijf natuurlijk code, verdomme...! Het project was oorspronkelijk bedoeld als open source en dat zal gedurende de hele levensduur zo blijven. Onze onmiddellijke plannen omvatten het overstappen naar onze eigen versie van Raft, het veranderen van het peer-protocol naar een meer draagbaar protocol, het introduceren van aanvullende interne statistieken, nieuwe soorten statistieken, bugfixes en andere verbeteringen.
Uiteraard is iedereen welkom om te helpen bij de ontwikkeling van het project: PR creëren, Issues bedenken, indien mogelijk reageren, verbeteren, etc.
Dat gezegd hebbende, dat is alles, koop onze olifanten!
Bron: www.habr.com