Passa al contenuto principale
Lakebase

Una guida pratica all'ottimizzazione dei costi con Lakebase Postgres

di Benjamin Nwokeleme, Firas Farah e Jen Darrouzet

  • Lakebase è conveniente fin dalla progettazione perché la sua architettura con storage e compute separati consente a branching, repliche di lettura e alta disponibilità di condividere un unico livello di storage, mentre l'autoscaling serverless e lo scale-to-zero consentono di pagare solo per le risorse di calcolo effettivamente utilizzate.
  • I maggiori risparmi pratici derivano dalla sincronizzazione del solo sottoinsieme di lavoro dei dati del Lakehouse in Lakebase, adattando la modalità di sincronizzazione (Snapshot, Triggered o Continuous) all'effettiva freschezza richiesta per i dati e dimensionando correttamente il compute in modo che il working set attivo entri nella cache.
  • Applicando queste pratiche (sincronizzare solo il sottoinsieme di lavoro, adattare la modalità di sincronizzazione alle esigenze di freschezza, dimensionare correttamente il compute in modo che i dati caldi entrino nella cache e ottimizzare PITR e snapshot), i costi rimangono prevedibili e bassi, senza rinunciare alle prestazioni, alla disponibilità e alla developer experience di cui le tue applicazioni hanno bisogno.

Lakebase è un database Postgres completamente gestito, progettato per le esigenze operative dello sviluppo di applicazioni moderne. Ciò che lo distingue dagli altri fornitori di database sul mercato che offrono un motore Postgres è l'architettura sottostante, con storage ed elaborazione separati grazie a un livello di calcolo serverless, e la sua stretta integrazione con il Lakehouse e la piattaforma di data intelligence. Puoi scoprire di più su questa architettura e su alcuni dei suoi vantaggi qui. Un vantaggio che tuttavia spesso passa inosservato è che questa architettura rende Lakebase anche estremamente conveniente. In questo blog analizzeremo da dove derivano questi risparmi e condivideremo consigli pratici per sfruttarli al meglio.

Perché Lakebase è conveniente per progettazione

Evita costi di storage duplicati con il branching

I branch del database consentono agli sviluppatori di creare ambienti isolati con dati di produzione per scopi di sviluppo, test o sperimentazione. A differenza degli approcci che richiedono la creazione di una copia fisica separata del database per ogni ambiente, i branch di Lakebase condividono lo stesso storage sottostante e tengono traccia delle modifiche man mano che il branch diverge da quello principale. Questo rende il branching particolarmente conveniente per gli ambienti di sviluppo e test a breve termine, dove i team possono lavorare con dati simili a quelli di produzione senza dover configurare e mantenere una copia del database completamente separata.

Paga solo per le risorse di calcolo che utilizzi

L'autoscaling modifica attivamente le risorse di calcolo della tua istanza Lakebase in risposta ai diversi livelli di attività. Puoi controllare l'intervallo minimo e massimo entro cui l'istanza può scalare. I vantaggi in termini di costi di questa funzionalità sono evidenti: la capacità di calcolo può scalare in base alla domanda del carico di lavoro, invece di essere configurata staticamente per i picchi di utilizzo.

L'impostazione di una dimensione massima di calcolo aiuta a rendere i costi prevedibili, poiché previene spese impreviste ponendo un limite massimo ai costi di calcolo. Nei momenti di scarso utilizzo, le risorse di calcolo scalano verso il basso, riducendo i costi. Se combinato con lo scale to zero, il calcolo viene completamente sospeso dopo un periodo di inattività, azzerando i costi di calcolo. Il calcolo riprende dallo scale to zero in poche centinaia di millisecondi. Questo lo rende particolarmente interessante per scenari che non sono eccezionalmente sensibili alla latenza, come i flussi di lavoro di sviluppo, le varianti non di produzione delle app e le app di produzione che non richiedono latenze a doppia cifra.

Quando lo scale to zero è disattivato, Lakebase offre la tariffazione always-on, che prevede uno sconto del 25% sulla capacità di base. Questa riduzione dei costi si applica anche a qualsiasi risorsa di calcolo che non può scalare a zero, come le configurazioni HA.

Aggiungi repliche e alta disponibilità senza duplicare lo storage

