sql >> Databasteknik >  >> RDS >> MariaDB

Förstå effekterna av hög latens i High Availability MySQL- och MariaDB-lösningar

Hög tillgänglighet är en hög andel av tiden som systemet fungerar och svarar enligt affärsbehoven. För produktionsdatabassystem är det vanligtvis högsta prioritet att hålla den nära 100 %. Vi bygger databaskluster för att eliminera alla enstaka felpunkter. Om en instans blir otillgänglig bör en annan nod kunna ta arbetsbördan och fortsätta därifrån. I en perfekt värld skulle ett databaskluster lösa alla våra systemtillgänglighetsproblem. Tyvärr, även om allt kan se bra ut på pappret, är verkligheten ofta annorlunda. Så var kan det gå fel?

Transaktionsdatabassystem kommer med sofistikerade lagringsmotorer. Att hålla data konsekvent över flera noder gör den här uppgiften mycket svårare. Clustering introducerar ett antal nya variabler som i hög grad beror på nätverk och underliggande infrastruktur. Det är inte ovanligt att en fristående databasinstans som kördes bra på en enda nod plötsligt fungerar dåligt i en klustermiljö.

Bland antalet saker som kan påverka klustrets tillgänglighet spelar latensproblem en avgörande roll. Men vad är latensen? Är det bara relaterat till nätverket?

Termen "latens" syftar faktiskt på flera typer av förseningar som uppstår i behandlingen av data. Det är hur lång tid det tar för en bit information att flytta från scen till en annan.

I det här blogginlägget kommer vi att titta på de två huvudsakliga högtillgänglighetslösningarna för MySQL och MariaDB, och hur de båda kan påverkas av latensproblem.

I slutet av artikeln tar vi en titt på moderna lastbalanserare och diskuterar hur de kan hjälpa dig att hantera vissa typer av latensproblem.

I en tidigare artikel skrev min kollega Krzysztof Książek om "Att hantera opålitliga nätverk när man skapar en HA-lösning för MySQL eller MariaDB". Du hittar tips som kan hjälpa dig att designa din produktionsklara HA-arkitektur och undvika några av de problem som beskrivs här.

Master-Slave-replikering för hög tillgänglighet.

MySQL master-slave replikering är förmodligen den mest populära databasklustertypen på planeten. En av de viktigaste sakerna du vill övervaka när du kör ditt master-slave replikeringskluster är slavfördröjningen. Beroende på dina applikationskrav och hur du använder din databas, kan replikeringsfördröjningen (slavfördröjning) avgöra om data kan läsas från slavnoden eller inte. Data som registrerats på master men ännu inte tillgänglig på en asynkron slav betyder att slaven har ett äldre tillstånd. När det inte är ok att läsa från en slav, skulle du behöva gå till mastern, och det kan påverka applikationens prestanda. I värsta fall kommer ditt system inte att kunna hantera all arbetsbelastning på en master.

Slavfördröjning och inaktuella data

För att kontrollera statusen för master-slav-replikeringen bör du börja med följande kommando:

SHOW SLAVE STATUS\G
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.0.3.100
                  Master_User: rpl_user
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: binlog.000021
          Read_Master_Log_Pos: 5101
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 809
        Relay_Master_Log_File: binlog.000021
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 5101
              Relay_Log_Space: 1101
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 3
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
                   Using_Gtid: Slave_Pos
                  Gtid_IO_Pos: 0-3-1179
      Replicate_Do_Domain_Ids: 
  Replicate_Ignore_Domain_Ids: 
                Parallel_Mode: conservative
1 row in set (0.01 sec)

Med hjälp av ovanstående information kan du avgöra hur bra den totala replikeringslatensen är. Ju lägre värde du ser i "Seconds_Behind_Master", desto bättre dataöverföringshastighet för replikering.

Ett annat sätt att övervaka slavfördröjning är att använda ClusterControl-replikeringsövervakning. I den här skärmdumpen kan vi se replikeringsstatusen för asymchoronous Master-Slave (2x) Cluster med ProxySQL.

Det finns ett antal saker som kan påverka replikeringstiden. Det mest uppenbara är nätverkets genomströmning och hur mycket data du kan överföra. MySQL kommer med flera konfigurationsalternativ för att optimera replikeringsprocessen. De väsentliga replikeringsrelaterade parametrarna är:

  • Parallelltillämpning
  • Logisk klockalgoritm
  • Kompression
  • Selektiv master-slav-replikering
  • Replikeringsläge

