Visualizzazione post con etichetta mongodb. Mostra tutti i post
Visualizzazione post con etichetta mongodb. Mostra tutti i post

martedì 25 luglio 2017

MongoDB, C and Bulk Operation


E' molto tempo che voglio provare ad eseguire delle operazione su MongoDB utilizzando il Linguaggio C. Sono tantissimi anni che non uso più il C (circa 18.. dai tempi dei CGI sulla WebSphere Commerce Suite di IBM).

Per prima cosa vediamo come installare sotto Debian/Ubuntu il driver con i relativi sorgenti.

apt-get install libmongoc-1.0-0

A questo punto inizio ad analizzare il funzionamento del driver, la documentazione è molto valida.

Il problema che voglio risolvere è un calcolo su un numero elevato di record. Per testing utilizzo il db del Meteo. Il calcolo prevede di prendere i dati presenti nell'archivio delle piogge (Field RC) che sono in realtà un numero incrementale azzerato ad ogni riavvio della console del meteo. Quindi oggi il contatore è 200, domani 200, dopodomani 201, quindi andando per differenza oggi è caduto 1 mm di pioggia.

La struttura dell'object su cui vengono eseguite le query di mongo è la seguente:


 I record sono circa 1 M.



per la compilazione del pacchetto basta eseguire il comando:


sudo gcc -o raindata raindata.c utils.c $(pkg-config --cflags --libs libmongoc-1.0)

 La cosa molto interessante è la funzionalità di Bulk insert molto simile alle transazione dei classici db relazioni. Ovvero si caricano tutti i dati in una struttura e poi si esegue una flush e tutti i dati vengo inseriti in modo molto veloce.

Non mi soffermo tanto sul calcolo del dato puro ma sulle performance di inserimento. 
La prima esecuzione è con insert ripetitive, la seconda con la funzionalità di bulk. 

Si passa da 8 minuti a 12 secondi!!



come sempre trovate tutto il sorgente sul github https://github.com/marcoberri/mbmeteomongoc

mercoledì 10 febbraio 2016

MongoDB - Backup di grandi db

Nasce, molte volte, il problema di eseguire un backup su una grande mole di dati.

Uno dei modi possibili (vedi doc) è prendere i file dei db di mongo e semplicemente copiarli.

Il nostro problema nasce che non tutti i db devono essere backuppati per essere ribaltati, e il nome dei file di archivio di mongo non sono parlanti.

Una soluzione e configurare ogni db in una singola cartella con i parametri di configurazione

storage.directoryPerDB

un'altro parametro ottimo è:

storage.wiredTiger.engineConfig.directoryForIndexes

i db vengono archiviati in cartelle separate e divisi in due cartelle collections e index così eventualmente in fase di copia dei dati è possibile escludere le folder degli indici risparmiando spazio e tempo.


Questa configurazione necessita di un mongodump e un mongorestore. In caso di ReplicaSet basta fermare il primario, svuotare le cartelle, cambiare le conf e attendere che si replichi con il secondario che è diventato primario. Al termine il primario diventa nuovamente secondario e viceversa.

MongoDB version 3.0.7

martedì 9 febbraio 2016

MongoDB - Script to Delete all collection with exclusion

Semplice script per eliminare tutte le collection di un db ad esclusione di una lista di collection.


giovedì 4 febbraio 2016

MongoDB - Script per eseguire una purge di dati dalle varie collection di log

Capita alle volte di voler svuotare delle collection che contengo informazioni di log.

Questo script partendo dal nome del server ricerca tutti i db che iniziano con un certo nome, cicla tutte le collection (ad esclusione di quelle specificate), esegue una query per conteggiare i record che devono essere eliminati e poi elimina in base al numero di giorni che vogliamo mantenere sui log a partire da oggi.

Il campo di controllo di data è chiamato ts.



martedì 2 febbraio 2016

MongoDB - Migrazione da ReplicaSet a Singolo Nodo

Alle volte capita di dover demolire una replica e riportare i dati su un singolo nodo del MongoDB.

ecco la procedura testata su MongoDB 3.0.8



martedì 26 gennaio 2016

MongoDB Script per current operations

Script molto utile per analizzare le operazioni in esecuzione sul Mongo Server.

Ottimo per prevedere la creazione di eventuali indici senza utilizzare il profile standard.



risultato:

on:<dbname>.<collectionname>
time:12968
query: {"_id":{"str":"54b64c9ee4b009e7c6df0f40"}}