La separazione di storage e calcolo di Lakebase rende anche le repliche di lettura e l'alta disponibilità più convenienti. Le repliche di lettura sono istanze di calcolo indipendenti che leggono dallo stesso livello di storage sottostante del database primario, quindi la scalabilità della capacità di lettura non richiede la creazione e il pagamento di un'altra copia del database. Allo stesso modo, l'alta disponibilità aggiunge risorse di calcolo ridondanti tra le zone di disponibilità, continuando a utilizzare il livello di storage a elevata disponibilità esistente. Ciò significa che puoi aggiungere scalabilità di lettura e ridondanza di calcolo senza moltiplicare l'ingombro dello storage.

Consigli pratici per ottimizzare i costi di Lakebase

Gestisci un sottoinsieme di dati del Lakehouse con le Synced Tables di Lakebase

La stretta integrazione di Lakebase con la più ampia Databricks Intelligence Platform consente sincronizzazioni gestite tra i due ambienti. Le Synced Tables espongono i dati di Unity Catalog nel tuo database Lakebase per supportare letture transazionali a bassa latenza per casi d'uso di applicazioni o feature serving.

Un errore comune commesso dai clienti consiste nel caricare una grande tabella Delta in Lakebase quando l'applicazione interroga solo un sottoinsieme attivo molto più piccolo. Questo gonfia lo storage di Lakebase, aumenta i costi di sincronizzazione e, in alcuni scenari, può persino causare problemi di prestazioni. La soluzione è semplice: sincronizza solo il set di lavoro necessario per l'applicazione. Definisci esattamente i dati necessari alla tua app con una vista materializzata, ad esempio una finestra mobile di 60 giorni, e sincronizza solo quella. Le pipeline di sincronizzazione di Lakebase possono utilizzare il change data feed automatico delle MV per calcolare le modifiche a livello di riga al momento della lettura. Ciò significa che le modifiche alla MV, comprese le eliminazioni quando le righe escono dalla finestra mobile, possono essere propagate in modo incrementale in Lakebase. Il risultato è un sottoinsieme attivo aggiornato e a bassa latenza in Lakebase, mentre la cronologia completa rimane in Delta. Associa questo alla modalità di sincronizzazione più efficiente che soddisfa i tuoi requisiti, descritta di seguito, e otterrai un pattern di reverse ETL molto più conveniente.

Utilizzo della modalità di sincronizzazione Lakehouse → Lakebase appropriata

Sotto la scocca, le Synced Tables sono Serverless Spark Declarative Pipelines (SDP) gestite e vengono eseguite per l'intera durata della sincronizzazione. Di conseguenza, il costo di sincronizzazione è determinato da fattori quali la quantità di dati trasferiti e le dimensioni dell'istanza Lakebase / Capacity Units (CU).

Esistono tre diverse modalità di sincronizzazione per spostare i dati dal Lakehouse a Lakebase, ed è importante far corrispondere la modalità al livello di aggiornamento dei dati effettivamente richiesto. La scelta della modalità corretta consente di soddisfare i requisiti di latenza mantenendo i costi sotto controllo.

ModalitàDescrizioneIdeale da usare quando
SnapshotCopia di tutti i datiLe modifiche all'origine interessano più del 10% delle righe per ciclo. In questi scenari sarà sostanzialmente più conveniente rispetto alla modalità Triggered.
TriggeredAggiornamenti incrementali eseguiti su richiesta o a intervalliLe righe di origine cambiano con una cadenza nota. Inserimenti, aggiornamenti ed eliminazioni vengono propagati a ogni aggiornamento.
ContinuousStreaming in tempo reale con latenza di pochi secondiLe modifiche devono apparire in Lakebase quasi in tempo reale. Offre il ritardo minimo al costo più elevato.

Origine: Modalità di sincronizzazione

La modalità Snapshot è l'opzione più conveniente per le tabelle aggiornate raramente o altamente volatili, mentre Continuous può essere la più costosa perché la sua pipeline viene eseguita continuamente e consuma risorse di calcolo anche quando non ci sono modifiche da elaborare. La modalità Snapshot è consigliata quando più del 10% dei dati di origine cambia tra una sincronizzazione e l'altra, poiché può essere fino a 10 volte più efficiente. Per i carichi di lavoro incrementali, la modalità Triggered offre il bilanciamento ideale tra costi e latenza. Puoi ottenere un livello di aggiornamento quasi continuo con un budget limitato associando la modalità Triggered a un trigger di aggiornamento della tabella, assicurando che venga eseguita solo quando i dati di origine cambiano. In generale, evita lunghi intervalli tra le esecuzioni, poiché un enorme backlog di modifiche può rendere la sincronizzazione successiva lenta e costosa.

