2. DataStore: caratteristiche [1]
Il Google App Engine Datastore è un sistema di
memorizzazione "schema-less", la cui unità fondamentale di
memorizzazione è l'Entity, formato da una Key immutabile e da
zero o più proprietà mutabili.
Gli Entity possono essere creati, aggiornati, cancellati, caricati
per Key e ricercati per valore delle proprietà tramite Query.
Il DataStore può essere usato in modo transazionale, anche
con il supporto della "current transaction".
3. DataStore: building blocks [2][3][6]
Il GAE DataStore è una tipica "composizione" di tecnologie
Google
Indici e transazionalità basati su MegaTable
persistente grazie al GFS
distribuita grazie a Chubby
4. DataStore: BigTable
Per usare in modo corretto il DataStore di GAE è
necessario conoscere BigTable, componente che ne
caratterizza la persistenza non relazionale.
Le API JDO/JPA che GAE ci mette a disposizione
infatti cercano di mostrarcelo come relazionale,
rischiando però che il DataStore venga utilizzato
come RDBMS.
5. BigTable: definizione [4]
"A Bigtable is a sparse, distributed, persistent multi-
dimensional sorted map"
ovvero
E' un array associativo :
sparso perchè memorizza solo i valori non "vuoti"
distribuito nel cloud di Google
persistente sul Google File System
multidimensionale nel numero di colonne
ordinato lessicograficamente per chiave
6. BigTable: vista "fisica"
La chiave è una terna:
row: String
column: String
timestamp: long
Ad ogni chiave è associato un valore che invece è un array
di byte.
7. BigTable: vista logica (row)
la row è sempre "com.cnn.www"
abbiamo due famiglie di colonne: contents e anchor
"contents" referenzia tre versioni di contenuto, HTML della
pagina
Le due "anchor" invece hanno una sola versione, con la
descrizione del link.
8. BigTable: row string
E' una stringa arbitraria, fino a 64kb, anche se di solito è
composta di qualche decina di caratteri con un significato
nel contesto del dominio del problema
Le modifiche per riga sono atomiche in lettura e scrittura, a
prescindere dal numero di colonne che si vanno a
modificare (no multiriga)
La riga è anche usata per mantenere ordinati
lessicograficamente i dati e per partizionarli dinamicamente
9. BigTable: tablet
Un range di dati ordinati per riga è chiamato "tablet"
La "tablet" è l'unità minima di distribuzione e load-balancing
(circa 200MB)
Un accesso a dati per righe continue è molto efficiente
perchè tocca il numero minimo di "tablet" e quindi di accessi
a macchine remote
E' importante in fase di design scegliere un principio di
massima località per le righe
Ad es. per l'ordinamento di righe di una table di
indicizzazione può essere vantaggioso il reverse-domain
order (ad.es net.lucamasini.www/page1.html e net.
lucamasini.www/page2.html sono probabilmente nello
stesso tablet)
10. BigTable: column families
Le colonne sono raggruppate in "column families" che
rappresentano l'unità di controllo degli accessi
Si rappresentano con la sintassi:
family:qualifier
Un esempio di colonne può essere:
language:it_IT
anchor:com.yahoo.www
anchor:com.google.www
Su ogni singola famiglia di una BigTable possiamo decidere
per ogni principal se può leggere, scrivere, aggiornare.
11. BigTable: timestamp
La versione è mantenuta con un intero a 64bit
Se "automatic" allora è assegnata da BigTable e
rappresenta il tempo in microsecondi (?????)
Un'applicazione può anche decidere di assegnarlo, facendo
attenzione all'unicità
Le righe sono memorizzate in ordine inverso di timestamp
La garbage collection delle righe può avvenire secondo due
politiche:
ultime n versioni
versioni più vecchie di un tempo T
L'applicazione sceglie la politica di GC e il parametro di
configurazione
12. BigTable: esempio scrittura
// Apre la tabella dato il namespace
Table t =
BigTable.
openOrDie("/bigtable/web/webtable");
// Prepara un aggiornamento della riga
RowMutation rm =
new RowMutation(t, "com.cnn.www");
rm.set("anchor:www.c-span.org", "CNN");
rm.delete("anchor:www.abc.com");
// Applica atomicamente la RowMutation
Operation op = BigTable.apply(rm);
13. BigTable: esempio lettura
Scanner scanner = new Scanner(t);
ScanStream stream =
scanner.fetchColumnFamily("anchor");
stream.setReturnAllVersions(true);
scanner.lookup("com.cnn.www");
for (; !stream.done(); stream.next()) {
System.printf("%s %s %lld %sn",
scanner.getRowName(),
stream.getColumnName(),
stream.getMicroTimestamp(),
stream.getValue());
}
14. DataStore: JPA/JDO come astrazione della BigTable
Come abbiamo visto le differenze rispetto ad un DB
relazionale sono molte e decisive
Disegnare il modello senza tenere di conto ad esempio di
una modellazione corretta della Key può far decadere in
modo definitivo le performance
A questo aggiungiamo che per chi usa GWT come layer di
presentation i modelli non sono “serializzabili” (a meno di
qualche trucco o uso di librerie esterne)
15. DataStore: API dirette
Può essere conveniente usare direttamente le API di
accesso al DataStore, saltando lo strato JPA/JDO, così da
sfruttare appieno le feature del repository distribuito.
Con il comando di query asincrono possiamo anche
lanciare più thread per eseguire le nostre query, che con un
procedimento alla MapReduce divide il lavoro di selezione
su più job che girano in parallelo nel cloud di Google [5].
16. DataStore: esempio d'uso
Entity paramEntity = new Entity(KIND);
paramEntity.setProperty("nome", "Luca");
paramEntity.setProperty("cognome", "Masini");
final DatastoreService datastoreService =
DatastoreServiceFactory.getDatastoreService();
Key key = datastoreService.put(paramEntity);
PreparedQuery pq = datastoreService.prepare(
new Query(KIND));
for(Entity entity: pq.asIterable()) {
....
}
17. DataStore: problemi
GQL non supporta operatori comuni di SQL, come LIKE e
OR
Trattandosi di un repository non relazionale dobbiamo
gestire "manualmente" le relazioni tra le varie entità
SELECT *
FROM indirizzi a, persone b
WHERE b.id_indirizzo = a.id
AND (b.nome = 'Luca' OR b.nome='Alberto')
OR a.comune like 'F%'
18. DataStore: il relazionale è dentro di noi
Ricordiamoci sempre che siamo abituati a pensare in termini
relazionali perchè la tecnologia vincente degli ultimi 35 anni è
stata proprio il DataBase Management System Relazionale .
Spesso siamo convinti che tutte le soluzioni abbiano una buona
implementazione relazionale, ma questo non è assolutamente
vero, basta pensare alla fatica che dobbiamo fare per mappare
le nostre gerarchie di oggetti Java anche con i più moderni
ORM.
E' su questa "forma mentis" che dobbiamo lavorare per poter
usare a pieno i nuovi strumenti di Cloud-Computing che Google
ad altri vendor ci stanno mettendo a disposizione.
19. DataStore: domande per Ikai
Dov'è finità la possibilità di versionare i contenuti, nativa di
BigTable ??
Credono di rendere disponibili API che permettano una più
facile parallelizzazione delle query, per sfruttare a pieno le
caratteristiche di BigTable e del Cloud ?
In alternativa alla precedente, potrebbero darci la possibilità
di usare algoritmi alla MapReduce
Pensano di darci la possibilità di indicizzare anche il
contenuto e non solo le column-families ?
Hanno in ponte un RESTful gateway per il DataStore di
GAE ??
Modellazione con JPA/JDO o DataStore API ??