on:<dbname>.<collectionname>
time:18489
query: {"_id":{"str":"54b64c9ee4b009e7c6df0f40"}}

on:<dbname>.<collectionname>
time:131
query: {"field1":"515c785c9ccb3d8e563baf32","field2":"AAA","field1":"BBB"}

lunedì 14 dicembre 2015

MongoDB Tools 3.0.7 - mongorestore bug


Mongorestore bug:

mongorestore --drop --host <HOST> -v /dump/DB_FOLDER

Command result:

Failed: restore error: komparu_product_dev.product: error restoring from dump/<dbame>/>collection-name>.bson: insertion error: EOF


FIX:

mongorestore --drop batchSize=1 --host <HOST> -v /dump/DB_FOLDER


lunedì 19 ottobre 2015

MongoDB v.3 Memory Problem

Utilizzando un piccolo server (magari con più processi di mongod ) è possibile che per mancanza di risorse il processo venga killato dal SO.

Nel var/log/messages si trova questa cosa devastante...

Oct 15 02:00:33 <servername> kernel: [723954.577468] Out of memory: Kill process 18100 (mongod) score 368 or sacrifice child

la soluzione è semplicemente dosare correttamente la cache del wiredTiger nel file di configurazione


nel mio caso con un server (debian 8.1 con 16Gb di Ram) con 3 mongod in esecuzione in replica secondaria il parametro è settato a 3Gb per ogni mongod.

dopo una taratura i mongod non crollano più.



 





venerdì 18 settembre 2015

MongoDB - Script di MapReduce con uso di scope su map dinamico

Dovendo realizzare una MapReduce per il calcolo dei valori massimi e minimi in un determinato periodo (meteorologico) mi sono scontrato col il problema di passare ad una funzione di Map dei parametri dinamici provenienti da un ciclo.

Per risolvere questo problema bisogna utilizzare un parametro di scope quando si lancia l'esecuzione della MapReduce:


es:

var KEYS = {FIELD : 'test',PERIOD : 'Day'};

dbOne.rawdata.mapReduce(map,reduceMax,{out:{inline:1}, scope : {KEYS:KEYS}}).results;

e nella map posso usarlo:

var map = function(){


if(KEYS.PERIOD == 'Day')
...
emit(somefunction, this[KEYS.FIELD]);
...

};

esempio completo:



giovedì 25 giugno 2015

Integrazione app Meteo con La Crosse Technology WS1640

Dopo un buon periodo di inattività delle rilevazioni meteo causate dal malfunzionamento della vecchia stazione meteo, Cinzia mi regala un sistema completo nuovo sotto il 150 Euro una  La Crosse Technology WS1640

Dopo aver installato la stazione sul balcone arriva la parte più interessante ovvero creare una app web e collegarci in tempo reale i risultati della stazione.

L'uscita usb della stazione è connesso ad un raspberry in wifi e alimentato da rete.

La stazione utilizza il cavo usb del raspberry per alimentarsi

Per prelevare i dati dalla stazione attraverso una piccola app in java sul Raspberry PI utilizzo questa libreria comoda e senza tanti fronzoli. La app in java preleva i dati e li invia ad una web-app sul server in formato json ogni tot minuti, oltre che alla sera scaricare tutto l'archivio sul dispositivo e rispedirlo al server in modo da prevedere eventuali buchi di rete durante la giornata.

La app è sul github.

Per la parte server il sitarello è realizzato con NodeJs compreso il servizio in ascolto del posto da parte del Raspberry PI qui il sorgente.

Seconda applicazione presente sul server è un piccolo batch per la generazione dei grafici con jfreechart. Visto che i dati sono molto non è possibile renderizzare tutto in tempo reale in javascript.

Naturalmente i dati sono tutti archiviati su MongoDB.

Questo è il sorgente del batch per i grafici.








giovedì 12 marzo 2015

Migrazione a MongoDB 3


Finalmente è arrivato MongoDB 3.0 !!!

Eseguo subito qualche test di migrazione!!!

Per migrare alla versione 3 bisogna almeno prima passare le eventuali versioni 2.4 alla 2.6. 

La migrazione è leggermente complessa, si tratta di cambiare l'engine di elaborazione su fs con http://www.wiredtiger.com/ azienda comprata da mongo per gestire in modo velocemente le transazioni e ottimizzare le risorse su disco. 


- test di migrazione su db non in replica/cluster. 