Un'altra utile ottimizzazione dei costi è la possibilità di raggruppare (binpack) più tabelle in una singola pipeline di sincronizzazione. Se il tuo caso d'uso lo consente, la stessa pipeline può sincronizzare le modifiche da più tabelle Delta in Lakebase, consentendo a tali tabelle di condividere le stesse risorse di calcolo sottostanti. Questo può essere particolarmente prezioso per le sincronizzazioni in modalità Continuous, in cui la pipeline è sempre in esecuzione, perché evita di pagare per pipeline separate in esecuzione continua per ciascuna tabella.

Dimensiona correttamente Lakebase fin dall'inizio

Quando viene creato un progetto Lakebase, questo include automaticamente un branch di produzione e una risorsa di calcolo primaria di lettura-scrittura. Per impostazione predefinita, tale risorsa di calcolo è configurata per l'autoscaling tra 8 e 16 CU, con lo scale to zero abilitato dopo 24 ore di inattività. Questi valori predefiniti potrebbero essere perfettamente ragionevoli per il tuo carico di lavoro, ma se la tua applicazione richiede meno risorse di calcolo, lasciarli invariati può significare pagare per una capacità superiore a quella necessaria.

Invece di creare il progetto e ricordarsi di ridimensionarlo in un secondo momento, puoi impostare l'intervallo di calcolo iniziale quando configuri il progetto a livello di codice. Ad esempio, utilizzando l'SDK Databricks:

Se gestisci Lakebase in modo dichiarativo con i Declarative Automation Bundles (DAB), puoi definire in modo simile l'intervallo di calcolo per gli endpoint configurati:

L'elemento più importante per il dimensionamento è il tuo working set: i dati e gli indici a cui l'applicazione accede frequentemente, a differenza delle dimensioni totali del database su disco. Un database da 2500 GB con un working set attivo di 20 GB non ha bisogno di 2500 GB di RAM. Richiede solo memoria sufficiente per mantenere memorizzati nella cache quei 20 GB, oltre a un certo margine di sicurezza. Questo è importante per via di come la risorsa di calcolo utilizza la memoria. La RAM scala in modo lineare con le dimensioni della risorsa di calcolo e fino al 75% della RAM di una risorsa di calcolo è disponibile come cache di calcolo. Quando il working set rientra in tale cache, la stragrande maggioranza delle letture viene servita dalla memoria, quindi rimangono veloci e la loro latenza rimane costante. Quando non vi rientra, Postgres deve recuperare dallo storage le pagine non presenti nella cache (cache miss), il che è molto più lento di un accesso in memoria e introduce una variabilità della latenza che si ripercuoterà sull'applicazione. Il dimensionamento consiste quindi in gran parte nello scegliere una risorsa di calcolo la cui cache superi il working set, lasciando al contempo un margine per altre operazioni. Tuttavia, la memoria non è l'unica cosa che scala con le dimensioni della risorsa di calcolo. Valuta anche la complessità delle query, la concorrenza e i tuoi obiettivi di latenza, perché un carico di lavoro altamente concorrente o sensibile alla latenza richiede un margine maggiore rispetto a uno strumento interno poco utilizzato a parità di dimensioni dei dati.

Anche le connessioni al database meritano una particolare attenzione. max_connections, il limite massimo di connessioni Postgres simultanee, è determinato anche dalle dimensioni della risorsa di calcolo e, per una risorsa di calcolo con scalabilità automatica, segue una regola specifica: il limite è stabilito dal valore minore tra la CU massima e otto volte la CU minima. L'aumento del massimo, quindi, aggiunge connessioni solo fino a otto volte il minimo e, oltre quel punto, un minimo ridotto limita i vantaggi che un massimo più elevato può offrire. Un'applicazione che apre un numero elevato di connessioni può raggiungere questo limite e iniziare a rifiutare nuove connessioni con errori. Se il volume delle connessioni rappresenta un vincolo reale, tienine conto nella CU minima e inserisci un pooler di connessioni davanti a Lakebase. Un pooler consente a molte connessioni client di condividere un pool di connessioni Postgres e supporta fino a 10.000 connessioni client simultanee. Il pooling è solitamente la risposta corretta per le app che aprono molte connessioni ed è più economico rispetto al ridimensionamento della risorsa di calcolo al solo scopo di innalzare il limite di connessione.

