Ottimizza la scalabilità automatica dei ECS servizi Amazon - Amazon Elastic Container Service

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Ottimizza la scalabilità automatica dei ECS servizi Amazon

Un ECS servizio Amazon è una raccolta gestita di attività. A ogni servizio è associata una definizione delle attività, un numero di attività desiderato e una strategia di posizionamento opzionale. La scalabilità automatica del ECS servizio Amazon viene implementata tramite il servizio Application Auto Scaling. Application Auto Scaling utilizza le CloudWatch metriche come fonte per le metriche di scalabilità. Utilizza inoltre gli CloudWatch allarmi per impostare soglie su quando ampliare o disattivare il servizio. Puoi fornire le soglie per la scalabilità impostando un obiettivo metrico, denominato ridimensionamento del tracciamento degli obiettivi, o specificando delle soglie, denominate scalabilità dei passaggi. Una volta configurato, Application Auto Scaling calcola continuamente il numero di attività desiderato appropriato per il servizio. Inoltre, notifica ad Amazon ECS quando il numero di attività desiderato deve cambiare, ridimensionandolo o ridimensionandolo.

Per utilizzare il service auto scaling in modo efficace, è necessario scegliere una metrica di scalabilità appropriata.

Un'applicazione deve essere scalata orizzontalmente se si prevede che la domanda sia superiore alla capacità attuale. Al contrario, un'applicazione può essere scalata per ridurre i costi quando le risorse superano la domanda.

Identifica una metrica

Per una scalabilità efficace, è fondamentale identificare una metrica che indichi l'utilizzo o la saturazione. Questa metrica deve presentare le seguenti proprietà per essere utile per la scalabilità.

  • La metrica deve essere correlata alla domanda. Quando le risorse vengono mantenute stabili, ma la domanda cambia, anche il valore della metrica deve cambiare. La metrica dovrebbe aumentare o diminuire quando la domanda aumenta o diminuisce.

  • Il valore della metrica deve essere scalato in proporzione alla capacità. Quando la domanda rimane costante, l'aggiunta di più risorse deve comportare una modifica proporzionale del valore della metrica. Pertanto, il raddoppio del numero di attività dovrebbe far diminuire la metrica del 50%.

Il modo migliore per identificare una metrica di utilizzo è eseguire test di carico in un ambiente di preproduzione come un ambiente di staging. Le soluzioni commerciali e open source per i test di carico sono ampiamente disponibili. Queste soluzioni in genere possono generare carichi sintetici o simulare il traffico utente reale.

Per avviare il processo di test di carico, crea dashboard per le metriche di utilizzo dell'applicazione. Queste metriche includono CPU l'utilizzo, l'utilizzo della memoria, le operazioni di I/O, la profondità della coda di I/O e il throughput di rete. Puoi raccogliere queste metriche con un servizio come Container Insights. Per ulteriori informazioni, consulta Monitora ECS i contenitori Amazon utilizzando Container Insights. Durante questo processo, assicurati di raccogliere e tracciare le metriche relative ai tempi di risposta dell'applicazione o ai tassi di completamento del lavoro.

Inizia con una piccola richiesta o una percentuale di inserimento lavorativo ridotta. Mantieni questa frequenza costante per diversi minuti per consentire all'applicazione di riscaldarsi. Quindi, aumenta lentamente la velocità e mantienila costante per alcuni minuti. Ripeti questo ciclo, aumentando ogni volta la frequenza fino a quando i tempi di risposta o di completamento dell'applicazione non saranno troppo lenti per soddisfare gli obiettivi in termini di livello di servizio (). SLOs

Durante il test di carico, esaminate ciascuna metrica di utilizzo. Le metriche che aumentano insieme al carico sono le migliori candidate a fungere da migliori metriche di utilizzo.

