Over de overstap van Redis naar Redis-cluster

Over de overstap van Redis naar Redis-cluster

Als je naar een product komt dat al meer dan tien jaar in ontwikkeling is, is het helemaal niet verrassend dat er verouderde technologieën in voorkomen. Maar wat als je over zes maanden de belasting tien keer hoger moet houden en de kosten van vallen honderden keren zullen stijgen? In dit geval heb je een coole Highload Engineer nodig. Maar bij gebrek aan een dienstmeisje vertrouwden ze mij de oplossing van het probleem toe. In het eerste deel van het artikel vertel ik hoe we van Redis naar Redis-cluster zijn gegaan, en in het tweede deel geef ik advies over hoe je het cluster kunt gaan gebruiken en waar je op moet letten bij het gebruik ervan.

Technologie selectie

Is het zo erg? afzonderlijke Redis (standalone redis) in een configuratie van 1 master en N slaves? Waarom noem ik het verouderde technologie?

Nee, zo slecht is Redis niet... Er zijn echter enkele tekortkomingen die niet kunnen worden genegeerd.

  • Ten eerste ondersteunt Redis geen noodherstelmechanismen na een masterfout. Om dit probleem op te lossen, hebben we een configuratie gebruikt met automatische overdracht van VIP's naar een nieuwe master, waarbij de rol van een van de slaven werd gewijzigd en de rest werd omgeschakeld. Dit mechanisme werkte, maar het kon geen betrouwbare oplossing worden genoemd. Ten eerste vonden er valse alarmen plaats, en ten tweede was het wegwerpbaar, en na gebruik waren handmatige acties nodig om de veer op te laden.

  • Ten tweede leidde het hebben van slechts één master tot het probleem van sharding. We moesten verschillende onafhankelijke clusters creëren, “1 master en N slaves”, en vervolgens de databases handmatig over deze machines verdelen, in de hoop dat een van de databases morgen niet zo groot zou worden dat deze naar een aparte instance zou moeten worden verplaatst.

Wat zijn de opties?

  • De duurste en rijkste oplossing is Redis-Enterprise. Dit is een boxed-oplossing met volledige technische ondersteuning. Ondanks dat het er vanuit technisch oogpunt ideaal uitziet, paste het ons om ideologische redenen niet.
  • Opnieuw distribueren-cluster. Standaard is er ondersteuning voor master failover en sharding. De interface verschilt bijna niet van de reguliere versie. Het ziet er veelbelovend uit, over de valkuilen zullen we het later hebben.
  • Tarantool, Memcache, Aerospike en anderen. Al deze tools doen vrijwel hetzelfde. Maar elk heeft zijn eigen tekortkomingen. We hebben besloten om niet al onze eieren in één mandje te leggen. We gebruiken Memcache en Tarantool voor andere taken, en vooruitkijkend zal ik zeggen dat er in onze praktijk meer problemen mee waren.

Bijzonderheden van gebruik

Laten we eens kijken welke problemen we historisch gezien hebben opgelost met Redis en welke functionaliteit we hebben gebruikt:

  • Cache vóór verzoeken aan externe diensten zoals 2GIS | Golang

    KRIJG SET MGET MSET "SELECT DB"

  • Cache vóór MYSQL | PHP

    KRIJG SET MGET MSET SCAN "SLEUTEL OP PATROON" "SELECT DB"

  • De hoofdopslag voor de service van het werken met sessies en chauffeurscoördinaten | Golang

    GET SET MGET MSET "SELECT DB" "ADD GEO KEY" "GET GEO KEY" SCANNEN

Zoals je kunt zien, geen hogere wiskunde. Wat is dan de moeilijkheid? Laten we elke methode afzonderlijk bekijken.

werkwijze
beschrijving
Kenmerken van Redis-cluster
beslissing

MAAK JE KLAAR
Schrijf/lees-toets

MGET MSET
Schrijf/lees meerdere sleutels
De sleutels bevinden zich op verschillende knooppunten. Kant-en-klare bibliotheken kunnen slechts meerdere bewerkingen binnen één knooppunt uitvoeren
Vervang MGET door een pijplijn met N GET-bewerkingen