Non devi andare a tentativi. La dashboard delle metriche di Lakebase riporta le dimensioni del working set in intervalli di 5 minuti, 15 minuti e 1 ora e le mostra direttamente accanto alla cache di calcolo disponibile, in modo da poter vedere a colpo d'occhio se i dati attivi vi rientrano. Analizzala insieme al tasso di hit della cache, alla CPU, alla RAM e all'utilizzo delle connessioni per convalidare il dimensionamento iniziale e regolarlo verso l'alto o verso il basso. Per i carichi di lavoro con pattern di accesso stabili, il confronto del working set di 1 ora con la cache di calcolo disponibile è un segnale particolarmente utile. La scalabilità automatica offre il massimo vantaggio quando il working set rientra già in memoria con la CU minima, perché altrimenti si paga una penalità per la cache fredda ogni volta che la risorsa di calcolo scala verso l'alto. Utilizza queste metriche per impostare un minimo che contenga il working set e un massimo che assorba i picchi.

Come si manifesta una risorsa di calcolo sottodimensionata

Il sottodimensionamento raramente si presenta come un guasto totale. Più spesso si manifesta con sintomi facili da diagnosticare in modo errato:

  • Latenza delle query lenta e incoerente. Quando il working set non rientra più nella cache, le letture che non trovano riscontro nella cache vanno allo storage. La latenza mediana potrebbe apparire ancora adeguata, mentre p95 e p99 aumentano e diventano irregolari, poiché le prestazioni ora dipendono dal fatto che i dati di una determinata query siano stati memorizzati o meno nella cache.
  • Un rapporto di hit della cache in calo. Questo è l'indicatore principale del fatto che il working set ha superato la cache disponibile e inizia a scendere prima che la latenza peggiori visibilmente.
  • Saturazione della CPU e accodamento delle query. Una risorsa di calcolo sottodimensionata blocca la CPU sotto carico, quindi le query attendono, il throughput si stabilizza e la latenza aumenta a tutti i livelli.
  • Errori di connessione. Ogni dimensione della risorsa di calcolo prevede un limite massimo di connessioni simultanee; quando i client lo superano, le nuove connessioni vengono rifiutate con errori di tipo "too many clients" anziché degradare gradualmente.
  • Penalità per cache fredda dopo la scalabilità o il riavvio. Dopo un riavvio da una scalabilità a zero, o quando la scalabilità automatica scala inizialmente verso l'alto, la cache parte vuota e deve riscaldarsi. Noterai un picco di query più lente finché il working set non viene nuovamente memorizzato nella cache; ecco perché le dimensioni minime della risorsa di calcolo contano tanto quanto quelle massime.

Ottimizza la tua strategia di PITR e snapshot

Il ripristino a un momento specifico (PITR) mantiene continuamente la cronologia necessaria per ripristinare il database in qualsiasi momento all'interno di una finestra di ripristino configurabile di 2-30 giorni. Gli snapshot, d'altra parte, sono acquisizioni discrete in un determinato momento di un ramo radice che possono essere create manualmente o in base a una pianificazione automatica giornaliera, settimanale o mensile.

Lo storage PITR cresce sia con l'attività di scrittura che con la lunghezza della finestra di ripristino, poiché Lakebase deve conservare la cronologia delle modifiche durante tale periodo. Per un'applicazione con un numero elevato di scritture, una finestra PITR lunga può comportare un consumo di storage significativo. Un approccio attento ai costi consiste nello scegliere una finestra PITR che soddisfi i requisiti di ripristino di emergenza e integrarla con snapshot pianificati quando sono necessari punti di ripristino a più lungo termine.

La buona notizia è che entrambi hanno una tariffa inferiore rispetto allo storage dei branch Lakebase standard. Lo storage degli snapshot ($0,090/GB-mese) è circa il 74% più economico rispetto allo storage dei branch standard, mentre lo storage PITR ($0,200/GB-mese) è circa il 42% più economico. Gli snapshot pianificati possono essere particolarmente efficienti in termini di storage: il primo snapshot di una pianificazione viene memorizzato come snapshot completo, mentre per gli snapshot successivi vengono addebitate solo le modifiche incrementali.