- Prendo un succoso dump da 21GB. Ripristinato su un mongo 2.6.6 (circa 2 ore di restore)

situazione di partenza:

DB1 0.5GB
DB2 27.4GB
DB3 0.03GB
DB4 2.49GB
local 0.03B

cartella di storage 40GB

- Cambio l'engine al mongo 3.0 e forzo il motore a quello standard:

/bin/mongod --dbpath /mongo/mongodatastandalone/ --logpath "standalone_3.0.log" --storageEngine mmapv1

la partenza è lenta esegue dei recovery del journal (40 secondi)

- Eseguo un dump dei dati (35 minuti circa) :

/mongodump --out /backup_mongo_3/

rimango basito... il mongodump adesso lavora con processi paralleli!!!
il dump generato è circa 21GB

- Start del mongo che punta ad una cartella di dati diversa da quella precedente specificando il motore di engine nuovo.

/bin/mongod --dbpath /mongo/mongodatastandalone_3/ --logpath "standalone_3.0.log" --storageEngine wiredTiger


- Eseguo la restore dei dati sul tiger (2 ore e 10 minuti circa):

mongorestore /backup_mongo_3/

siamo passati da uno storage su disco di 40GB ad uno di 17GB


il prossimo passo sarà di testare la migrazione delle repliche.
Per evitar di farmi una migrazione per ogni server replica si potrebbe eseguire tutto su un nodo singolo sganciando prima le repliche e poi attivare le repliche su nodi di mongo 3 pulito in modo da far replicare i dati in modo automatico dal mongo.


problema per le app:
il java driver attualmente è alla beta 3 - https://github.com/mongodb/mongo-java-driver/releases

mercoledì 4 febbraio 2015

MongoDB - Script di compact per tutto il server

Questo script esegue la compact su tutte le collection per tutti i db di tutto il server.

mongo --host <servername> compact.js

utile quando si prova a risparmia  spazio su disco anche se non è sempre detto che funzioni...








giovedì 4 dicembre 2014

MongoDB - Script per rigenerare _id

Alle volte capita che per sbaglio vengano inseriti dei valori non generati da mongo per _id.

es:

{"_id":1, "a":1},
{"_id":2, "a":3}.. etc..etc



Mongo non prevede l'unset del _id
uno script del genere

 db.events.update({},{$set : {_id:new ObjectId()}},{multi:true});

ritorna questo errore:

After applying the update to the document {_id: 4 , ...}, the (immutable) field '_id' was found to have been altered to _id: ObjectId('54801ec49103c90347485eaf')


il modo migliore è quello di prendere tutti i valori ribaltarli su una collection di appoggio (eliminando il vecchio _id) e rinominare la collection in quella sorgente.

giovedì 13 novembre 2014

MongoDB - Script per profile su tutto il server

Abilita il profile per tutti i db del mongo server esclusi local e admin.


per interrogare tutti i profile con l'elenco delle ultime 5 query che superano i 5 millis

lunedì 21 luglio 2014

MongoDB - Script to check Collections Size

Script di utils per recuperare la collection size di ogni db del vostro mongo.

da lanciare con: mongo mongo check_collection_size.js

permette di ottenere la size delle collection di tutti i db in modo da poterla monitorare con qualche app tipo jmeter o nagios.

il risultato:


[ {
"name" : "meteoArpa",
"collections" : [
{
"name" : "data",
"storageSize" : "680.00 KB",
"size" : "510.89 KB",
"count" : 519
},
{
"name" : "pluvio",
"storageSize" : "21.46 MB",
"size" : "19.97 MB",
"count" : 20779
},
{
"name" : "system.indexes",
"storageSize" : "8.00 KB",
"size" : "336 B",
"count" : 3
},
{
"name" : "temperature",
"storageSize" : "21.46 MB",
"size" : "20.00 MB",
"count" : 20807
}
]
},
{
"name" : "pcat",
"collections" : [
{
"name" : "products",
"storageSize" : "8.00 KB",
"size" : "3.58 KB",
"count" : 11
},
{
"name" : "system.indexes",
"storageSize" : "8.00 KB",
"size" : "112 B",
"count" : 1
}
]
},
{
"name" : "admin",
"collections" : [ ]
}
]





giovedì 24 aprile 2014

MongoDB - esempi di scripting

In questo file potete trovare vari esempi di scripting per mongo divisi in classi/metodi js

L'uso è semplice

