Esplora E-book
Categorie
Esplora Audiolibri
Categorie
Esplora Riviste
Categorie
Esplora Documenti
Categorie
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Agenda
Giorno 1
Mattina Pomeriggio
● Introduzione ai database NoSQL ● Sicurezza: autenticazione dei client,
● MongoDB: database agile per il web! autenticazione tra nodi del cluster, encryption
● Dev key features: modello a documenti, delle connessioni mediante SSL
relational vs document, JSON, BSON, MQL ● Creazione di utenti e ruoli per l’autenticazione
● (MongoDB Query Language), shell dei client
● Ops key features: pluggable architecture, storage ● Replica: principi e funzionamento
engines, replica, sharding ● Architetture di deploy di un replica set
● Mongo, mongod, mongos, mongodump, ● Esempio pratico di creazione di un replica set
mongorestore, mongoimport, mongoexport
● Installare MongoDB
DevOps
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Agenda
Giorno 2
Mattina Pomeriggio
● Sharding: quando e perchè fare sharding ● Tipi di dato
● Componenti: shard, router (mongos), config servers (metadati) ● Chiavi e indici
● Shard keys: concetti e scelta della sharding key ● Operazioni CRUD da shell
● Tipi di shard keys: hashed e ranged ● Aggregation framework
● Shard tagging ● Ricerche testuali
● Use cases di un’architettura a shard: segmentazione dei dati ● Ricerche geospaziali
per posizione geografica, segmentazione per applicazione o
cliente, segmentazione basata sull’hardware
● Esempio pratico di creazione di un cluster a due shard
DevOps Dev
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Agenda
Giorno 3
Mattina Pomeriggio
● Explain plan: esempio pratico di ottimizzazione ● ODM: Spring Data MongoDB e Morphia
di una query, index fit, working set ● GridFS
● Data design ● Data import su MongoDB: Apache NiFi
● Document validation ● Cenni all’integrazione con Apache Solr
● Pattern di struttura: relazioni 1 - 1, relazioni 1 - n, ● Cloud Manager: backup e monitoring sul cloud
alberi ● Cenni su Ops Manager e MongoDB Compass
● Timeseries ● Cenni su MongoDB Atlas
● Driver Java (sincrono e asincrono) ● MongoDB Enterprise vs MongoDB Community
● Concetti base di utilizzo del driver Java
(connessione a ReplicaSet e Shard)
Dev
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Parte 1
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Ottimizzazione delle query
● create gli indici a supporto delle query. L’80% dei problemi di performance è dovuto alla
mancanza di indici.
Abilitate il profiler per “scovare” le query lente, usate l’explain per ottimizzarle
● limitate i risultati delle query (db.posts.find().sort( { timestamp : -1 } ).limit(10) ) per
evitare consumo di banda inutile
● usate la projection per farvi ritornare solo i campi necessari
● nelle operazioni di incremento usate l’operatore $inc invece di leggere il documento,
modificarlo lato server e riscriverlo completamente
● in alcuni casi potete dire a MongoDB di usare un altro indice ($hint) perchè più performante
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Explain plan
db.collection.explain().<method(...)> cursor.explain()
Usato per i metodi aggregate(), count(), Usato per i metodi che ritornano un
distinct(), find(), group(), remove(), update() cursore (ad es. find)
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Verbosity
queryPlanner: è il default se non si specifica niente. MongoDB esegue il query optimizer per scegliere il
piano d’esecuzione della query per l’operazione in corso di valutazione
executionStats: MongoDB esegue il query optimizer per scegliere il piano d’esecuzione, lo esegue e
ritorna le statistiche d’esecuzione del piano scelto
allPlansExecution: MongoDB esegue il query optimizer per scegliere il piano d’esecuzione, lo esegue e
ritorna le statistiche d’esecuzione del piano scelto. Oltre a queste statistiche ritorna altre statistiche
relative ai piani d’esecuzione candidati ricavate nella fase di selezione del piano d’esecuzione
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Analizzare le performance di una query
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Query senza indice
{
db.inventory.find( "queryPlanner" : {
{ quantity: { $gte: 100, $lte: 200 } "plannerVersion" : 1,
} ... Viene fatta una
).explain("executionStats")
"winningPlan" : { full scan
"stage" : "COLLSCAN",
...
}
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 3,
"executionTimeMillis" : 0, Vengono ritornati
"totalKeysExamined" : 0, 3 documenti
"totalDocsExamined" : 10,
"executionStages" : {
"stage" : "COLLSCAN",
...
},
...
Vengono esaminati
},
... 10 documenti
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Query con indice
{
"queryPlanner" : {
"plannerVersion" : 1,
db.inventory.createIndex( { quantity: 1 } ...
) "winningPlan" : { Viene fatta una
"stage" : "FETCH", scansione dell’indice
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"quantity" : 1
},
...
db.inventory.find( }
{ quantity: { $gte: 100, $lte: 200 } },
} "rejectedPlans" : [ ]
).explain("executionStats") },
"executionStats" : { Vengono ritornati
"executionSuccess" : true,
"nReturned" : 3, 3 documenti
"executionTimeMillis" : 0,
"totalKeysExamined" : 3,
"totalDocsExamined" : 3,
"executionStages" : {
...
}, Vengono esaminati
...
}, 3 documenti
...
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Parte 2
Data design
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Importanza dello schema design
Focus sull’ottimizzazione dello storage dei dati Focus sull’uso dei dati
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Elementi fondamentali di schema design
Flessibilità
● Scelte in fase di progettazione possono essere modificate
● Ogni record può avere una campi diversi
● I campi devono essere consistenti per l’applicativo
● Alcune strutture possono essere forzate dagli applicativi
● Facile evoluzione della struttura al cambio dei requisiti
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Elementi fondamentali di schema design
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Elementi fondamentali di schema design
Embedding di Documenti
● Un Field può contenere un documento
● Documenti innestati permettono di ottenere strutture complesse
● Maggiori performance grazie alla localizzazione dei dati
● Possono essere eseguite query ad ogni livello
● Possono essere indicizzati
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Esempio di schema design
Contacts Addresses
{ {
“_id”: 2, “_id”: 1,
“name”: “Steven Jobs”, “street”: “10260 Bandley Dr”,
“title”: “VP, New Product “city”: “Cupertino”,
Development”, “state”: “CA”,
“company”: “Apple Computer”, “zip_code”: ”95014”,
“phone”: “408-996-1010”, “country”: “USA”
“address_id”: 1 }
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Esempio di schema design
Contacts
{
“_id”: 2,
“name”: “Steven Jobs”,
“title”: “VP, New Product Development”,
“company”: “Apple Computer”,
“address”: {
“street”: “10260 Bandley Dr”,
“city”: “Cupertino”,
“state”: “CA”,
“zip_code”: ”95014”,
“country”: “USA”
},
“phone”: “408-996-1010”
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Relazionale VS Documenti
Contact
1. Name
Contact Address 2. Company
3. Title
1. Name 1. Street 4. Address
2. Company 2. City a. Street
3. Title 3. State b. City
4. Phone 4. Zip_code c. State
d. Zip_code
5. Phone
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Esempio di flessibilità
{
{ “name”: “Larry Page”,
“name”: “Steven Jobs”, “url”: “http://google.com/”,
“title”: “VP, New Product Development”, “title”: “CEO”,
“company”: “Apple Computer”, “company”: “Google!”,
“address”: { “email”: “larry@google.com”,
“street”: “10260 Bandley Dr”, “address”: {
“city”: “Cupertino”, “street”: “555 Bryant, #106”,
“state”: “CA”, “city”: “Palo Alto”,
“zip_code”: ”95014” “state”: “CA”,
}, “zip_code”: “94301”
“phone”: “408-996-1010” },
} “phone”: “650-618-1499”,
“fax”: “650-330-0100”
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Traduzione di relazioni
Groups Addresses
Twitter
1. Name 1. Type
1. Name
2. Location 1 N N 2. Street
3. City
3. Web
4. State
4. Bio
N 5. Zip_code
1 1
Contact
Thumbnails 1 1
1. Name
1 Phones
1. mime_type 2. Company N
2. Data 1 3. Title 1 1. Type
2. Number
Portraits 1 N e-mail
1. mime_type 1. Type
2. Data 2. Address
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Relazione 1:1
1 1
Contact Twitter Contact
Twitter_id
1. Name
2. Company
3. Title
4. Twitter
twitter
1 1
Contact Twitter
Contact_id
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Relazione 1:N
1 1
Contact Phones Contact
Phones_id: [ ]
1. Name
2. Company
3. Title
4. Phones
phones
1 1
Contact Phones
Contact_id
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Relazione N:N - 1 di 3
Join table
Contact
groups_contacts
Groups
1. Name
1. group_id 2. Company
1. Name
2. contact_id 3. Title
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Relazione N:N - 2 di 3
Join table
Contact
groups_contacts
Groups
1. Name
1. group_id 2. Company
1. Name
2. contact_id 3. Title
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Relazione N:N - 3 di 3
N N
Group Contact Group Contact
contact_id: [ ]
1. Contacts 1. Groups
contact group
N N
Group Contact
group_id: [ ]
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Risultato della conversione: schema
N
Groups N Contact Phones
1. Name N
Phones
2. Location
1 3. Web 1. Type
4. Bio 2. Number
Portraits
1
1. mime_type 1 N
2. Data Thumbnails Email
1. mime_type 1. Type
2. Data 2. Address
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Risultato della conversione: json
{
“name” : “Gary J. Murakami, Ph.D.”,
“company” : “MongoDB, Inc.”,
“title” : “Lead Engineer”,
“twitter” : {
“name” : “Gary Murakami”, “location” : “New Providence, NJ”,
“web” : “http://www.nobell.org”
},
“portrait_id” : 1,
“addresses” : [
{ “type” : “work”, “street” : ”229 W 43rd St.”, “city” : “New York”, “zip_code” : “10036” }
],
“phones” : [
{ “type” : “work”, “number” : “1-866-237-8815 x8015” }
],
“emails” : [
{ “type” : “work”, “address” : “gary.murakami@mongodb.com” },
{ “type” : “home”, “address” : “gjm@nobell.org” }
]
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Consigli
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Document Validation
● Permette di validare i documenti in fase di inserimento o modifica
● Le regole di validazione vanno specificate a livello di collection
● La validazione può essere abilitata anche ad una collection esistente (comando collMod). In tal
caso i documenti presenti non saranno sottoposti a validazione fino alla prima operazione di
modifica
● Ci sono tre livelli di validazione: off (disabilitata), strict (viene applicata la validazione a tutte le
insert e a tutte le update), moderate (applica la validazione a tutte le insert e alle sole update
valide, non si applica alle update sui documenti esistenti e non validi)
● Ci sono due possibili azione da applicare per i documenti non validi: error (in questo caso i
documenti non validi non vengono scritti e viene lanciata un’eccezione), warn (in questo caso i
documenti vengono comunque scritti ma viene loggata il fatto che non abbiano superato la
validazione)
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Timeseries
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Schema design nelle timeseries
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Singolo documento per evento
{
server: “server1”,
load: 92,
ts: ISODate("2013-10-16T22:07:38.000-0500")
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Singolo documento per minuto (media)
{
server: “server1”,
load_num: 92,
load_sum: 4500,
ts: ISODate("2013-10-16T22:07:00.000-0500")
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Singolo documento per minuto (secondo)
{
server: “server1”,
load: { 0: 15, 1: 20, …, 58: 45, 59: 40 }
ts: ISODate("2013-10-16T22:07:00.000-0500")
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Singolo documento per ora (salvo ogni secondo) - 1 di 2
{
server: “server1”,
load: { 0: 15, 1: 20, …, 3598: 45, 3599: 40 }
ts: ISODate("2013-10-16T22:00:00.000-0500")
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Singolo documento per ora (salvo ogni secondo) - 2 di 2
{
server: “server1”,
load: {
0: {0: 15, …, 59: 45},
….
59: {0: 25, …, 59: 75}
ts: ISODate("2013-10-16T22:00:00.000-0500")
}
● Salvataggio dei dati ogni secondo con sottodocumenti per ogni minuto
● Il carico per il DB è rappresentato dalle update
● Pre-allocare la struttura per evitare spostamenti del documento su disco
● L’aggiornamento dell’ultimo secondo richiede di esaminare prima 59 + 59
campi
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Timeseries: analisi delle scritture
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Timeseries: analisi delle letture
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
GridFS
E’ un insieme di specifiche per salvare files su MongoDB la cui dimensione
eccede i 16MB
● Si possono salvare SOLO files, ovvero stream di byte
Come funziona?
MongoDB divide il file in chunk e salva i chunks come documenti separati. Al momento del
salvataggio del file, vengono popolate due collections, la collection fs.chunks e la collection fs.files
{
{ "_id" : <ObjectId>,
"length" : <num>,
"_id" : <ObjectId>, "chunkSize" : <num>,
"files_id" : <ObjectId>, "uploadDate" : <timestamp>,
fs.chunks fs.files "md5" : <hash>,
"n" : <num>,
"filename" : <string>,
"data" : <binary> "contentType" : <string>,
} "aliases" : <string array>,
"metadata" : <dataObject>,
}
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Come usare GridFS
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Quando usare GridFS
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Parte 3
Driver java
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Versioni
Sync Async*
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.mongodb</groupId> <groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId> <artifactId>mongodb-driver-async</artifactId>
<version>3.5.0</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Connessione a MongoDB
Si usa la classe MongoClient() la cui istanza rappresenta un pool di connessioni verso il database
Tipicamente si usa un’unica istanza della classe per ogni JVM, non fate
new MongoClient() ad ogni query!
Esempi:
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
Database, collection e documenti
Accesso ad un database
Creazione di un documento
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
CRUD
Inserimento
● collection.insertOne(doc);
● collection.insertMany(documents); documents = new ArrayList<Document>();
Modifica
● collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 110)));
● collection.updateMany(lt("i", 100), inc("i", 100));
Cancellazione
● collection.deleteOne(eq(" i", 110));
● collection.deleteMany(gte(" i", 100));
Ricerca
● Document myDoc = collection.find().first();
● MongoCursor<Document> cursor = collection.find().iterator()
● Document myDoc = collection.find(Filters.eq(" i", 71)).first();
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter
GRAZIE!
www.zero12.it Nome
Nome Cognome
Roberto
ciao
Cognome
Contiero
www.zero12.it @account Twitter
@account
@contieroroberto
Twitter