SELECTEER DB
Selecteer de basis waarmee we gaan werken
Ondersteunt geen meerdere databases
Zet alles in één database. Voeg voorvoegsels toe aan sleutels

SCAN
Doorloop alle sleutels in de database
Omdat we één database hebben, is het te duur om alle sleutels in het cluster te doorzoeken
Handhaaf een invariant binnen één sleutel en voer een HSCAN uit op deze sleutel. Of volledig weigeren

GEO
Bewerkingen met een geosleutel
De geokey is niet geshard

SLEUTEL PER PATROON
Een sleutel zoeken op patroon
Omdat we één database hebben, zoeken we in alle sleutels in het cluster. Te duur
Weiger of handhaaf de invariant, zoals in het geval van SCAN

Redis versus Redis-cluster

Wat verliezen we en wat winnen we als we overstappen naar een cluster?

  • Nadelen: we verliezen de functionaliteit van verschillende databases.
    • Als we logisch niet-gerelateerde gegevens in één cluster willen opslaan, zullen we krukken in de vorm van voorvoegsels moeten maken.
    • We verliezen alle “basis” -bewerkingen, zoals SCAN, DBSIZE, CLEAR DB, enz.
    • Multi-operaties zijn veel moeilijker te implementeren geworden omdat er mogelijk toegang tot meerdere knooppunten nodig is.
  • voordelen:
    • Fouttolerantie in de vorm van master failover.
    • Sharding aan de Redis-kant.
    • Breng gegevens atomair en zonder downtime over tussen knooppunten.
    • Voeg capaciteit en lading toe en herverdeel deze zonder downtime.

Ik zou concluderen dat als je geen hoog niveau van fouttolerantie hoeft te bieden, de overstap naar een cluster niet de moeite waard is, omdat het een niet-triviale taak kan zijn. Maar als u in eerste instantie kiest tussen een aparte versie en een clusterversie, dan moet u een cluster kiezen, aangezien dit niet slechter is en u bovendien een deel van de hoofdpijn zal verlichten

Voorbereiden om te verhuizen

Laten we beginnen met de vereisten voor verhuizen:

  • Het moet naadloos zijn. Een volledige stop van de dienst gedurende 5 minuten past niet bij ons.
  • Het moet zo veilig en geleidelijk mogelijk gebeuren. Ik wil enige controle hebben over de situatie. We willen niet alles in één keer dumpen en bidden voor de terugdraaiknop.
  • Minimaal dataverlies bij verhuizing. We begrijpen dat het erg moeilijk zal zijn om atomair te bewegen, dus staan ​​we enige desynchronisatie toe tussen gegevens in reguliere en geclusterde Redis.

Clusteronderhoud

Vlak voor de verhuizing moeten we nadenken of we het cluster kunnen ondersteunen:

  • Grafieken. We gebruiken Prometheus en Grafana om de CPU-belasting, het geheugengebruik, het aantal clients, het aantal GET-, SET-, AUTH-bewerkingen, enz. in kaart te brengen.
  • Expertise. Stel je voor dat je morgen een enorm cluster onder je verantwoordelijkheid hebt. Als het kapot gaat, kan niemand anders dan jij het repareren. Als hij begint te vertragen, zal iedereen naar je toe rennen. Als u middelen moet toevoegen of de last opnieuw moet verdelen, neem dan contact met u op. Om op 25-jarige leeftijd niet grijs te worden, is het raadzaam om in deze gevallen te voorzien en vooraf na te gaan hoe de technologie zich onder bepaalde acties zal gedragen. Laten we hier in meer detail over praten in het gedeelte 'Expertise'.
  • Monitoring en waarschuwingen. Wanneer een cluster kapot gaat, wil je daar als eerste van op de hoogte zijn. Hier hebben we ons beperkt tot een melding dat alle knooppunten dezelfde informatie retourneren over de status van het cluster (ja, het gebeurt anders). En andere problemen kunnen sneller worden opgemerkt door waarschuwingen van de Redis-clientservices.

kruising

