Hoe we Pub / Sub-berichten comprimeren en meer, een hoop geld besparen

(29 dec.2020)

Compressie is een truc die kan worden gebruikt om een ​​hoop problemen op te lossen. Vaak zullen uw tools inhoud transparant comprimeren: de meeste moderne browsers vragen om gzipte HTTP-payload, en sommige bestandssystemen kunnen worden geconfigureerd om blokken te comprimeren zonder dat de gebruiker erom vraagt.

Buiten de bekende use-cases zijn er een scala aan mogelijkheden om de efficiëntie te verbeteren of veel geld te besparen door gebruik te maken van compressie. Het is handig om op de hoogte te zijn van veelvoorkomende gebruiksscenarios, zodat u deze kansen kunt benutten wanneer ze zich voordoen.

Logboeken migreren

Als recent voorbeeld migreerde mijn team logboeken van één Elasticsearch-cluster naar een ander. Hoewel het niet echt Big Data ™ was, had dit cluster 10 miljard logboekvermeldingen, of ongeveer 60 TB onbewerkte JSON.

Als je ervaring hebt met het aanpakken van langlopende, grootschalige migraties zoals deze, wil je een proces bouwen dat stelt u in staat om het spel zo vaak mogelijk op te slaan. Dit betekent dat u een exportproces kunt bouwen en uitvoeren, alle problemen kunt afhandelen die zich voordoen (dat zullen ze, ik beloof het!), En vervolgens netjes verder kunt gaan met het importproces. Net als bij exports, zal je importproces ook verpesten: dus het zou ook gemakkelijk opnieuw moeten kunnen worden uitgevoerd.

Omdat het wordt gebruikt op een groot aantal GoCardless-systemen, Google Pub / Sub is een natuurlijke oplossing voor dit probleem. De marketing-slogan van Google klinkt zelfs alsof deze is geschreven om ons ideale, ontkoppelde proces te beschrijven:

Pub / Sub is een asynchrone berichtenservice die services die gebeurtenissen produceren, loskoppelt van services die gebeurtenissen verwerken.

In Pub / Sub publiceert u berichten naar onderwerpen . Elk onderwerp kan veel abonnementen hebben, waarvan consumenten berichten kunnen ophalen . In de meest eenvoudige bewoordingen zou de migratie:

  1. Logboeken van het oorspronkelijke cluster exporteren naar een (per-index) Pub / Sub-onderwerp
  2. De Pub / Sub-abonnementen configureren om gebeurtenissen te behouden (stel retain\_acked\_messages, zie: Berichten afspelen en opschonen ), zodat we ze opnieuw kunnen afspelen, als onze importeren gaat fout
  3. Importeer logboeken door berichten uit de onderwerpabonnementen te halen

Dus, wat heeft dit te maken met compressie? Zoals de meeste Cloud-services, brengt Pub / Sub kosten in rekening voor gebruik, wat betekent dat we kosten in rekening brengen die evenredig zijn aan de gegevens die we door de service sturen.

Deze kosten zijn:

  • $ 40 per geleverde TiB, toegepast om te publiceren en te abonneren.
  • Google Compute Engine-netwerktarieven (we negeren deze, aangezien ze ingewikkeld worden)
  • Zoekgerelateerde berichtopslag om onze berichten bewaren voor $ 0,27 per GiB-maand

In het beste geval waarin we succesvol importeren / exporteren bij de eerste poging (dit zal niet gebeuren en is het niet gebeurd), zullen we worden 2 x $ 40 x 60TB = $ 4.800 in rekening gebracht voor berichtbezorging , aangezien dit van toepassing is op zowel publiceren als abonneren. Als we onze berichten twee weken bewaren terwijl de migratie aan de gang is, wordt 0,5 x $ 0,27 x 60.000 GB = $ 8.100 in rekening gebracht voor berichtopslag .

Dit laat een ondergrens van $ 12.900 over om de migratie uit te voeren .

Nu, GoCardless is niet slecht. En als vuistregel: u wilt normaal gesproken optimaliseren voor engineering-uren boven infrastructuurkosten.

Maar als u de kosten kunt verlagen met een minimale inspanning, zou u dat moeten doen.

Publiceren gecomprimeerde berichten

Hiertoe hebben we een kleine wijziging aangebracht in onze migratietool (elastic-toolbox) om compressie te ondersteunen van de berichten die we naar Pub / Sub hebben gepubliceerd.

Als de foutafhandeling is verwijderd, is dit de publicatiemethode, waarbij we compressie toepassen na serialisering:

Voorwaardelijk compressie toepassen op een berichtpayload

De compressie zelf is doodeenvoudig, en bijna volledig waarneembaarheidscode:

Implementatie van de gzip-compressie, met observatie

Aangezien onze besparingen evenredig zijn met onze compressieverhouding (gecomprimeerde / originele bytes), geven we er veel om comprimeerbaar onze data is.