Parallelltillämpning

Det är inte ovanligt att börja replikera med att aktivera parallella processer. Anledningen till det är som standard, MySQL går med sekventiell binär loggtillämpning, och en typisk databasserver kommer med flera processorer att använda.

För att komma runt sekventiell logg, erbjuder både MariaDB och MySQL parallell replikering. Implementeringen kan skilja sig åt per leverantör och version. T.ex. MySQL 5.6 erbjuder parallell replikering så länge som ett schema separerar frågorna medan MariaDB (från och med version 10.0) och MySQL 5.7 båda kan hantera parallell replikering över scheman. Olika leverantörer och versioner kommer med sina begränsningar och funktioner så kontrollera alltid dokumentationen.

Att köra frågor via parallella slavtrådar kan påskynda din replikeringsström om du skriver tungt. Men om du inte är det, skulle det vara bäst att hålla sig till den traditionella entrådiga replikeringen. För att aktivera parallell bearbetning, ändra slave_parallel_workers till antalet CPU-trådar du vill involvera i processen. Det rekommenderas att hålla värdet lägre än antalet tillgängliga CPU-trådar.

Parallell replikering fungerar bäst med gruppbeslut. För att kontrollera om du har gruppbekräftelser som sker, kör följande fråga.

show global status like 'binlog_%commits';

Ju större förhållandet är mellan dessa två värden desto bättre.

Logisk klocka

Slave_parallel_type=LOGICAL_CLOCK är en implementering av en Lamport-klockalgoritm. När du använder en flertrådad slav anger denna variabel metoden som används för att bestämma vilka transaktioner som får utföras parallellt på slaven. Variabeln har ingen effekt på slavar för vilka multithreading inte är aktiverad, så se till att slave_parallel_workers är högre än 0.

MariaDB-användare bör också kolla optimistiskt läge introducerat i version 10.1.3 eftersom det också kan ge dig bättre resultat.

GTID

MariaDB kommer med en egen implementering av GTID. MariaDBs sekvens består av en domän, server och transaktion. Domäner tillåter replikering med flera källor med distinkt ID. Olika domän-ID:n kan användas för att replikera den del av data som inte fungerar (parallellt). Så länge det är okej för din applikation kan detta minska replikeringsfördröjningen.

Den liknande tekniken gäller för MySQL 5.7 som också kan använda multisource master och oberoende replikeringskanaler.

Kompression

CPU-kraften blir billigare med tiden, så att använda den för binlog-komprimering kan vara ett bra alternativ för många databasmiljöer. Parametern slave_compressed_protocol talar om för MySQL att använda komprimering om både master och slav stöder det. Som standard är denna parameter inaktiverad.

Från och med MariaDB 10.2.3 kan valda händelser i den binära loggen valfritt komprimeras för att spara nätverksöverföringarna.

Replikeringsformat

MySQL erbjuder flera replikeringslägen. Att välja rätt replikeringsformat hjälper till att minimera tiden för att skicka data mellan klusternoderna.

Multimaster-replikering för hög tillgänglighet

Vissa applikationer har inte råd att använda föråldrad data.

I sådana fall kanske du vill tvinga fram konsekvens över noderna med synkron replikering. Att hålla data synkront kräver ett extra plugin, och för vissa är den bästa lösningen på marknaden för det Galera Cluster.

Galera kluster kommer med wsrep API som ansvarar för att överföra transaktioner till alla noder och exekvera dem enligt en klusteromfattande ordning. Detta kommer att blockera exekveringen av efterföljande frågor tills noden har tillämpat alla skrivuppsättningar från sin appliceringskö. Även om det är en bra lösning för konsekvens, kan du drabbas av några arkitektoniska begränsningar. De vanliga latensproblemen kan relateras till:

  • Den långsammaste noden i klustret
  • Horisontell skalning och skrivoperationer
  • Geolokaliserade kluster
  • Hög ping
  • Transaktionsstorlek

Den långsammaste noden i klustret

Genom designen kan skrivprestandan för klustret inte vara högre än prestandan för den långsammaste noden i klustret. Starta din klustergranskning genom att kontrollera maskinresurserna och verifiera konfigurationsfilerna för att se till att alla körs med samma prestandainställningar.

Parallellisering