Hoe gaan we verhuizen:

  • Allereerst moet u een bibliotheek voorbereiden om met het cluster te werken. We hebben go-redis als basis voor de Go-versie genomen en deze een beetje naar eigen wens aangepast. We hebben Multi-methoden geïmplementeerd via pijplijnen en hebben ook de regels voor herhaalde verzoeken enigszins gecorrigeerd. De PHP-versie had meer problemen, maar uiteindelijk kozen we voor php-redis. Ze hebben onlangs clusterondersteuning geïntroduceerd en het ziet er naar onze mening goed uit.
  • Vervolgens moet u het cluster zelf implementeren. Dit gebeurt letterlijk in twee opdrachten op basis van het configuratiebestand. Hieronder zullen we de instelling nader bespreken.
  • Voor geleidelijke bewegingen gebruiken we de droge modus. Omdat we twee versies van de bibliotheek hebben met dezelfde interface (één voor de reguliere versie, de andere voor het cluster), kost het niets om een ​​wrapper te maken die met een aparte versie werkt en parallel alle verzoeken aan het cluster dupliceert, vergelijk de reacties en schrijf discrepanties in de logs (in ons geval in NewRelic). Dus zelfs als de clusterversie kapot gaat tijdens de implementatie, zal onze productie daar geen last van hebben.
  • Nadat we het cluster in de droge modus hebben uitgerold, kunnen we rustig naar de grafiek met responsverschillen kijken. Als het foutenpercentage langzaam maar zeker in de richting van een kleine constante beweegt, is alles in orde. Waarom zijn er nog steeds verschillen? Omdat het opnemen in een aparte versie iets eerder plaatsvindt dan in het cluster, en door microlag, kunnen de gegevens uiteenlopen. Het enige dat overblijft is kijken naar de discrepantielogboeken, en als ze allemaal worden verklaard door de niet-atomiciteit van het record, kunnen we verder gaan.
  • Nu kunt u de droogmodus in de tegenovergestelde richting schakelen. We zullen vanuit het cluster schrijven en lezen, en het in een aparte versie dupliceren. Waarvoor? De komende week wil ik het werk van het cluster observeren. Mocht ineens blijken dat er problemen zijn bij piekbelasting, of hebben we ergens geen rekening mee gehouden, dan hebben we dankzij de dry-mode altijd een emergency rollback naar de oude code en actuele data.
  • Het enige dat overblijft is het uitschakelen van de droge modus en het ontmantelen van de afzonderlijke versie.

Expertise

Eerst kort over het clusterontwerp.

Allereerst is Redis een sleutelwaardewinkel. Willekeurige strings worden gebruikt als sleutels. Getallen, tekenreeksen en volledige structuren kunnen als waarden worden gebruikt. Van deze laatste zijn er heel veel, maar voor het begrijpen van de algemene structuur is dit voor ons niet belangrijk.
Het volgende abstractieniveau na de sleutels zijn slots (SLOTS). Elke sleutel behoort tot een van de 16 slots. Er kan een willekeurig aantal sleutels in elke gleuf zitten. Alle sleutels zijn dus verdeeld in 383 onsamenhangende sets.
Over de overstap van Redis naar Redis-cluster

Vervolgens moeten er N hoofdknooppunten in het cluster zijn. Elk knooppunt kan worden gezien als een afzonderlijk Redis-exemplaar dat alles weet over andere knooppunten binnen het cluster. Elk masterknooppunt bevat een aantal slots. Elk slot behoort tot slechts één masternode. Alle slots moeten over knooppunten worden verdeeld. Als sommige slots niet zijn toegewezen, zijn de daarin opgeslagen sleutels niet toegankelijk. Het is zinvol om elk masterknooppunt op een afzonderlijke logische of fysieke machine te laten draaien. Het is ook de moeite waard om te onthouden dat elk knooppunt slechts op één kern draait, en als u meerdere Redis-instanties op dezelfde logische machine wilt uitvoeren, zorg er dan voor dat ze op verschillende kernen draaien (we hebben dit niet geprobeerd, maar in theorie zou het moeten werken) . In wezen bieden masterknooppunten reguliere sharding, en met meer masterknooppunten kunnen schrijf- en leesverzoeken worden geschaald.

