versione italiana versione italiana
english version english version

Very Large Dimension

All’avviamento di Analysis Services, tutte le dimensioni di tutti i database sono caricate in RAM (precisamente, in memoria virtuale). L’unica eccezione sono le dimensioni ROLAP, mentre tutte le dimensioni MOLAP (anche quelle eventualmente associate a un cubo con partizioni ROLAP) rientrano in questa lettura iniziale. Ricordiamo che le dimensioni ROLAP sono obbligatorie quando il numero di elementi in una dimensione supera i 10 milioni.

Questo caricamento ha alcuni effetti collaterali importanti: consuma una grande quantità di memoria virtuale e allunga i tempi di partenza del servizio, perché i dati sono fisicamente letti dai file delle dimensioni per essere caricati in RAM (ed eventualmente paginati su disco se non c’è RAM sufficiente).

 

Normalmente, tutte le dimensioni sono caricate all’interno dello spazio di processo di Analysis Services: su Task Manager la cosa è ben visibile analizzando la memoria occupata dal processo msmdsrv.exe, consultando la colonna “VM Usage” (in italiano “Dimensione memoria virtuale”, da non confondersi con “Utilizzo memoria” visibile per default). In Windows a 32 bit un processo ha uno spazio di indirizzamento disponibile per l’applicazione di 2Gb, che può arrivare a 3Gb sulle versioni enterprise con l’abilitazione /3Gb. Talvolta questo è un limite, perché la somma delle dimensioni di tutti i database potrebbe occupare uno spazio superiore a tale limite.

Per ovviare al problema, la versione Enterprise di Sql Server consente ad Analysis Services di caricare una o più dimensioni attraverso il Very Large Dimension Manager: la chiave di registry VLDMThreshold definisce un valore limite della grandezza della dimensione in byte (calcolata senza considerare le member property, anche se queste sono comunque caricate in memoria) oltre il quale la dimensione stessa è caricata in un processo separato, che è proprio il Very Large Dimension Manager (msmdvldm.exe).

Tutto bene? Non proprio. Bisogna infatti valutare gli effetti collaterali di quest’azione, ponderando il giusto valore di VLDMThreshold e l’eventuale uso di strategie alternative (una descrizione completa delle voci di Registry di Analysis Services è disponibile su http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql2k/html/sql2k_anservregsettings.asp).

I problemi sono prima di tutto prestazionali: la comunicazione tra due processi rende il caricamento della dimensione e le successive interrogazioni dei cubi che la usano meno performanti rispetto al caso in cui è tutto caricato nello stesso processo. Una prima considerazione è che bisogna usare il Very Large Dimension Manager solo quando non se ne può fare a meno. Questo significa anche cercare di ridurre il numero di dimensioni gestite in processi esterni.

Ogni dimensione che supera il limite definito da VLDMThreshold è caricata in un processo distinto: con Task Manager è possibile osservare tante istanze di msmdvldm.exe quante sono le dimensioni che superano tale limite. Per evitare di caricare troppe dimensioni su processi esterni è necessario alzare il valore di VLDMThreshold. Ovviamente, un valore troppo alto potrebbe pregiudicare la possibilità di far partire il servizio, perché le dimensioni potrebbero non essere caricabili tutte nello stesso processo.

 

Proviamo a fare qualche esempio pratico. In una situazione con un solo database, con alcuni cubi e due dimensioni da 128Mb ciascuna, più altre dimensioni minori (con solo qualche decina di elementi ciascuna), vedremmo due istanze di msmdvldm.exe; può avere senso alzare il valore di VLDMThreshold portandolo a 200Mb, così da caricare tutte le dimensioni in msmdsrv.exe (il cui valore di dimensione di memoria virtuale impegnata aumenterà, eliminando però le due istanze di msmdvldm.exe). Dopo ogni modifica di VLDMThreshold è necessario riavviare il servizio o riprocessare i database.

In un’altra situazione, invece, potrebbe essere necessaria l’operazione opposta: se si hanno molte dimensioni da 50Mb (magari su molti database diversi), potrebbe essere necessario abbassare il valore di VLDMThreshold così da caricare tali dimensioni in processi separati. In realtà è auspicabile che un caso del genere non si verifichi rispetto al valore di default di 64Mb, mentre è più probabile che, a distanza di tempo, sia necessario abbassare un valore di VLDMThreshold precedentemente modificato: quello che andava bene con un certo numero di database potrebbe non consentire più il caricamento del servizio con un nuovo database che fa superare il limite dei 2 o 3 Gb.