Parallella trådar garanterar inte bättre prestanda, men det kan påskynda synkroniseringen av nya noder med klustret. Statusen wsrep_cert_deps_distance talar om för oss den möjliga graden av parallellisering. Det är värdet på medelavståndet mellan högsta och lägsta sekvensvärde som eventuellt kan appliceras parallellt. Du kan använda statusvariabeln wsrep_cert_deps_distance för att bestämma det maximala antalet möjliga slavtrådar.

Horisontell skalning

Genom att lägga till fler noder i klustret har vi färre punkter som kan misslyckas; informationen måste dock gå över flera instanser tills den har begåtts, vilket multiplicerar svarstiderna. Om du behöver skalbara skrivningar, överväg en arkitektur baserad på skärning. En bra lösning kan vara en Spider-lagringsmotor.

I vissa fall, för att minska information som delas mellan klusternoderna, kan du överväga att ha en författare åt gången. Det är relativt enkelt att implementera när du använder en lastbalanserare. När du gör detta manuellt, se till att du har en procedur för att ändra DNS-värdet när din skrivarnod går ner.

Geolokaliserade kluster

Även om Galera Cluster är synkront är det möjligt att distribuera ett Galera Cluster över datacenter. Synkron replikering som MySQL Cluster (NDB) implementerar en två-fas commit, där meddelanden skickas till alla noder i ett kluster i en "prepare" fas, och en annan uppsättning meddelanden skickas i en "commit" fas. Det här tillvägagångssättet är vanligtvis inte lämpligt för geografiskt skilda noder, på grund av latenserna i att skicka meddelanden mellan noder.

Hög ping

Galera Cluster med standardinställningarna hanterar inte bra hög nätverkslatens. Om du har ett nätverk med en nod som visar en hög pingtid, överväg att ändra parametrarna evs.send_window och evs.user_send_window. Dessa variabler definierar det maximala antalet datapaket i replikering åt gången. För WAN-inställningar kan variabeln ställas in på ett betydligt högre värde än standardvärdet på 2. Det är vanligt att ställa in den på 512. Dessa parametrar är en del av wsrep_provider_options.

--wsrep_provider_options="evs.send_window=512;evs.user_send_window=512"

Transaktionsstorlek

En av de saker du måste tänka på när du kör Galera Cluster är storleken på transaktionen. Att hitta balansen mellan transaktionsstorlek, prestanda och Galera-certifieringsprocessen är något du måste uppskatta i din ansökan. Du kan hitta mer information om det i artikeln How to Improve Performance of Galera Cluster for MySQL eller MariaDB av Ashraf Sharif.

Load Balancer Causal Consistency Reads

Även med den minimerade risken för problem med datafördröjning kan standard MySQL asynkron replikering inte garantera konsekvens. Det är fortfarande möjligt att data ännu inte replikeras till slav medan din applikation läser den därifrån. Synkron replikering kan lösa detta problem, men det har arkitekturbegränsningar och kanske inte passar dina applikationskrav (t.ex. intensiva massskrivningar). Så hur kan man övervinna det?

Det första steget för att undvika inaktuell dataläsning är att göra applikationen medveten om replikeringsfördröjning. Det är vanligtvis programmerat i applikationskod. Lyckligtvis finns det moderna databaslastbalanserare med stöd för adaptiv frågedirigering baserad på GTID-spårning. De mest populära är ProxySQL och Maxscale.

ProxySQL 2.0

ProxySQL Binlog Reader låter ProxySQL i realtid veta vilket GTID som har körts på varje MySQL-server, slavar och master själv. Tack vare detta vet ProxySQL omedelbart på vilken server frågan kan köras när en klient kör en läsning som måste ge orsaksmässiga konsistensläsningar. Om skrivningarna av någon anledning inte har utförts på någon slav än, kommer ProxySQL att veta att skribenten exekveras på master och skicka läsningen dit.

Maxscale 2.3

MariaDB introducerade tillfälliga läsningar i Maxscale 2.3.0. Hur det fungerar liknar det ProxySQL 2.0. I princip när causal_reads är aktiverade kommer alla efterföljande läsningar som utförs på slavservrar att göras på ett sätt som förhindrar att replikeringsfördröjning påverkar resultaten. Om slaven inte har kommit ikapp mastern inom den konfigurerade tiden kommer frågan att göras om på mastern.


  1. Kan inte ansluta till heroku postgresql-databas från lokal nodapp med uppföljare

  2. Distribuera ett certifikat för krypterad anslutning SQL Server

  3. Varför anses det vara dålig praxis att använda markörer i SQL Server?

  4. Hur man ansluter en databas med en Amazon VPC