Nadat alle sleutels over de slots zijn verdeeld en de slots over de masterknooppunten zijn verspreid, kan een willekeurig aantal slave-knooppunten aan elk masterknooppunt worden toegevoegd. Binnen elk van deze master-slave-verbindingen zal normale replicatie werken. Slaven zijn nodig om leesverzoeken te schalen en voor failover in geval van masterstoring.
Over de overstap van Redis naar Redis-cluster

Laten we het nu hebben over operaties die beter zouden kunnen worden uitgevoerd.

We krijgen toegang tot het systeem via Redis-CLI. Omdat Redis geen enkel toegangspunt heeft, kunt u de volgende bewerkingen op elk van de knooppunten uitvoeren. Op elk punt vestig ik afzonderlijk de aandacht op de mogelijkheid om de operatie onder belasting uit te voeren.

  • Het eerste en belangrijkste dat we nodig hebben is de werking van de clusterknooppunten. Het retourneert de status van het cluster, toont een lijst met knooppunten, hun rollen, slotverdeling, enz. Meer informatie kan worden verkregen met behulp van clusterinfo en clusterslots.
  • Het zou leuk zijn om knooppunten toe te kunnen voegen en te verwijderen. Voor dit doel zijn er cluster meet- en cluster vergeet-bewerkingen. Houd er rekening mee dat clustervergeet moet worden toegepast op ELK knooppunt, zowel masters als replica's. En cluster meet hoeft slechts op één knooppunt te worden aangeroepen. Dit verschil kan verontrustend zijn, dus u kunt er het beste meer over weten voordat u live gaat met uw cluster. Het toevoegen van een node gebeurt veilig in de strijd en heeft op geen enkele manier invloed op de werking van het cluster (wat logisch is). Als u een knooppunt uit het cluster gaat verwijderen, moet u ervoor zorgen dat er geen slots meer op zitten (anders loopt u het risico de toegang tot alle sleutels op dit knooppunt te verliezen). Verwijder ook geen master die slaves heeft, anders wordt er onnodig op een nieuwe master gestemd. Als de knooppunten geen slots meer hebben, dan is dit een klein probleem, maar waarom hebben we extra keuzes nodig als we eerst de slaven kunnen verwijderen.
  • Als u de master- en slave-posities met kracht moet verwisselen, is de cluster failover-opdracht voldoende. Als je het in de strijd roept, moet je begrijpen dat de meester tijdens de operatie niet beschikbaar zal zijn. Normaal gesproken vindt de omschakeling plaats in minder dan een seconde, maar deze is niet atomair. U kunt verwachten dat sommige verzoeken aan de master gedurende deze tijd zullen mislukken.
  • Voordat u een knooppunt uit het cluster verwijdert, mogen er geen slots meer op zitten. Het is beter om ze opnieuw te distribueren met behulp van de opdracht cluster reshard. Slots worden van de ene master naar de andere overgedragen. De hele operatie kan enkele minuten duren, afhankelijk van de hoeveelheid gegevens die wordt overgedragen, maar het overdrachtsproces is veilig en heeft op geen enkele manier invloed op de werking van het cluster. Zo kunnen alle gegevens direct onder belasting van het ene knooppunt naar het andere worden overgedragen, zonder dat u zich zorgen hoeft te maken over de beschikbaarheid ervan. Er zijn echter ook subtiliteiten. Ten eerste gaat gegevensoverdracht gepaard met een bepaalde belasting van de ontvanger- en zenderknooppunten. Als het ontvangende knooppunt al zwaar op de processor wordt belast, moet u het niet belasten met het ontvangen van nieuwe gegevens. Ten tweede: zodra er geen enkel slot meer over is op de zendende master, zullen al zijn slaves onmiddellijk naar de master gaan waarnaar deze slots zijn overgedragen. En het probleem is dat al deze slaven gegevens in één keer willen synchroniseren. En je zult geluk hebben als het gedeeltelijke in plaats van volledige synchronisatie is. Houd hier rekening mee en combineer de handelingen van het overdragen van slots en het uitschakelen/overdragen van slaves. Of hopen dat je voldoende veiligheidsmarge hebt.
  • Wat moet u doen als u tijdens de overdracht merkt dat u ergens uw slots bent kwijtgeraakt? Ik hoop dat dit probleem geen gevolgen voor u heeft, maar als dit wel het geval is, is er een clusterfixoperatie. Op zijn minst zal ze de slots in willekeurige volgorde over de knooppunten verspreiden. Ik raad aan om de werking ervan te controleren door eerst het knooppunt met gedistribueerde slots uit het cluster te verwijderen. Omdat gegevens in niet-toegewezen slots al niet beschikbaar zijn, is het te laat om u zorgen te maken over problemen met de beschikbaarheid van deze slots. De operatie heeft op zijn beurt geen invloed op gedistribueerde slots.
  • Een andere nuttige handeling is monitoren. Hiermee kunt u in realtime de volledige lijst met verzoeken bekijken die naar het knooppunt gaan. Bovendien kunt u het oppakken en nagaan of er het nodige verkeer is.

