polyglot persistance con postgresql, couchdb, mongodb, redis e orientdb
DESCRIPTION
Pirma parte del seminario su NoSQL al DiTeDi di Udine del 15/12/2012. Affrontato il caso di studio di un'architettura enterprise, basata su datastore relazionali (PostgreSQL) e non (CouchDB, MongoDB, Redis e OrientDB).TRANSCRIPT
Polyglot Persistance Esempio di architettura basata
su PostgreSQL, CouchDB, MongoDB, Redis e OrientDB
DiTeDi, Udine - Italia 15-12-2012
@maraspin
@stefanovalle
http://www.mvassociati.it/
IL CONTESTO
L’OBIETTIVO
DATI IN TEMPO REALE
REPERIMENTO FEEDBACK IMMEDIATO
MENO HARDWARE NEGLI HOTEL
Partiamo da stack LAMP/LAPP
11
PostgreSQL Backend
12
Chi usa PostgreSQL?
13
Gestione "meta" dati di: • Hotel • Applicazioni • Configurazioni • Personalizzazioni • Utenti • ACL • RELAZIONI tra essi
14
Modello relazionale
15
Film
TitoloNome CategoriaRating CategoriaAnnoVisioniGradimentiVoto
Diamo un’occhio ai dati…
16
E se voglio cambiare rating per i drammatici?
Normalizzazione
17
Schema aggiornato
18
Come sono memorizzati i dati
19
E se vogliamo un report?
20
SELECT film_normal.* , categoria.* FROM film_normal JOIN categoria on categoria.id = film_normal.categoria_id
JOIN: Operazione impegnativa
21
X
Morale: considerare sempre i benefici della normalizzazione. Ci torniamo tra poco!
Indici
22
EXPLAIN ANALIZE SELECT …
O(N) -> O(log N)
PostgreSQL vs MySQL
23
Idea: SELECT titolo, max(visioni) FROM film;
Qual’è il film più visto?
MySQL
24
SELECT titolo, max(visioni) FROM film;
PostgreSQL
25
SELECT titolo, max(visioni) FROM film;
SELECT titolo, max(visioni) FROM film;
SQL error: ERROR: column "film.titolo" must appear in the GROUP BY clause or be used in an aggregate function at character 8 In statement: SELECT titolo, max(visioni) FROM film;
PostgreSQL
26
SELECT titolo, max(visioni) FROM film;
SELECT titolo, max(visioni) FROM film;
SQL error: ERROR: column "film.titolo" must appear in the GROUP BY clause or be used in an aggregate function at character 8 In statement: SELECT titolo, max(visioni) FROM film;
27
Disclaimer: Ciò non significa che non utilizziamo anche MySQL in determinati contesti
Ocio però!
Perchè cio?
28
Risultato Casuale
SELECT titolo, max(visioni) FROM film;
Tabelle Sparse
29
Possibile Soluzione
30
CREATE VIEW film AS SELECT titolo, anno, visioni FROM film_provider1 UNION SELECT titolo, anno, visioni FROM film_provider2;
POI SU UPDATE…
Alternativa
32
Supporto per Ereditarietà
33
CREATE TABLE film ( id integer NOT NULL, titolo character varying(50), anno integer, visioni integer ); CREATE TABLE film_provider1 ( gradimenti integer ) INHERITS (film); CREATE TABLE film_provider2 ( voto integer ) INHERITS (film);
Comportamento dell’Ereditarietà
34
select * from film; select * from film_provider1;
Write Ahead Log (Journal) • Apri il Log • Scrivici informazioni tipo “Questo dato va
qui (offset)” • Scrivi il file • Tenta il salvataggio su disco (fsync) • Modifica i dati • Segna sul Log che le operazioni sono
state compiute
35
http://www.depesz.com/2011/07/14/write-ahead-log-understanding-postgresql-conf-checkpoint_segments-checkpoint_timeout-checkpoint_warning/
Durevolezza dei Dati
36
MVCC
37
Supporto AutoVacuum
Replicazione con LOG – 8.4
38
Replicazione Streaming - 9.0
39
Replicazione Sincrona - 9.1
40
Failover
41
Cosa portare a casa: • Solido e Affidabile (Ingres 1974) • Potenti strumenti di programmazione
(PL/PGSQL, PL/Python, PL/Java, ...) • Object-Relational Database (eredità) • Interessanti add-ons (IE fuzzystrmatch) • Replicazione Master/Slave Integrata • PostGIS • Community estesa, know how consolidato
42
Da dove eravamo partiti?
43
E SE…
DISTRIBUZIONE DATI E LOGICA
47
COERENZA DEI DATI
DISPONIBILITÀ DEL SERVIZIO
Non potete avere tutto, ragazzi!
Prof. Eric Brewer http://www.cs.berkeley.edu/~brewer/
Se volete distribuire una base dati, qualora si venga a creare un partizionamento, dovete scegliere tra coerenza dei dati e disponibilità del servizio.
CAP Theorem, Nancy Lynch and Seth Gilbert, “Brewer's conjecture and the feasibility of consistent, available, partition-tolerant web services”, ACM SIGACT News, Volume 33 Issue 2 (2002), pg. 51-59.
Vediamo che significa
52
Vediamo che significa
53
Uno o più nodi non raggiungibili: partizonamento
Vediamo che significa
54
Hotel Farm
Uno o più nodi non raggiungibili: partizonamento
55
RINUNCIA ALLA DISPONIBILITÀ?
Non scordiamo neppure la latenza!
CAP Theorem
58
Consistency
Availability Partition Tolerance
Soluzioni disponibili
59
Consistency
Availability Partition Tolerance
Categoria CP: BigTable Hbase MongoDB Redis Memcached etc.
Categoria CA: RDBMS etc.
Categoria AP: DynamoDB CouchDB Cassandra SimpleDB Tokyo Cabinet Riak Voldemort etc.
Soluzioni disponibili
60
Consistency
Availability Partition Tolerance
Categoria CP: BigTable Hbase MongoDB Redis Memcached etc.
Categoria CA: RDBMS etc.
Categoria AP: DynamoDB CouchDB Cassandra SimpleDB Tokyo Cabinet Riak Voldemort etc.
Come abbiamo scelto? • Supporto multi-master • Facilità di sincronizzazione applicazione • Flessibilità del modello dati • Semplicità
61
Soluzioni disponibili
62
Consistency
Availability Partition Tolerance
Categoria CP: BigTable Hbase MongoDB Redis Memcached Scalaris etc.
Categoria CA: RDBMS GreenPlum etc.
Categoria AP: DynamoDB CouchDB Cassandra SimpleDB Tokyo Cabinet Riak Voldemort etc.
63
“designed with the web in mind”
Cos’è CouchDB? • Datastore Documentale (JSON) • Interfaccia HTTP • Replicazione master-master (con filtri) • Può contenere applicazioni Web
HTML/CSS/JS (Couchapp) • Pensato per contesti distribuiti • Un progetto dalla storia “travagliata”
64
Incontriamo Futon (demo live)
65
Schemaless
66
Schemaless
67
Replicazione Semplice
68
Supporto per modalità PULL e PUSH
Ma Semplice Davvero!
69
Aggiornati non solo i dati ma anche le viste (design docs)
Scenario di conflitto
70
CouchDB – The definitive guide – O’Reilly
Risoluzione del Conflitto
71
CouchDB – The definitive guide – O’Reilly
Versioni • ID / _rev • Meglio generare da se gli ID (sequenziali) • Aggiornamenti atomici sui documenti • Aggiornamento ottimista, MVCC • Coerenza Eventuale
72
POSSIAMO RISOLVERE I CONFLITTI
O CERCARE DI EVITARLI
Progettiamo per evitarli
75
{
"titolo": "Il Padrino",
"sommario": "..."
"visioni": 3873,
"gradimenti": 185,
}
Provider Camera 1
Camera 2
Progettiamo per evitarli
76
{
"titolo": "Il Padrino",
"sommario": "...",
"visioni": 3873,
"gradimenti": 185,
}
Provider Camera 1
Camera 2
{
"titolo": "Il Padrino",
"sommario": "...",
"visioni": 3873,
"gradimenti": 185,
}
Progettiamo per evitarli
77
{
"titolo": "Il Padrino",
"sommario": "..."
}
Provider Camera 1
Camera 2
{
"titolo": "Il Padrino",
"visioni": 3873,
"gradimenti": 185,
}
MVCC
Progettiamo per evitarli
78
{
"titolo": "Il Padrino",
"sommario": "..."
}
Provider Camera 1
Camera 2
{
"titolo": "Il Padrino",
"visioni": 3873,
"gradimenti": 185,
}
{
"titolo": "Il Padrino",
"visioni": 3873,
"gradimenti": 185,
}
{
"titolo": "Il Padrino",
"sommario": "..."
}
79
80
CouchApps
81
LOGICA LATO CLIENT
SVILUPPATORI
SERVER-SIDE
84
RELAZIONI
METADATI
Classico Backend
86
WebApps Generate Server Side
87
88
E QUINDI PRESENTATE AI CLIENT
Alto consumo di disco
90
0
2000
4000
6000
8000
10000
12000
14000
16000
DB Size (MB)
NB Quanto sopra su update!
Btree+, che Succede?
91
Questione di affidabilità, performance
COMPATTIAMO QUANDO POSSIBILE…
Indicatori di Performance • 350 evt/sec in inserimento • 3000 evt/sec se in batch mode • 100 evt/sec su update • 10 evt/sec durante compattazione
93
• NB: dati forniti unicamente per dare ordini di grandezza. Test eseguiti su server entry level IBM x3550 M3, 1x3.60 GHz Xeon, 4GB RAM, Dischi SAS in RAID 0
• CouchDB configurato con httpd max_connections = 2048, export ERL_MAX_PORTS=4096, export ERL_FLAGS="+A 4«, fsync
94
95
DI COSA AVREMMO BISOGNO?
SHARDING
Sharding
98
Da considerare: • Inerentemente più rischioso • Più onerosa la manutenzione e il backup
degli shard • Delicato decidere con quali criteri
• In SQL: “Join” tra shards costosi.
Replicazione delle tabelle “globali” – es. categorie film
99
Una possibile soluzione
100
Recap su CouchDB: • Ottima soluzione per contesti distribuiti • Non adatto per situazioni con frequenti
aggiornamenti e carichi (ingenti) costanti • API REST aiuta a scalare le letture • Bigcouch in aiuto sulle scritture • Architetture innovative con le Couchapp • Si possono usare strumenti Tipici Web:
HAproxy, Nginx
101
Da Tenere a Mente: • Attenzione alla generazione degli ID,
specie se distribuiti • Lo spazio su disco cresce e la
compattazione «inchioda» lo strumento • I «driver» disponibili non sempre sono di
alta qualità...
102
Da Tenere sotto controllo: • TouchDB
database CouchDB compatibile, adatto all’embedding in device mobili
• PouchDB libreria js: come avere CouchDB nel browser
103
Ulteriori Esigenze
104
“L’aggregatore”
105
RSS
Previsioni meteo
Vimeo
Eventi
...
Aggregatore
Architettura dell’aggregatore
106
RSS
Previsioni meteo
Vimeo
Eventi
...
REST API Crawler
CDN
Cosa scegliamo?
107
RSS
Previsioni meteo
Vimeo
Eventi
...
REST API Crawler
CDN
?
Cosa ci serve? • Flessibilità del modello dati • Semplicità • Facilità di dialogo con PHP • Scalabilità sulle letture • Flessibilità di query
108
Perché no CouchDB? • Flessibilità del modello dati • Semplicità • Facilità di dialogo con PHP • Scalabilità sulle letture • Flessibilità di query
109
INTERAGIRE CON COUCHDB
Quante visioni hanno avuto i film in totale?
MAP REDUCE
113
{
"_id": "39c7c57daddba704c2b04606de001373",
"info_type": "view",
"movie": "The Gladiator",
"views": 37
}
{
"_id": "39c7c57daddba704c2b04606de000a2f",
"info_type": "view",
"movie": "Spiderman",
"views": 10
}
{
"_id": "39c7c57daddba704c2b04606de000c92",
"info_type": "view",
"movie": "Shrek",
"views": 25
}
114
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
115
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
10 37 25
116
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
10 37 25
47 25
117
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
10 37 25
47 25
72
118
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
10 37 25
47 25
72
MAP
119
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
10 37 25
47 25
72
REDUCE
In CouchDB
120
function(doc) {
if (doc.info_type == 'view') {
emit(doc.movie, doc.views);
}
}
Map:
{
"_id": "39c7c57...",
"info_type": "view",
"movie": "The Gladiator",
"views": 37
}
Cosa fa il map?
121
Map: function(doc) {
if (doc.info_type == 'view') {
emit(doc.movie, doc.views);
}
}
{
"movie": "Spiderman",
"views": 10
}
{
"movie": "The Gladiator",
"views": 37
}
{
"movie": "Shrek",
"views": 25
}
10 37 25
Cosa fa il reduce?
122
Reduce: function (key, values, rereduce) {
return sum(values);
}
10 37 25
47 25
Dov’è il problema?
123
function(doc) {
if (doc.info_type == 'config') {
for (param in doc.params) {
emit(param, doc.params[param]);
}
}
}
Map:
Reduce: .... Non possiamo avere parametri in input!
Viste precalcolate su ciascun documento
124
“Hu(mongo)us”
About MongoDB • Datastore Documentale (JSON) • Database / Collezioni • Protocollo Binario • Tanto Marketing • Veloce quasi come /dev/null :-P • Update in place -> locks! • Flessibilità nelle query • Autosharding
125
Interagire con il DB è banale
126
Attenzione!
127
Query
128
// operatori di confronto
db.notizie.find({tipo: {$ne: ‘cnn’},
ora_reperimento: {$gt: 1352505039}
});
// eventi di oggi e (necessariamente) domani
db.evento.find( { data: { $all: [ ‘2012-11-10’,
‘2012-11-11’ ] } } );
// eventi di oggi e/o domani
db.evento.find( { data : { $in : [‘2012-11-10’
‘2012-11-11’ ] } } );
// eventi di una giornata sola
db.evento.find( { data : { $size: 1 } } );
// cerca dentro gli array
db.previsioni.find( { ‘settimana.temp_max’ : 20 } );
Performance VS Durevolezza
129
Le impostazioni predefinite (32bit e <v2.0) sono “rischiose” (no journal)
Performance VS Durevolezza
130
MongoDB a 32bit NON VA USATO in PRODUZIONE!
Replica Set
131
http://docs.mongodb.org/manual/core/replication/
Automated Failover
132
Recap su MongoDB: • Semplice (arma a doppio taglio!) • Linguaggio d’interrogazione potente • Ottima documentazione • Flessibilità nella configurazione • Driver disponibili per molti linguaggi • Sviluppo molto attivo • Supporto
133
Fare attenzione a: • Opzione safe, journaling • Si inchioda negli ordinamenti se non
definiti indici • Attenzione ai nomi! • Non farsi coinvolgere e cercare di
costruirci sopra DB relazionali
134
135
TUTTO A POSTO SIGNORE!
Cosa abbiamo considerato? • Performance • Semplicità • Expiration automatico dei valori • Gestione del cold start • Non è un problema la perdita di dati
-> Ok persistenza volatile, no replicazione
137
Perchè no Couch/Mongo? • Couch occupa troppo spazio, troppo lento • MongoDB poteva starci (soprattutto
perché TTL introdotte da poco – 12/09); • Ma ci sono soluzioni più semplici…
138
139
“An open source, advanced key-value store”
About Redis • Key/Value++ • Progetto Italiano (Salvatore Sanfilippo) • Protocollo Binario • Sponsorizzato da VMWare • Gestione expiry delle chiavi
140
Esempi di query
141
// Memorizzare un valore
> SET status ok
// Collezioni
> SADD luci_accese camera bagno
// Valore con scadenza prefissata
> SET status ok
> EXPIRE status 10 // in secondi
Sorted Sets
142
Recap su Redis: • E’ molto veloce • Salva su RAM (snapshot su disco) • E’ un’ottima soluzione di caching,
evitando problema cold start • Necessario avere abbastanza RAM • Può essere usato per delegare alcuni
calcoli costosi
143
144
COME STANNO ANDANDO LE COSE?
Cosa ci serve? • Gestire grandi moli di dati • Modello di dati che supporti correlazione
146
Com’è fatta una nostra app?
147
E una sessione d’uso?
148
E una sessione d’uso?
149
E una sessione d’uso?
150
E una sessione d’uso?
151
Cosa ci ricorda tutto ciò?
152
G=(V,E)
Un semplcie grafo
154
Con strumenti visti prima… • Query di Couch poco flessibili • Redis assenza indici secondari • MongoDB e Postgres forse ok ma limiti
nel traversare nodi non immediatamente adiacenti
155
Troviamo le visite a partire dalla
dashboard in un determinato periodo
Con RDBMS
157
SELECT p1 . * , p2 . * , v . *
FROM pagina AS p1
JOIN visita AS v ON v.pagina_da = p1.id
JOIN pagina AS p2 ON v.pagina_a = p2.id
WHERE p1.id =1
AND v.data_visita >0
AND v.data_visita <4
Il problema…
158
SELECT p1 . * , p2 . * , v . *
FROM pagina AS p1
JOIN visita AS v ON v.pagina_da = p1.id
JOIN pagina AS p2 ON v.pagina_a = p2.id
WHERE p1.id =1
AND v.data_visita >0
AND v.data_visita <4
O(log N) O(log M) O(log N)
Invece con un grafo:
159
O(1)
O(1)
Adiacenza senza necessità di consultare un indice!
160
“Multiple datamodels support”
Modello Dati
161
https://github.com/tinkerpop/blueprints/wiki/Property-Graph-Model
Interagire con OrientDB • Protocollo binario / REST • JSON • Tinkerpop Stack: Gremlin, Pipes
• SQL(+)
163
Select titolo, in.out.in.nome from #16:5
Replica Master-Master
Sync/Async - Configurabile 165
Recap su OrientDB:
• Ottima soluzione per gestire relazioni • Traversa 5 Milioni+ di record/sec • Progetto Italiano (Luca Garulli) • ACID • Supporta ereditarietà • Semplice da installare e avviare
166
167
Ringraziamento
168
Il know how utilizzato per la preparazione di questa presentazione è stato in buona parte acquisito durante lo sviluppo del sistema Hotel OnAir di concezione e proprietà di VDA Multimedia Spa, cui il case study di cui si è fatto accenno fa riferimento. Ringraziamo il team leader del progetto, Stefano Brenelli, e tutto il team di sviluppo, per l'interessante, edificante e proficua collaborazione. In particolare ringraziamo: Carlo Anselmi, Maurizio Battistella, Manuel Bitto, Nicola Busanello, Antonino Murador, Antonio Parrella, Nicola Pressi, Riccardo Zamuner, Michele Zanon, Tiziano Zonta. Ringraziamo anche i colleghi Diego Drigani e Dario Tion, nonchè tutto il PUG Friuli per i sempre utili confronti e consigli.
DOMANDE?
http://friuli.grusp.org/
http://www.ditedi.it/
Image Credits • http://www.flickr.com/photos/leandrociuffo/4128603357/ • http://www.flickr.com/photos/uggboy/8043043095/ • http://www.flickr.com/photos/kky/704056791/ • http://www.flickr.com/photos/shareandenjoy/7074965023/ • http://www.flickr.com/photos/ivyfield/4497654857/ • http://www.flickr.com/photos/craigmarren/6086280669/ • http://www.flickr.com/photos/getbutterfly/6317955134/ • http://www.flickr.com/photos/62698615@N08/5948655391/ • http://20bits.com/article/interview-questions-database-indexes • http://www.flickr.com/photos/iita-media-library/4808291918/ • http://www.flickr.com/photos/47108884@N07/6949078701/ • http://www.flickr.com/photos/rrrodrigo/4139483872/ • http://www.flickr.com/photos/latt/509790815/ • http://www.flickr.com/photos/spine/525988813/ • http://www.flickr.com/photos/latt/509790815/ • http://www.flickr.com/photos/antmoose/116845021/ • http://www.flickr.com/photos/charleylhasa/3374499088/ • http://www.flickr.com/photos/mcascherrypoint/6277623762/ • http://www.flickr.com/photos/superk8/2801590280/ • http://www.flickr.com/photos/cawley/1067814030/ • http://www.flickr.com/photos/mr_g_travels/863720665/ • http://www.flickr.com/photos/cortesdecima/6099516346/ • http://www.flickr.com/photos/portofsandiego/7777282856/ • http://www.flickr.com/photos/22750018@N05/4268345597/ • http://www.flickr.com/photos/petereed/132829587/ • http://www.flickr.com/photos/myfruit/7031263653/ • http://www.flickr.com/photos/maugiart/5014963068/ • http://www.flickr.com/photos/freefoto/3844247553/ • http://www.flickr.com/photos/incognito_rico/69242116/ • http://tinkerpop.com/ • http://www.slideshare.net/lvca/orientdb-distributed-architecture-11h • ttp://www.flickr.com/photos/dobs/4128798936/
172
Grazie per l’attenzione
Stefano Maraspin @maraspin [email protected]
Stefano Valle @stefanovalle [email protected]