JSON-logboeken zijn waarschijnlijk erg comprimeerbaar omdat:

  • Logboeken delen veel van de JSON-sleutels, die kunnen worden gededupliceerd (kubernetes.pod\_name)
  • Waarden van veelgebruikte logboekvelden kunnen heel vaak voorkomen (kubernetes.labels.namespace)

Met behulp van de gewijzigde elastic-toolbox om een ​​gelijktijdige export van drie verschillende indices uit te voeren, kunnen we de elastic\_toolbox\_export\_pubsub\_write\_compression\_ratio Prometheus-statistiek gebruiken (zie de compress methode hierboven) om een ​​heatmap van compressieverhoudingen te maken:

Gecomprimeerd bytes / originele bytes, altijd 0\%

Deze heatmap laat zien dat alle berichten zijn gecomprimeerd tot maximaal 30\% van de oorspronkelijke grootte . Gemeten over ons hele corpus aan logboeken, hebben we een gemiddelde van een ~ 12\% compressieverhouding, wat betekent dat 1 GB aan logboeken slechts 120 MB wordt.

Onze oorspronkelijke factuur van $ 12.900 is 12\% x $ 12.900 = $ 1.548 geworden.

Dit betekent dat we ongeveer $ 11.500 hebben bespaard.

Verken de gegevens zelf op deze Raintank Snapshot: elastic-toolbox-compressie .

Volgende stap? Solliciteer fulltime.

De meest voor de hand liggende volgende stap was om dit altijd op onze logging-pijplijn toe te passen. Aangezien we containerlogboeken rechtstreeks naar Pub / Sub verzenden en ze uit een abonnement op Elasticsearch halen, kunnen we gemakkelijk een fluentd -filter schrijven dat dezelfde compressiestrategie toepast.

Mijn collega Ben heeft een geweldig dashboard samengesteld om bij te houden hoeveel we besparen, wat neerkomt op enkele duizenden per maand :

Besparingen door het comprimeren van logboeken wanneer ze de logboekpijplijn binnenkomen

Waar kan compressie nog meer helpen?

Als u in een Cloud-omgeving werkt, zijn er zoveel mogelijkheden om bespaar geld door je gegevens te comprimeren.

Naast logboeken is een ander voorbeeld van GoCardless een tool genaamd draupnir . Deze service host kopieën van onze productiedatabases voor het testen van belasting en forensische analyse (voorspelling van queryplannen, enz.). Google SSD-opslag kost $ 187 per TiB / maand, wat betekent dat elk exemplaar van onze 5 TB Postgres $ 1.000 / maand kost .

Draupnir kan meerdere exemplaren tegelijk hosten, afhankelijk van het gebruik. We kunnen veel geld besparen door btrfs-compressie in te schakelen om de blokken van het bestandssysteem transparant te comprimeren, waardoor we kunnen gebruiken ~ 70\% minder SSD-capaciteit dan we anders zouden kunnen.

En als je dacht dat compressie beperkt was tot kostenbesparingen, zou je het mis hebben! Nadat we af en toe een kleine storing hadden ondervonden toen mensen grote aanvullingen hadden of nieuwe database-indexen bouwden, hebben we het probleem opgelost door Postgres WAL-compressie in te schakelen (zie Functies van Postgres te weinig: WAL-compressie , of de Postgres Schrijf vooruit logdocumenten ).

De storingen werden veroorzaakt door databasebewerkingen die een grote hoeveelheid WAL-churn veroorzaakten, waarbij de replica liep vast tijdens het schrijven van de WAL naar schijf. Door de WAL-stream te comprimeren, hebben we de IO-pieken aanzienlijk verminderd, waardoor de replica de stream probleemloos kan verwerken .

Er zijn meer voorbeelden, maar ik denk dat dit een goed beeld schetst.

Hoe helpt dit je?

Compressie is een afweging, een beslissing die we nemen om ruil CPU voor een andere bron die mogelijk duurder of minder beschikbaar is. De waarde die is toegewezen aan CPU, geheugen of netwerkbandbreedte verandert voortdurend, en je moet deze berekening van geval tot geval maken.

Dit bericht was bedoeld om een ​​scenario te behandelen waarin de kosten van compressie, zowel in de rekenresource als in de time-to-build, werd aanzienlijk gecompenseerd door de besparingen die het zou opleveren. Niet alle situaties zullen dezelfde economie hebben, maar het kost een paar minuten servetwiskunde om hoe dan ook te beslissen.

Ik hoop dat deze casestudy aanzet tot het overwegen van compressie buiten de standaard, saaie use-cases, en helpt om mogelijkheden te vinden waar u het op uw eigen systemen kunt toepassen.

Bespreek dit bericht op Hackernews .

Oorspronkelijk gepubliceerd op https: // blog .lawrencejones.dev op 29 december 2020.