Het is ook de moeite waard om de master failover-procedure te vermelden. Kortom, het bestaat, en naar mijn mening werkt het prima. Denk echter niet dat als u het netsnoer loskoppelt van een machine met een masternode, Redis onmiddellijk zal overschakelen en dat klanten het verlies niet zullen merken. In mijn praktijk gebeurt het schakelen binnen enkele seconden. Gedurende deze tijd zullen sommige gegevens niet beschikbaar zijn: de onbeschikbaarheid van de master wordt gedetecteerd, knooppunten stemmen voor een nieuwe, slaven worden gewisseld, gegevens worden gesynchroniseerd. De beste manier om er zeker van te zijn dat het schema werkt, is door lokale oefeningen uit te voeren. Verhoog het cluster op uw laptop, geef het een minimale belasting, simuleer een crash (bijvoorbeeld door de poorten te blokkeren) en evalueer de schakelsnelheid. Naar mijn mening kun je pas nadat je een dag of twee op deze manier hebt gespeeld, vertrouwen hebben in de werking van de technologie. Nou ja, of hopen dat de software waar de helft van het internet gebruik van maakt waarschijnlijk wel werkt.

Configuratie

Vaak is de configuratie het eerste wat je nodig hebt om met de tool aan de slag te gaan, en als alles werkt, wil je niet eens meer aan de configuratie komen. Het kost wat moeite om jezelf te dwingen terug te gaan naar de instellingen en deze zorgvuldig door te nemen. In mijn herinnering hadden we minstens twee ernstige mislukkingen als gevolg van onoplettendheid bij de configuratie. Besteed speciale aandacht aan de volgende punten:

  • time-out 0
    Tijd waarna inactieve verbindingen worden gesloten (in seconden). 0 - niet sluiten
    Niet elke bibliotheek van ons kon verbindingen correct sluiten. Door deze instelling uit te schakelen, lopen we het risico de limiet voor het aantal klanten te bereiken. Aan de andere kant, als er een dergelijk probleem is, zal de automatische beëindiging van verbroken verbindingen dit maskeren, zonder dat we het merken. Bovendien moet u deze instelling niet inschakelen als u persistente verbindingen gebruikt.
  • Bewaar xy en voeg alleen ja toe
    Een RDB-momentopname opslaan.
    We zullen RDB/AOF-kwesties hieronder in detail bespreken.
  • stop-writes-on-bgsave-fout nee & slave-serve-verouderde data ja
    Indien ingeschakeld, zal de master stoppen met het accepteren van wijzigingsverzoeken als de RDB-snapshot kapot gaat. Als de verbinding met de master wegvalt, kan de slave blijven reageren op verzoeken (ja). Of reageert niet meer (nee)
    Wij zijn niet blij met de situatie waarin Redis in een pompoen verandert.
  • repl-ping-slave-periode 5
    Na deze periode zullen we ons zorgen gaan maken dat de master defect is en dat het tijd is om de failover-procedure uit te voeren.
    U zult handmatig een balans moeten vinden tussen valse positieven en het activeren van een failover. In onze praktijk is dit 5 seconden.
  • repl-backlog-grootte 1024mb & epl-backlog-ttl 0
    We kunnen precies zoveel gegevens in een buffer opslaan voor een mislukte replica. Als de buffer opraakt, zul je volledig moeten synchroniseren.
    De praktijk leert dat het beter is om een ​​hogere waarde in te stellen. Er zijn tal van redenen waarom een ​​replica zou kunnen achterblijven. Als het achterblijft, heeft je meester hoogstwaarschijnlijk al moeite om ermee om te gaan, en volledige synchronisatie zal de druppel zijn.
  • maxclients 10000
    Maximaal aantal eenmalige klanten.
    Onze ervaring is dat het beter is om een ​​hogere waarde in te stellen. Redis verwerkt prima 10k-verbindingen. Zorg ervoor dat er voldoende aansluitingen op het systeem aanwezig zijn.
  • maxmemory-beleid vluchtig-ttl
    De regel waarmee sleutels worden verwijderd wanneer de beschikbare geheugenlimiet wordt bereikt.
    Wat hier belangrijk is, is niet de regel zelf, maar het begrip van hoe dit zal gebeuren. Redis kan worden geprezen om zijn vermogen om normaal te werken wanneer de geheugenlimiet is bereikt.

