Amazon Aurora Serverless tillhandahåller en på begäran, automatiskt skalbar, högtillgänglig, relationsdatabas som bara debiterar dig när den används. Det ger ett relativt enkelt, kostnadseffektivt alternativ för sällsynta, intermittenta eller oförutsägbara arbetsbelastningar. Det som gör detta möjligt är att den startar automatiskt, skalar beräkningskapaciteten för att matcha din applikations användning och sedan stängs av när den inte längre behövs.
Följande diagram visar Aurora Serverless högnivåarkitektur.
Med Aurora Serverless får du en slutpunkt (i motsats till två slutpunkter för Auroras standardiserade DB). Detta är i grunden en DNS-post som består av en flotta av proxyservrar som sitter ovanpå databasinstansen. Från en MySQL-serverpunkt betyder det att anslutningarna alltid kommer från proxyflottan.
Aurora Serverless Auto-Scaling
Aurora Serverless är för närvarande endast tillgängligt för MySQL 5.6. Du måste i princip ställa in minsta och maximala kapacitetsenhet för DB-klustret. Varje kapacitetsenhet motsvarar en specifik beräknings- och minneskonfiguration. Aurora Serverless minskar resurserna för DB-klustret när dess arbetsbelastning ligger under dessa tröskelvärden. Aurora Serverless kan minska kapaciteten till ett minimum eller öka kapaciteten till en enhet med maximal kapacitet.
Klustret skalas upp automatiskt om något av följande villkor är uppfyllt:
- CPU-användningen är över 70 % ELLER
- Mer än 90 % av anslutningarna används
Klustret skalas ned automatiskt om båda följande villkor är uppfyllda:
- CPU-användningen sjunker under 30 % OCH
- Mindre än 40 % av anslutningarna används.
Några av de anmärkningsvärda sakerna att veta om Auroras automatiska skalningsflöde:
- Den skalas bara upp när den upptäcker prestandaproblem som kan lösas genom att skala upp.
- Efter uppskalning är nedkylningsperioden för nedskalning 15 minuter.
- Efter nedskalning är nedkylningsperioden för nästa nedskalning 310 sekunder.
- Den skalas till noll kapacitet när det inte finns några anslutningar under en 5-minutersperiod.
Som standard utför Aurora Serverless den automatiska skalningen sömlöst, utan att avbryta några aktiva databasanslutningar till servern. Den kan bestämma en skalningspunkt (en tidpunkt då databasen säkert kan initiera skalningsoperationen). Under följande förhållanden kanske Aurora Serverless inte kan hitta en skalningspunkt:
- Långgående frågor eller transaktioner pågår.
- Tillfälliga bord eller bordslås används.
Om något av ovanstående fall inträffar, fortsätter Aurora Serverless att försöka hitta en skalningspunkt så att den kan initiera skalningsoperationen (såvida inte "Force Scaling" är aktiverat). Den gör detta så länge den bestämmer att DB-klustret ska skalas.
Observera Auroras automatiska skalningsbeteende
Observera att i Aurora Serverless kan endast ett litet antal parametrar ändras och max_connections är inte en av dem. För alla andra konfigurationsparametrar använder Aurora MySQL Serverless-kluster standardvärdena. För max_connections styrs den dynamiskt av Aurora Serverless med följande formel:
max_connections =GREATEST({log(DBInstanceClassMemory/805306368)*45},{log(DBInstanceClassMemory/8187281408)*1000})
Var, logg är logg2 (log base-2) och "DBInstanceClassMemory" är antalet byte minne som allokerats till DB-instansklassen associerad med den aktuella DB-instansen, minus minnet som används av Amazon RDS-processerna som hanterar instansen. Det är ganska svårt att förutbestämma värdet som Aurora kommer att använda, så det är bra att göra några tester för att förstå hur detta värde skalas därefter.
Här är vår Aurora Serverless-distributionssammanfattning för detta test:
För det här exemplet har jag valt minst 1 Aurora-kapacitetsenhet, vilket är lika med 2 GB RAM upp till den maximala kapaciteten på 256 enheter med 488 GB RAM.
Tester utfördes med sysbench, genom att helt enkelt skicka ut flera trådar tills den når gränsen för MySQL-databasanslutningar. Vårt första försök att skicka ut 128 samtidiga databasanslutningar på en gång misslyckades:
$ sysbench \
/usr/share/sysbench/oltp_read_write.lua \
--report-interval=2 \
--threads=128 \
--delete_inserts=5 \
--time=360 \
--max-requests=0 \
--db-driver=mysql \
--db-ps-mode=disable \
--mysql-host=${_HOST} \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run
Kommandot ovan returnerade omedelbart felet 'För många anslutningar':
FATAL: unable to connect to MySQL server on host 'aurora-sysbench.cluster-cdw9q2wnb00s.ap-southeast-1.rds.amazonaws.com', port 3306, aborting...
FATAL: error 1040: Too many connections
När vi tittade på inställningarna för max_connection fick vi följande:
mysql> SELECT @@hostname, @@max_connections;
+----------------+-------------------+
| @@hostname | @@max_connections |
+----------------+-------------------+
| ip-10-2-56-105 | 90 |
+----------------+-------------------+
Det visar sig att startvärdet för max_connections för vår Aurora-instans med en DB-kapacitet (2 GB RAM) är 90. Detta är faktiskt mycket lägre än vårt förväntade värde om det beräknas med den angivna formeln för att uppskatta max_connections värde:
mysql> SELECT GREATEST({log2(2147483648/805306368)*45},{log2(2147483648/8187281408)*1000});
+------------------------------------------------------------------------------+
| GREATEST({log2(2147483648/805306368)*45},{log2(2147483648/8187281408)*1000}) |
+------------------------------------------------------------------------------+
| 262.2951 |
+------------------------------------------------------------------------------+
Detta betyder helt enkelt att DBInstanceClassMemory inte är lika med det faktiska minnet för Aurora-instansen. Det måste vara mycket lägre. Enligt denna diskussionstråd justeras variabelns värde för att ta hänsyn till minne som redan används för OS-tjänster och RDS-hanteringsdemon.
Ändå kommer det inte att hjälpa oss att ändra standardvärdet för max_connections till något högre eftersom detta värde styrs dynamiskt av Aurora Serverless-kluster. Därför var vi tvungna att minska sysbench-starttrådarnas värde till 84 eftersom Aurora interna trådar redan reserverade runt 4 till 5 anslutningar via 'rdsadmin'@'localhost'. Dessutom behöver vi också en extra anslutning för våra hanterings- och övervakningsändamål.
Så vi körde följande kommando istället (med --threads=84):
$ sysbench \
/usr/share/sysbench/oltp_read_write.lua \
--report-interval=2 \
--threads=84 \
--delete_inserts=5 \
--time=600 \
--max-requests=0 \
--db-driver=mysql \
--db-ps-mode=disable \
--mysql-host=${_HOST} \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run
Efter att ovanstående test slutförts på 10 minuter (--tid=600), körde vi samma kommando igen och vid denna tidpunkt hade några av de anmärkningsvärda variablerna och status ändrats enligt nedan:
mysql> SELECT @@hostname AS hostname, @@max_connections AS max_connections,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'THREADS_CONNECTED') AS threads_connected,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'UPTIME') AS uptime;
+--------------+-----------------+-------------------+--------+
| hostname | max_connections | threads_connected | uptime |
+--------------+-----------------+-------------------+--------+
| ip-10-2-34-7 | 180 | 179 | 157 |
+--------------+-----------------+-------------------+--------+
Lägg märke till att max_connections nu har fördubblats upp till 180, med ett annat värdnamn och liten drifttid som om servern precis skulle börja. Ur applikationssynpunkt ser det ut som att en annan "större databasinstans" har tagit över slutpunkten och konfigurerats med en annan max_connections-variabel. När man tittar på Aurora-evenemanget har följande hänt:
Wed, 04 Sep 2019 08:50:56 GMT The DB cluster has scaled from 1 capacity unit to 2 capacity units.
Sedan startade vi samma sysbench-kommando och skapade ytterligare 84 anslutningar till databasens slutpunkt. Efter att det genererade stresstestet har slutförts skalar servern automatiskt upp till 4 DB kapacitet, som visas nedan:
mysql> SELECT @@hostname AS hostname, @@max_connections AS max_connections,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'THREADS_CONNECTED') AS threads_connected,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'UPTIME') AS uptime;
+---------------+-----------------+-------------------+--------+
| hostname | max_connections | threads_connected | uptime |
+---------------+-----------------+-------------------+--------+
| ip-10-2-12-75 | 270 | 6 | 300 |
+---------------+-----------------+-------------------+--------+
Du kan se det genom att titta på det olika värdnamnet, max_connection och drifttidsvärdet om det jämförs med det föregående. En annan större instans har "tagit över" rollen från den tidigare instansen, där DB-kapaciteten var lika med 2. Den faktiska skalningspunkten är när serverbelastningen föll och nästan slog i golvet. I vårt test, om vi höll anslutningen full och databasbelastningen konsekvent hög, skulle automatisk skalning inte ske.
Genom att titta på båda skärmdumparna nedan kan vi se att skalningen bara sker när vår Sysbench har slutfört sitt stresstest i 600 sekunder eftersom det är den säkraste punkten att utföra automatisk skalning.
Serverlös DB-kapacitet CPU-användning CPU-användningNär man tittar på Aurora-händelser inträffade följande händelser:
Wed, 04 Sep 2019 16:25:00 GMT Scaling DB cluster from 4 capacity units to 2 capacity units for this reason: Autoscaling.
Wed, 04 Sep 2019 16:25:05 GMT The DB cluster has scaled from 4 capacity units to 2 capacity units.
Äntligen genererade vi mycket fler anslutningar till nästan 270 och väntar tills det är klart, för att komma in i kapaciteten på 8 DB:
mysql> SELECT @@hostname as hostname, @@max_connections AS max_connections,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'THREADS_CONNECTED') AS threads_connected,
(SELECT VARIABLE_VALUE FROM global_status WHERE VARIABLE_NAME = 'UPTIME') AS uptime;
+---------------+-----------------+-------------------+--------+
| hostname | max_connections | threads_connected | uptime |
+---------------+-----------------+-------------------+--------+
| ip-10-2-72-12 | 1000 | 144 | 230 |
+---------------+-----------------+-------------------+--------+
I instansen med 8 kapacitetsenheter är MySQL max_connections-värdet nu 1000. Vi upprepade liknande steg genom att maxa databasanslutningarna och upp till gränsen på 256 kapacitetsenheter. Följande tabell sammanfattar den totala DB-kapacitetsenheten kontra max_connections-värdet i våra tester upp till den maximala DB-kapaciteten:
Tvingad skalning
Som nämnts ovan kommer Aurora Serverless endast att utföra automatisk skalning när det är säkert att göra det. Användaren har dock möjlighet att tvinga DB-kapacitetsskalningen att ske omedelbart genom att markera kryssrutan Force scaling under alternativet "Ytterligare skalningskonfiguration":
När forcerad skalning är aktiverad, sker skalningen så snart timeouten är slut nått vilket är 300 sekunder. Detta beteende kan orsaka databasavbrott från ditt program där aktiva anslutningar till databasen kan avbrytas. Vi observerade följande fel när tvångsautomatisk skalning ägde rum efter att den når timeout:
FATAL: mysql_drv_query() returned error 1105 (The last transaction was aborted due to an unknown error. Please retry.) for query 'SELECT c FROM sbtest19 WHERE id=52824'
FATAL: `thread_run' function failed: /usr/share/sysbench/oltp_common.lua:419: SQL error, errno = 1105, state = 'HY000': The last transaction was aborted due to an unknown error. Please retry.
Ovanstående betyder helt enkelt, istället för att hitta rätt tid att skala upp, tvingar Aurora Serverless instansersättningen att äga rum omedelbart efter att den når sin timeout, vilket gör att transaktioner avbryts och backas. Om du försöker igen den avbrutna frågan för andra gången kommer troligen att lösa problemet. Denna konfiguration kan användas om din applikation är motståndskraftig mot anslutningsavbrott.
Sammanfattning
Amazon Aurora Serverless auto scaling är en vertikal skalningslösning, där en mer kraftfull instans tar över en sämre instans och utnyttjar den underliggande Aurora delade lagringstekniken effektivt. Som standard utförs den automatiska skalningsoperationen sömlöst, varvid Aurora hittar en säker skalningspunkt för att utföra instansbytet. Man har möjlighet att tvinga fram automatisk skalning med risk för att aktiva databasanslutningar tappas.