Successivamente, identifica la risorsa che raggiunge la saturazione. Allo stesso tempo, esamina anche le metriche di utilizzo per vedere quale si appiattisce prima ad un livello elevato o raggiunge un picco e poi blocca prima l'applicazione. Ad esempio, se l'CPUutilizzo aumenta dallo 0% al 70-80% man mano che si aggiunge il carico e poi rimane a quel livello dopo aver aggiunto ancora più carico, si può tranquillamente affermare che è saturo. CPU A seconda dell'CPUarchitettura, potrebbe non raggiungere mai il 100%. Ad esempio, supponiamo che l'utilizzo della memoria aumenti man mano che aggiungi carico e che l'applicazione si blocchi improvvisamente quando raggiunge il limite di memoria dell'attività o dell'EC2istanza Amazon. In questa situazione, è probabile che la memoria sia stata completamente consumata. L'applicazione potrebbe consumare più risorse. Pertanto, scegli la metrica che rappresenta la risorsa che si esaurisce per prima.

Infine, riprova a testare il carico dopo aver raddoppiato il numero di attività o EC2 istanze Amazon. Supponiamo che la metrica chiave aumenti o diminuisca della metà rispetto a prima. In tal caso, la metrica è proporzionale alla capacità. Questa è una buona metrica di utilizzo per la scalabilità automatica.

Consideriamo ora questo scenario ipotetico. Supponiamo di testare un'applicazione e di scoprire che l'CPUutilizzo alla fine raggiunge l'80% a 100 richieste al secondo. Quando viene aggiunto più carico, non ne aumenta più CPU l'utilizzo. Tuttavia, fa sì che l'applicazione risponda più lentamente. Quindi, si esegue nuovamente il test di carico, raddoppiando il numero di attività ma mantenendo la frequenza al valore di picco precedente. Se ritieni che l'CPUutilizzo medio scenda a circa il 40%, allora l'CPUutilizzo medio è un buon candidato per una metrica di scalabilità. D'altra parte, se l'CPUutilizzo rimane all'80% dopo l'aumento del numero di attività, l'CPUutilizzo medio non è una buona metrica di scalabilità. In tal caso, sono necessarie ulteriori ricerche per trovare una metrica adeguata.

Modelli applicativi e proprietà di scalabilità comuni

Vengono eseguiti software di tutti i tipi. AWS Molti carichi di lavoro sono creati internamente, mentre altri si basano su popolari software open source. Indipendentemente dalla loro origine, abbiamo osservato alcuni modelli di progettazione comuni per i servizi. La scalabilità efficace dipende in gran parte dal modello.

L'efficiente CPU server associato

L'CPUefficiente server associato non utilizza quasi nessuna risorsa oltre CPU al throughput di rete. Ogni richiesta può essere gestita dalla sola applicazione. Le richieste non dipendono da altri servizi come i database. L'applicazione è in grado di gestire centinaia di migliaia di richieste simultanee e a tale scopo può utilizzarne più CPUs di una in modo efficiente. Ogni richiesta è gestita da un thread dedicato con un basso sovraccarico di memoria, oppure esiste un ciclo di eventi asincrono che viene eseguito su ciascuna richiesta che soddisfa le richieste. CPU Ogni replica dell'applicazione è ugualmente in grado di gestire una richiesta. L'unica risorsa che potrebbe essere esaurita prima CPU è la larghezza di banda della rete. Nei CPU servizi limitati, l'utilizzo della memoria, anche al picco della velocità effettiva, è una frazione delle risorse disponibili.

Questo tipo di applicazione è adatto per il ridimensionamento automatico CPU basato. L'applicazione gode della massima flessibilità in termini di scalabilità. Può essere scalato verticalmente fornendo EC2 istanze Amazon più grandi o Fargate. vCPUs Inoltre, può anche essere ridimensionato orizzontalmente aggiungendo altre repliche. L'aggiunta di più repliche o il raddoppio delle dimensioni dell'istanza dimezzano l'CPUutilizzo medio rispetto alla capacità.

Se utilizzi la EC2 capacità di Amazon per questa applicazione, valuta la possibilità di collocarla su istanze ottimizzate per il calcolo come la c5 famiglia or. c6g

L'efficiente server legato alla memoria

