Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB

Post on 27-Jan-2015

120 views 6 download

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 of Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB

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 s.maraspin@mvassociati.it

Stefano Valle @stefanovalle s.valle@mvassociati.it