mongo --host localhost
> load("global.js")

a questo punto avete caricato gli script e potete usarli es: meteolog.extract();

Gli script sono molto utili per seguire fix o altri tipi di operazioni massive lato db. molto più veloce che realizzarle sulle app client.

Un classico esempio è quello di estrarre i dati dopo averli elaborati in tempo reale csv o simili.

meteolog = {};

var dbMeteo = db.getSisterDB("Meteo");

meteolog.extract = function(){
        var coll = dbMeteo.Meteolog;

var count = coll.count();
print("Tot record :" + count);

var cursor = coll.find();

var line = "";
cursor.forEach(function(logData) {
 line += logData.n + ", " + logData.time;
 print(line);
});
}



domenica 1 dicembre 2013

Raspberry Pi - Dagu 5 - Primi Passi

UPDATE: la gestione hardware è stata demandata ad Arduino.Il Raspberry comanderà arduino. Nel prossimo post altri dettagli.

Proseguono gli esperimenti con il Raspberry PI, preso da una frenesia di acquisti notturni ho comprato questo spettacolare rover con la scheda di controllo per i motori.




Hardware


Per il Raspberry Utilizzo la distribuzione standard presente sul sito, ho tolto X ed aggiunto la java-openjdk per utilizzare appunto java più alcune utility (joe, htop, etc), tutto comodamente utilizzando apt-get install.

La comunicazione avviene tramite wifi applicando una chiavetta al raspberry in modo da mantenerlo autonomo da cavo di rete.

Prima problema.. mi sono accorto che l'uscita digitale GPIO del Rapsberry è a 3.3V invece la scheda di controllo dei motori del  dagu funziona su un segnale a 5 volt like Arduino. Quindi devo cercare un convertitore di segnale.. eccolo!!! Tindie converter gpio da 3 a 5v


Primi test.

Dopo vari esperimenti e ricerche trovo questa schedina che converte tutti i segnali del gpio a 5v. Proprio quello che serve per il controller del rover.

I primi esperimenti veloci dell'hardware sono con Nodejs e una piccola lib node-gpio semplice e veloce.


Materiale

Cavetti
Raspberry pi





ecco il tutto montato e pronto:







Primi esperimenti con python e nodejs... subito salta fuori il problema della programmazione parallela del gpio non molto semplice da risolvere. Se non risolvo la cosa sarà facile che passerò ad Arduino.... ufff....




lunedì 14 ottobre 2013

MongoDB + Java + Query + java.util.Date() Range

eseguendo questo codice:

final DBObject query = new BasicDBObject("field_1", new BasicDBObject("$exists", false))
.append("field_2", new BasicDBObject("$exists", true))
.append("field_3", new BasicDBObject("$exists", true))
.append("time", new BasicDBObject("$gte", new Date()));


System.out.println("----> query " + query.toString());

vi restituirà:

{ "field_1" : { "$exists" : false} , "field_2" : { "$exists" : true} , "field_3" : { "$exists" : true} , "time" : { "$gte" : { "$date" : "2013-10-09T15:53:18.649Z"}}}

e invece la query viene eseguita correttamente, se voi prende questa query e la lanciate dalla shell di mongo non funziona.... ma in realtà eseguita dai driver di mongo funziona!!!!

Quindi la query visualizzata vi sta mentendo!!!!

scusate sono impazzito 2 ore per capirlo....














martedì 24 settembre 2013

MongoDB + Morphia + Model to Map/Reduce Result with complex id

Alle volte capita di avere una collection risultante da una Map Reduce con un field id complesso.
Dopo varie ricerche ed esperimenti la soluzioni si trova agganciando come id una classe in embed:

la collection risultante della mapReduce:

{
"_id" : {
"time" : "2011-03",
"url" : "www.test.it",
"fast" : "c80"
},
"value" : 12
}



la classe di modello di result:

@Entity(value = "Stats.CountSingleUrl", noClassnameStored = true)
public class MRResult {

    @Id
    @Embedded
    @Indexed(value = IndexDirection.ASC, unique = true, dropDups = true)
    private IdObject id;
    private String value;

   ///... GETTER e SETTER

    public static class IdObject {

        private String time;
        private String url;
        private String fast;

     ///... GETTER e SETTER
    }
}

venerdì 12 luglio 2013

Certificazioni MongoDB 10gen

Sono disponibili i corsi gratuiti della 10gen con relativa certificazione di MongoDB.