Dunque, se ci si scontra con questi problemi è necessario trovare un compromesso tra prestazioni e limiti del sistema operativo. Troppi processi msmdvldm.exe incidono molto negativamente sulle prestazioni. Esistono soluzioni alternative? Un paio…

 

La soluzione definitiva (almeno fino alla prossima versione di SQL Server, nome in codice Yukon… ma se ne parla nel 2005) è quella di passare a SQL Server a 64 bit: in questo modo non esiste più il limite dello spazio di indirizzamento di 2/3Gb (nel senso che esiste ma è aumentato a 8Tb, cioè 8192Gb), ma bisogna poterselo permettere perché significa nuovo hardware e un nuovo sistema operativo (Windows a 64 bit).

L’altra soluzione è invece quella di aggirare il problema, ragionando sui motivi per cui ci si viene a trovare in una situazione critica. Mediamente, le dimensioni molto grandi solo legate a un’anagrafica clienti/utenti: spesso, dal punto di vista dell’analisi OLAP, questo livello di dettaglio non è particolarmente significativo, perché è improbabile che un singolo cliente sia oggetto di filtro o di analisi. Il più delle volte, tale livello di dettaglio è considerato importante perché, a fronte di una navigazione nei dati che evidenzia un’anomalia, si desidera avere il dettaglio dei clienti che contribuiscono a formare un valore definito “anomalo” (nel bene o nel male). Per ottenere questo servizio, però, è sufficiente avvalersi delle funzionalità di Drillthrough del cubo: in questo modo si può ridurre la granularità della dimensione incriminata, magari limitandosi al livello gerarchico immediatamente superiore (potrebbe essere la città in una gerarchia Paese/Regione/Provincia/Città/Cliente). Ovviamente, se al cliente erano associati degli attributi che definivano delle dimensioni virtuali, questi dovranno essere spostati nella tabella dei fatti puntando a dimensioni reali create appositamente: spesso, però, pur aumentando il numero complessivo di dimensioni, si riesce in questo modo ad abbassare la pressione complessiva sulla memoria, perché si abbassa drasticamente il numero di elementi della dimensione più critica (che passa da qualche centinaio di migliaia se non milioni a poche migliaia).

Anche la seconda soluzione presenta delle insidie, perché si viene a togliere qualche possibilità di analisi (ad es. la ricerca dei 10 migliori/peggiori clienti), ma come tutti i compromessi bisogna saper valutare quale è il giusto bilanciamento. Un compromesso nel compromesso potrebbe essere quello di mantenere il livello di granularità di una dimensione critica, modificandone radicalmente la grandezza intervenendo sulla dimensione di ogni record. Spesso la dimensione clienti/utenti presenta nella descrizione il nome completo del cliente/utente, arrivando a occupare mediamente 30/40 caratteri (perché oltre a nome/cognome si mette nella descrizione anche un codice identificativo, per discriminare le omonimie). In alcuni casi, si può recuperare una quantità considerevole di spazio abbassando la lunghezza di tale descrizione, magari includendo solo un codice identificativo nella descrizione, eliminando alcune proprietà (se non sono significative per l’analisi) e usando le Action per puntare a un sistema di reperimento delle informazioni del cliente dal database relazionale (per esempio una Intranet). Non è una soluzione che facilita la lettura dei dati, ma ancora una volta si tratta di un compromesso che potrebbe “rendere funzionante” un sistema le cui funzionalità sono pregiudicate dal raggiungimento dei limiti.

 

Un’ultima nota per gli sviluppatori. Spesso, in una macchina di sviluppo, si mantengono on-line molti database, non tutti effettivamente utilizzati. Se questi database sono stati elaborati, le loro dimensioni sono caricate in memoria all’avviamento del servizio di Analysis Services. Oltre ai fastidiosi tempi di caricamento, questo significa occupare risorse preziose della macchina di sviluppo (leggi memoria). Se alcuni database non sono effettivamente necessari, è utile metterli “off-line”: purtroppo questa funzionalità non è disponibile nativamente, ma ne parliamo nell’articolo “Backup Olap: come salvare le strutture senza i dati”. In questo modo, caricando solo i database effettivamente necessari, si ha il doppio beneficio di una minore occupazione di memoria e di tempi di avviamento del servizio ridotti.