L'efficiente server legato alla memoria alloca una quantità significativa di memoria per richiesta. In caso di massima concorrenza, ma non necessariamente della velocità effettiva, la memoria si esaurisce prima dell'esaurimento delle risorse. CPU La memoria associata a una richiesta viene liberata al termine della richiesta. Le richieste aggiuntive possono essere accettate purché sia disponibile memoria.

Questo tipo di applicazione è adatto per il ridimensionamento automatico basato sulla memoria. L'applicazione gode della massima flessibilità in termini di scalabilità. Può essere scalato sia verticalmente fornendogli risorse di memoria Amazon o EC2 Fargate più grandi. Inoltre, può essere ridimensionato orizzontalmente aggiungendo altre repliche. L'aggiunta di più repliche o il raddoppio delle dimensioni dell'istanza possono dimezzare l'utilizzo medio della memoria rispetto alla capacità.

Se utilizzi la EC2 capacità di Amazon per questa applicazione, valuta la possibilità di collocarla su istanze ottimizzate per la memoria come la r5 famiglia or. r6g

Alcune applicazioni legate alla memoria non liberano la memoria associata a una richiesta al termine, quindi una riduzione della concorrenza non si traduce in una riduzione della memoria utilizzata. Per questo, non è consigliabile utilizzare il ridimensionamento basato sulla memoria.

Il server basato sul lavoratore

Il server basato sul lavoratore elabora una richiesta per ogni singolo thread di lavoro una dopo l'altra. I thread di lavoro possono essere thread leggeri, ad esempio thread. POSIX Possono anche essere thread più pesanti, come i processi. UNIX Indipendentemente dal thread, c'è sempre una concorrenza massima che l'applicazione è in grado di supportare. Di solito il limite di concorrenza è impostato proporzionalmente alle risorse di memoria disponibili. Se viene raggiunto il limite di concorrenza, le richieste aggiuntive vengono inserite in una coda di backlog. Se la coda del backlog supera i limiti, le richieste aggiuntive in arrivo vengono immediatamente respinte. Le applicazioni più comuni che si adattano a questo modello includono il server web Apache e Gunicorn.

La concorrenza delle richieste è in genere la metrica migliore per scalare questa applicazione. Poiché esiste un limite di concorrenza per ogni replica, è importante eseguire la scalabilità orizzontale prima che venga raggiunto il limite medio.

Il modo migliore per ottenere le metriche relative alla concorrenza delle richieste consiste nel farle riportare dall'applicazione. CloudWatch Ogni replica dell'applicazione può pubblicare il numero di richieste simultanee come metrica personalizzata ad alta frequenza. Si consiglia di impostare la frequenza su almeno una volta al minuto. Dopo aver raccolto diversi report, puoi utilizzare la concorrenza media come metrica di scala. Questa metrica viene calcolata prendendo la concorrenza totale e dividendola per il numero di repliche. Ad esempio, se la concorrenza totale è 1000 e il numero di repliche è 10, la concorrenza media è 100.

Se la tua applicazione è alla base di un Application Load Balancer, puoi anche utilizzare la ActiveConnectionCount metrica per il load balancer come fattore nella metrica di scalabilità. La ActiveConnectionCount metrica deve essere divisa per il numero di repliche per ottenere un valore medio. Per la scalatura deve essere utilizzato il valore medio, anziché il valore di conteggio non elaborato.

Affinché questa progettazione funzioni al meglio, la deviazione standard della latenza di risposta deve essere piccola a basse frequenze di richiesta. Consigliamo che, durante i periodi di scarsa domanda, la maggior parte delle richieste riceva risposta in breve tempo e che non molte richieste impieghino molto più tempo della media per rispondere. Il tempo di risposta medio dovrebbe essere vicino al tempo di risposta del 95° percentile. In caso contrario, potrebbero verificarsi sovraccarichi dalla coda. Ciò porta a errori. Si consiglia di fornire repliche aggiuntive laddove necessario per mitigare il rischio di overflow.

Il server di attesa

