|
Il server va piano, come mai?
È una domanda che spesso mi sento rivolgere dai miei nuovi clienti... quando la "massa" di computer, "server" (pseudotali), switch, hub, mouse con filo e senza filo, webcam e altre diavolerie, diventa tale da essere più complessa di un filamento di RNA e, "ad occhio" qualcosa sembra non funzionare a dovere.
Premesso che il problema spesso dipende dall'assenza del "sistemista" full time e competente, sostituito in deroga o dal ragioniere contabile sbrigatutto (e magari anche socio), se siamo nella piccola o piccolissima impresa, oppure dalla presenza smodata di macchine con sistema operativo Windows e apparecchiature di bassa qualità (switch comperati a pallet da Auchan e cose simili...).
In questo breve articolo intendo soffermarmi su un aspetto in particolare delle performance del server di database. Esiste quasi sempre un server dedicato alla memorizzazione dei dati, che cresce "smodatamente"... fino a che non occorre passare ad un DBMS.
Quando mi viene lasciata facoltà di aiutare davvero il cliente, ossia quando non occorre mediare con il fornitore di turno che spinge per la solita soluzione Microsoft Access o Microsoft SQL Server... pianifico la migrazione delle sorgenti dati sul database PostrgreSQL e su un hardware degno del titolo nobiliare di "server".
Contrariamente a quanto si può immaginare, la spesa finale complessiva, inclusa quindi anche la mia modesta "retribuzione occasionale", è nella maggioranza dei casi inferiore al costo totale delle licenze dei prodotti di Redmond e del "tempo perso" a risolvere problemi che sorgono entro i primi sei mesi dal rilascio in produzione.
Intendiamoci, nessun astio preconcetto sui "prodotti" di Microsoft. Parlo per esperienza pregressa su questi prodotti e immaginando che l'obiettivo del committente sia quello di ottenere, fin da subito, un sistema di elaborazione dati efficiente e poco costoso da manutenere nel tempo. Risultato che le mie modeste capacità mi permettono di conseguire adottando soluzioni e software che tanti altri sistemisti e programmatori nel mondo condividono "apertamente".
Un aspetto particolare del server di base dati è spesso poco attenzionato: le prestazioni del "core" della CPU e la configurazione delle RAM. In molti manuali di PostgreSQL (e non solo) si legge "Keeping Information Near the CPU".
La velocità del core del microprocessore è uno dei "colli di bottiglia" dei sistemi moderni. L'altro principale punto critico è la velocità delle memorie RAM. Per esempio passare da RAM DDR2 a DDR3 o meglio ancora a DDR-1333, supportate dalle recenti configurazioni (AMD e Intel based).
Attualmente le prestazioni migliori si ottengono con CPU multicore di AMD anche se Intel non perde tempo e sta approntando la controproposta mi pare chiamata in codice "Sandy Bridge" (uscirà per la fine del 2010).
PostgreSQL, nato oltre venti anni fa presso l'università di Berkeley, si è evoluto fino a diventare il migliore database open source, con alle spalle una comunità internazionale, altrettanto attiva quella italiana.
Le principali caratteristiche: multipiattaforma (Windows, Linux, Unix), scritto in C, supporta le transazioni, ACID, utilizza WAL (write ahead log). Row Level Locking e gestione eccellente dei Table Spaces.
Supporta triggers e funzioni, linguaggi procedurali e tipi di dati personalizzabili e il point in time recovery. Mentre i "limiti" di PostgreSQL:
- dimensione massima di una tabella: 32 TeraByte
- massima dimensione di una riga: 1,6 TeraByte
- massima dimensione di un campo: 1 GigaByte
- illimitato numero di righe e tablle, illimitato numero di indici
Vi renderete conto da soli che prodotti semiludici, come Microsoft SQL Server o peggio, Access (indegnamente inserito nel novero dei DBMS) non possono tenere testa a PostgreSQL.
Tornando a PostgreSQL e all'ottimizzazione delle prestazioni. Il file di riferimento è postgresql.conf, contiene circa 200 parametri raggruppati in dieci categorie. Partiamo dalle informazioni sul numero di utenti che possono connettersi al database. Questi parametri sono regolati dalle dichiarazioni permax_connections e superuser_reserved_connections.
La prima variabile imposta il numero massimo di connessioni che PostgreSQL accetterà, mentre la seconda si riferisce al numero di connessioni riservate all'utente di amministrazione (superuser). Di solito queste due variabili vengono configurate all'atto dell'installazione da initdb sulla base di informazioni esposte dal kernel in uso.
In linea generale, all'aumentare del numero di connessioni aumenta anche la richiesta di risorse del sistema. PostgreSQL offre la possibilità di creare un "pool di connessioni" se il numero di richieste dovesse essere elevato (ad esempio oltre 1000). Altri parametri sui quali agire, comunque, per migliorare le prestazioni di PostgreSQL sono l'ottimizzazione dell'uso e dell'accesso alla memoria (come dicevamo prima)e ai dischi, oltre che una buona "ingegnerizzazione" degli indici e delle query.
Quando si lavora con il file postgresql.conf è bene tenere presente le differenti unità di misura secondo che si agisca sui registri della CPU, sulla cache o sulla RAM oppure sui dischi.
PostgreSQL non agisce direttamente sul disco, ma scrive le informazioni nello shared buffers, quindi è opportuno ottimizzare l'uso della memoria RAM in modo che lo shared_buffers abbia la giusta dimensione per consentire agli altri programmi di girare senza intoppi: uno valore troppo grande causerebbe swapping sul disco quindi un deterioramente delle performance complessive del sistema.
Il valore predefinito di shared_buffers è 32 Mb, come si legge nei commenti del file postgresql.conf, deve essere aumentato ad almeno 128 Kb e almeno 16Kb per ogni connessione dichiarata nella variabile max_connections.
Se si possiede una CPU a 64bit, questo valore può anche superare i 2Gb. Sovente occorre agire sulle impostazioni del kernel (sia che sia abbia una CPU a 32bit che a 64bit), per poter ampliare questi valori predefiniti. Le variabili del kernel sulle quali agire sono SHMMAX e SHMALL.
La variabile work_mem interessa sempre la memoria RAM "non shared", cioè quella che viene usata per le operazioni interne di ordinamento. Il valore di default è 1Mb e viene allocata per multipli di potenze di 2.
Esiste una regola approssimativa per calcolare il giusto valore: iniziare con il 25% del totale della RAM disponibile sul server assegnandola a shared_buffers e il 4% della RAM assegnata a work_mem. Se il sistema "non swappa", è possibile aumentare i valori. Viceversa diminuirli. Il valore di temp_buffers agisce invece sul numero massimo di buffers temporanei usati per ogni sessione di PostgreSQL.
Se l'applicazione che si appoggia al databse fa uso intensivo di tabelle temporanee, conviene aumentare questo valore, che di default è impostato a 8Mb.
Quando si effettuano operazioni come VACUUM, CREATE INDEX oppure ALTER TABLE (per aggiungere una FOREIGN KEY), conviene avere un valore di maintenance_work_mem superiore a quello di 16Mb di default.
Approfondimenti:
|