lunedì 2 aprile 2012

MongoDB - Profile and Java


Monitorare le eventuali operazioni sul db che possono creare ritardi è fondamentale per il buon funzionamento di una app.

Per abilitare il Profile è necessario eseguire queste funzionalità dalla console. (mongo)

use <dbname>
db.setProfilingLevel(2); 

ottimo e utile, tutte le query vengono memorizzate nella collection <dbname>.system.profile.

Allargo la colletion di tipo capped per avere più info memorizzate.

//fermo il profile
db.setProfilingLevel(0); 

//drop della collection con il profile
db.system.profile.drop(); 

//creo la nuova collection per uso del profile
db.createCollection("system.profile", {capped:true, size:8000000});

db.system.profile.stats();

db.setProfilingLevel(2); 


A questo punto scrivo questa breve query che:
- ricerca tutte le operazioni superiori a 5 millisecondi
- esclude le query eseguite sul profile (questa!!)
- estraggo solo le operazioni di query (insert/update/delete/ etc.)


db.system.profile.find( { op:"query", millis : { $gt : 5 },ns : { $ne : (db + '.system.profile') } },{ ts:1,millis:1, nscanned:1, nreturned:1, ns:1, op:1, query:1} ).sort({ts:-1})



nel caso in cui "nscanned" sia molto maggiore del parametro "nreturned" allora verifico gli indici sugli object elaborati.

see http://www.mongodb.org/display/DOCS/Database+Profiler


e in java? come posso monitorare la cosa?




package mongodbcheckprofile;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import java.io.IOException;

/**
 * use ; 
 * db.setProfilingLevel(0);
 * db.system.profile.drop()
 * db.createCollection("system.profile", {capped:true, size:8000000})
 * db.system.profile.stats()
 * see http://www.mongodb.org/display/DOCS/Database+Profiler
 * Query utils:  
 * db.system.profile.find( { millis : { $gt : 1 },ns : { $ne : 'nome_db.system.profile' } },{ millis:4, nscanned:1, nreturned:1, ns:1, op:1, query:1} )
 * nel caso: che "nscanned" (molto maggiore) "nreturned"  allora verificare gli indici sugli object elaborati.
 *
 * @author marco
 */
public class MongoDBCheckProfile {

    static String host = "192.168.0.220";
    static int port = 27017;
    static String db_name = "nome_db";
    static String op = "query";
    static int maxtime = 4;
    static int sleep = 5000;

    public static void main(String[] args) throws IOException, InterruptedException {

        while (true) {
            System.out.println("start: " + System.currentTimeMillis());
            Mongo m = new Mongo(host, port);
            DB db = m.getDB(db_name);
            BasicDBObject query = new BasicDBObject();
            DBCollection coll = db.getCollection("system.profile");
    

            query.put("millis", new BasicDBObject("$gt", 4));
            query.put("ns", new BasicDBObject("$ne", db_name + ".system.profile"));
            query.put("op", op);
            DBCursor cur = coll.find(query);
            

            while (cur.hasNext()) {
                DBObject  db_obj = cur.next();
                System.out.println(db_obj.get("ts") + " - " + db_obj.get("ns") + " - " + db_obj.get("nscanned") + "/" + db_obj.get("nreturned") + " millis :" + db_obj.get("millis"));

            }

            Thread.sleep(sleep);

            m.close();

        }


    }
}