Il server di attesa esegue alcune elaborazioni per ogni richiesta, ma il funzionamento dipende in larga misura da uno o più servizi a valle. Le applicazioni container spesso fanno un uso intensivo di servizi a valle come database e altri API servizi. La risposta di questi servizi può richiedere del tempo, in particolare in scenari ad alta capacità o ad alta concorrenza. Questo perché queste applicazioni tendono a utilizzare poche CPU risorse e a sfruttare la massima concorrenza in termini di memoria disponibile.

Il servizio di attesa è adatto sia nel modello di server legato alla memoria che nel modello di server basato sui lavoratori, a seconda di come è progettata l'applicazione. Se la concorrenza dell'applicazione è limitata solo dalla memoria, l'utilizzo medio della memoria deve essere utilizzato come metrica di scalabilità. Se la concorrenza dell'applicazione si basa su un limite di lavoratori, è necessario utilizzare la concorrenza media come metrica di scalabilità.

Il server basato su Java

Se il server basato su Java è associato a CPU -bound e si adatta proporzionalmente alle CPU risorse, allora potrebbe essere adatto per l'efficiente modello di server con associazione. CPU In tal caso, l'CPUutilizzo medio potrebbe essere appropriato come metrica di scalabilità. Tuttavia, molte applicazioni Java non sono CPU vincolate, il che le rende difficili da scalare.

Per prestazioni ottimali, si consiglia di allocare quanta più memoria possibile all'heap di Java Virtual Machine (JVM). Le versioni recenti diJVM, tra cui Java 8 update 191 o versioni successive, impostano automaticamente la dimensione dell'heap il più grande possibile per adattarla al contenitore. Ciò significa che, in Java, l'utilizzo della memoria è raramente proporzionale all'utilizzo dell'applicazione. Con l'aumento della frequenza delle richieste e della concorrenza, l'utilizzo della memoria rimane costante. Per questo motivo, non è consigliabile scalare i server basati su Java in base all'utilizzo della memoria. Invece, in genere consigliamo di ridimensionare l'utilizzo. CPU

In alcuni casi, i server basati su Java incontrano l'esaurimento dell'heap prima di esaurirsi. CPU Se l'applicazione è soggetta all'esaurimento dell'heap in caso di elevata contemporaneità, la metrica di scalabilità migliore è rappresentata dalle connessioni medie. Se la tua applicazione è soggetta all'esaurimento dell'heap a un throughput elevato, la frequenza media delle richieste è la metrica di scalabilità migliore.

Server che utilizzano altri runtime raccolti tramite garbage

Molte applicazioni server si basano su runtime che eseguono la raccolta dei rifiuti, ad esempio. NETe Ruby. Queste applicazioni server potrebbero rientrare in uno dei modelli descritti in precedenza. Tuttavia, come nel caso di Java, non è consigliabile scalare queste applicazioni in base alla memoria, poiché il loro utilizzo medio della memoria osservato spesso non è correlato alla velocità effettiva o alla concorrenza.

Per queste applicazioni, si consiglia di scalare in base all'CPUutilizzo se l'applicazione è associata. CPU In caso contrario, si consiglia di scalare in base alla velocità di trasmissione media o alla concorrenza media, in base ai risultati dei test di carico.

Job processor

Molti carichi di lavoro prevedono l'elaborazione asincrona dei processi. Includono applicazioni che non ricevono richieste in tempo reale, ma si iscrivono a una coda di lavoro per ricevere offerte di lavoro. Per questi tipi di applicazioni, la metrica di scalabilità corretta è quasi sempre la profondità della coda. L'aumento della coda indica che il lavoro in sospeso supera la capacità di elaborazione, mentre una coda vuota indica che c'è più capacità del lavoro da fare.

AWS i servizi di messaggistica, come Amazon SQS e Amazon Kinesis Data Streams CloudWatch, forniscono metriche che possono essere utilizzate per la scalabilità. Per AmazonSQS, ApproximateNumberOfMessagesVisible è la metrica migliore. Per Kinesis Data Streams, prendi in considerazione l'MillisBehindLatestutilizzo della metrica, pubblicata da Kinesis Client Library (). KCL È necessario calcolare la media di questa metrica tra tutti i consumatori prima di utilizzarla per la scalabilità.