Utilizza il PITR per eseguire il ripristino da incidenti imprevisti, come eliminazioni accidentali o scritture errate che potrebbero verificarsi in qualsiasi momento all'interno della finestra di ripristino. Utilizza gli snapshot per i punti di ripristino pianificati. Ad esempio, acquisisci uno snapshot manuale prima di una migrazione rischiosa o di un aggiornamento collettivo e utilizza gli snapshot pianificati per una protezione ordinaria a lungo termine.

In definitiva, adegua la configurazione di ripristino ai tuoi effettivi requisiti di ripristino. Conservare più cronologia o punti di ripristino del necessario può aumentare i costi di storage senza fornire un valore aggiunto significativo.

Individuare i costi di Lakebase

Come descritto sopra, i costi di Lakebase si suddividono in tre aree: calcolo del database, storage del database e, quando si utilizzano le Synced Tables, il calcolo della pipeline serverless utilizzato per sincronizzare i dati dal Lakehouse a Lakebase.

La risorsa di calcolo viene misurata in base all'utilizzo delle CU nel tempo. Con la scalabilità automatica, l'utilizzo segue la capacità di calcolo consumata man mano che il database scala all'interno dell'intervallo configurato.

Lo storage include lo storage dei branch del database, la cronologia del ripristino a un momento specifico (PITR) e lo storage degli snapshot. Questi vengono misurati separatamente in base all'utilizzo dello storage sottostante.

Le Synced Tables utilizzano pipeline gestite per spostare i dati da Unity Catalog a Lakebase. La risorsa di calcolo della pipeline utilizzata per la sincronizzazione viene fatturata separatamente dalla risorsa di calcolo del database Lakebase.

Visualizzare i costi di calcolo e storage di Lakebase

L'utilizzo delle risorse di calcolo e dello storage di Lakebase è disponibile in system.billing.usage. L'utilizzo dello storage può essere ulteriormente suddiviso utilizzando product_features.lakebase.storage_type:

  • BRANCH_DATA_STORAGE: storage per i branch del database senza scadenza
  • BRANCH_CHANGE_STORAGE: dati modificati memorizzati per i branch in scadenza
  • BRANCH_HISTORY_STORAGE: cronologia conservata per il PITR

La query seguente unisce usage a system.billing.list_prices per stimare il costo giornaliero al prezzo di listino effettivo.

Lakebase espone SKU di calcolo e archiviazione separati nelle tabelle del sistema di fatturazione, con il campo del tipo di archiviazione che fornisce la scomposizione aggiuntiva mostrata sopra.

Puoi trovare l'UID del progetto nella UI di Lakebase sotto Project > Settings > UID. A livello di codice, se conosci il nome del progetto, elenca i progetti e trova la corrispondenza su status.display_name per recuperare il suo UID.

Visualizza i costi della pipeline di Synced Table

Anche l'utilizzo della pipeline di Synced Table può essere interrogato da system.billing.usage. Filtra in base all'ID della pipeline sottostante ed esegui un join con system.billing.list_prices per stimare il costo giornaliero della pipeline.

Queste query stimano il costo utilizzando il prezzo di listino effettivo per il periodo di utilizzo. Gli sconti contrattuali specifici per il cliente non sono considerati.

Puoi trovare l'ID della pipeline aprendo la Synced Table nella UI e copiando Pipeline ID. A livello di codice, recupera la Synced Table e leggi status.pipeline_id:

Mettendo tutto insieme

Lakebase è progettato per essere efficiente in termini di costi fin dall'architettura, dallo storage condiviso e branching all'autoscaling e al calcolo serverless. Combina queste efficienze integrate con una configurazione attenta in termini di dimensionamento, strategia di sincronizzazione e ripristino, e potrai mantenere i costi prevedibili garantendo al contempo le prestazioni, la disponibilità e la developer experience di cui le tue applicazioni hanno bisogno.

(Questo post sul blog è stato tradotto utilizzando strumenti basati sull'intelligenza artificiale) Post originale

Ricevi gli ultimi articoli nella tua casella di posta

Iscriviti al nostro blog e ricevi gli ultimi articoli direttamente nella tua casella di posta.