RDB- en AOF-problemen

Hoewel Redis zelf alle informatie in het RAM-geheugen opslaat, is er ook een mechanisme om gegevens op schijf op te slaan. Meer precies, drie mechanismen:

  • RDB-snapshot - een volledige momentopname van alle gegevens. Stel in met behulp van de SAVE XY-configuratie en luidt: "Bewaar elke X seconden een volledige momentopname van alle gegevens als ten minste Y-sleutels zijn gewijzigd."
  • Bestand dat alleen kan worden toegevoegd: een lijst met bewerkingen in de volgorde waarin ze worden uitgevoerd. Voegt elke X seconden of elke Y-bewerking nieuwe binnenkomende bewerkingen toe aan het bestand.
  • RDB en AOF zijn een combinatie van de vorige twee.

Alle methoden hebben hun voor- en nadelen, ik zal ze niet allemaal opsommen, ik zal alleen de aandacht vestigen op punten die naar mijn mening niet voor de hand liggen.

Ten eerste vereist het opslaan van een RDB-snapshot het aanroepen van FORK. Als er veel gegevens zijn, kan heel Redis hierdoor enkele milliseconden tot een seconde vastlopen. Bovendien moet het systeem geheugen toewijzen voor een dergelijke momentopname, wat leidt tot de noodzaak om een ​​dubbele RAM-voorraad op de logische machine aan te houden: als 8 GB wordt toegewezen voor Redis, dan zou 16 GB beschikbaar moeten zijn op de virtuele machine met Het.

Ten tweede zijn er problemen met gedeeltelijke synchronisatie. In de AOF-modus kan, wanneer de slave opnieuw wordt aangesloten, in plaats van gedeeltelijke synchronisatie een volledige synchronisatie worden uitgevoerd. Waarom dit gebeurt, kon ik niet begrijpen. Maar het is de moeite waard om dit te onthouden.

Deze twee punten doen ons al nadenken of we deze gegevens echt nodig hebben op de schijf als alles al door slaven is gedupliceerd. Gegevens kunnen alleen verloren gaan als alle slaves uitvallen, en dit is een probleem op het niveau van “brand in de DC”. Als compromis kunt u voorstellen om alleen gegevens op slaves op te slaan, maar in dit geval moet u ervoor zorgen dat deze slaves tijdens een noodherstel nooit een master zullen worden (hiervoor is er een slave-prioriteitinstelling in hun configuratie). Voor onszelf denken we in elk specifiek geval na of het nodig is om gegevens op schijf op te slaan, en meestal is het antwoord "nee".

Conclusie

Concluderend hoop ik dat ik een algemeen idee heb kunnen geven van hoe redis-cluster werkt voor degenen die er helemaal nog nooit van hebben gehoord, en ook de aandacht heb kunnen vestigen op enkele niet voor de hand liggende punten voor degenen die het hebben gebruikt voor een lange tijd.
Bedankt voor uw tijd en zoals altijd zijn opmerkingen over dit onderwerp welkom.

Bron: www.habr.com

Voeg een reactie