Il miracoloso NodeJS

piattaforma Open Source event-driven

NodeJS – una piattaforma Open Source event-driven

Ok, ammetto che fino a non molto tempo fa mi ero quasi scordato di Javascript, nonostante fosse stato uno dei primi linguaggi da me studiati, nel lontano 1997, quando mi approcciai al mondo del web; negli anni successivi pero’, non essendo io uno sviluppatore, le tecnologie di gestione e deploy dei server web che dovevo gestire si erano spostate verso un grande quantitativo di linguaggi, in particolare per la parte back-end , passando cosi dal php, perl, python, java, ruby, lua etc……

Come stavo dicendo, per me javascript era rimasto in sordina come un linguaggio di scripting che intercorreva tra l’hmtl ed il css, nella composizione piu’ o meno dinamica di una pagina web ,prima che i pesi massimi sopra citati entrassero in campo per svolgere il duro lavoro.

Poi, un giorno, a ciel sereno……BOOOOOOOMMMM ! scopro l’esistenza di NodeJS, ed iniziai a chiedermi a cosa si dovesse tutto l’interesse di cui stavo leggendo; scopro quindi che NodeJS e’ una piattaforma Open Source event-driven per l’esecuzione di codice JavaScript Server-side, costruita sul motore V8 di Google Chrome. Mmmmhhhh, ok bene, ma quindi? cosa fa?

Ebbene questa piccola rivoluzione creata da Google consente agli sviluppatori di realizzare web application con JavaScript non più solo lato client, ma anche sfruttandolo come linguaggio di programmazione lato server.

E gli sviluppi sono davvero moltissimi, cosi tanti che mettere un’elenco sarebbe noioso e stancante ma, tanto per farne uno molto odierno, con NodeJS possiamo, ad esempio, realizzare dei ChatBot.

Ma qual’e’ dunque il funzionamento che lo rende cosi appetitoso? Innanzitutto partiamo dal dire che Node funziona con una logica a eventi: quando un evento viene generato, allora viene eseguita un’azione. Grazie a questa tecnica non bisogna attendere che le istruzioni precedenti siano terminate, rendendo cosi il tutto molto veloce.

Nella pratica, non c’e’ bisogno di sapere come funziona il V8 per poter utilizzare NodeJS, basti sapere che e’ l’interprete javascript piu’ veloce al mondo, poiche’ e’ stato altamente ottimizzato utilizzando un tipo di programmazione JIT (Just In Time), che trasforma rapidamente il codice javascript in linguaggio macchina.

Ma la cosa che, almeno a parere personale, mi ha maggiormente colpito, e’ stato quello che possiamo chiamare come “Modello non bloccante” , questo si basa sul concetto degli eventi, ma per meglio chiarire dovremmo spiegare un minimo la differenza tra modello bloccante e NON bloccante.

Immaginiamo di dover creare un programma che ci permetta di scaricare un file da internet e che alla fine dell’esecuzione del download ci mostri un messaggio.

Bene, con il modello classico (bloccante) basato sulla programmazione sincrona potremmo schematizzare il processo nel seguente modo:

  • Scarica il file
  • Mostra il messaggio
  • Fai qualcos’altro

Ci aspetteremmo quindi che le azione vengano eseguite in ordine, leggendo le operazioni da eseguire dall’alto verso il basso.

Nel sistema asincrono di NodeJS invece le operazioni verranno svolte nel seguente modo:

  • Scarica file
  • Fai qualcos’altro
  • Mostra il messaggio

Perche’ questa diversita’ nell’esecuzione rende il tutto piu’ veloce e performante? Beh perche’ mentre il sistema effettua il download del file, il programma non rimane in attesa che il processo venga portato a termine ma anzi nell’attesa il programma esegue altre operazioni.

Il codice in oggetto avra’un aspetto tipo questo:

request(‘http://www.site.com/file.zip’, function (error, response, body) {
console.log(“Download completato!”);
});

console.log(“Mentre aspetto eseguo il resto del codice…”);

Quello appena descritto qui sopra e’ un’esempio di procedura di callback 

Ok ma se non fosse ancora del tutto chiaro, proviamo ancora a spiegare perche’ le callback sono cosi importanti, procediamo con l’esempio di prima ed aggiungiamo una difficolta’; adesso i file da scaricare sono diventati due, dunque nel sistema sincrono il programma procederebbe nel seguente modo:

  • Scarico primo file
  • Attendo che finisca
  • Scarico secondo file
  • Attendo che finisca
  • Mando messaggio

La grande differenza in questo esempio sarebbe che con NodeJS verrebbero lanciati entrambi i download, nello stesso momento, permettendo gia cosi un piu’ veloce download e, nel frattempo il programma e’ in grado di svolgere eventuali altri compiti. Ma questo come dicevo e’ soltanto un esempio, invece di un download multiplo, potrebbero essere delle query ad un DB, o la richiesta di dati a servizi esterni tramite API (Facebook, Twitter).

Pensiamo quindi ad un sistema come Facebook, che riceve X richieste di Like ogni tot secondi e vengono cosi aperti N operatori che devono attendere il loro turno per fare la modifica (del like) consumando comunque energie anche mentre sono fermi in attesa; invece NodeJS nella stessa situazione di richiesta di “reaction” sul sisto di FB (like o altro) si comporterebbe nel seguente modo:

metterebbe tutte le richieste in ordine di arrivo, prenderebbe la prima e, vedendo che si tratta di una sfilza di input le inserirebbe all’interno del sistema e, una volta capito che si tratta di stesse azioni (ad esempio che aggiungono un Like) che devono contattare un DB, NodeJS contatta il DB e invece di attendere per effettuare ogni singola modifica, aggancia alla richiesta una callback, per ogni richiesta di modifica, tutti uno dietro l’altro. Quando il DB finisce la prima modifica scatta la callback e NodeJS restituisce all’utente l’avvenuta modifica della pagina e cosi via, gestendo quindi con un solo operatore le N richieste di modifica del Like invece di crearne uno per ogni richiesta e parcheggiandoli tutti in attesa della loro singola modifica. Quindi con un server (magari anche un container con Docker) e con poche risorse possiamo gestire un’enorme quantita’ di richieste al secondo.

Inoltre NodeJS usa come sistema di pacchetti e librerie l’NPM, ma di questo fantastico sistema di librerie parleremo in un’altro articolo.

Nel prossimo articolo su NodeJS parleremo anche di 5 nuovi framework ottimi per chi si occupa di sviluppare.

#NodeJS

 

Programmare pensando da Sistemista

 

linux-python-logoUna domanda che mi faccio da quando lavoro come sistemista e’ : “quale linguaggio di programmazione dovrei imparare ??“; e’ una domanda facile da formulare, che dovrebbe presupporre un’altrettanto facile risposta, ma ahimè non é così semplice, perlomeno non nel mio caso. Certo, i linguaggi di programmazione non mancano ed in giro ci sono dozzine di fonti di ottima qualità, ma penso comunque che per poter fornire un consiglio si dovrebbe sempre poter conoscere bene chi pone la domanda, ossia:

 

  • il suo background è scientifico o umanistico?
  • conosci bene l’inglese? (poiche’ la maggior parte delle fonti che consiglierei sono in inglese)
  • qual’è la tua età? ecc…!

…..insomma sono tanti i fattori da considerare e tutti hanno il loro peso da non sottovalutare.
In tempi non troppo lontani programmare significava conoscere il funzionamento dei computer a basso livello, comprendere a fondo la loro teoria e la loro struttura. Ma oggi è molto diverso. La gran parte dei programmatori (web 3.0) sono orientati alle applicazioni web/cloud ed i vecchi linguaggi macchina, tipo Assembly, li ha solo sentiti nominare a scuola. Questo anche perche’ i linguaggi ad alto livello (Java, Python…) ci permettono di concentrarci sulla soluzione dei problemi (gli algoritmi) delegando al compilatore la creazione delle istruzioni di basso livello.

Certo questa e’ una buona notizia ma, partendo da me stesso, se non fai il programmatore ed un linguaggio di programmazione ti serve per crearti scripts di ottimizzazione dei sistemi , non e’ pensabile dover conoscere 5/6 linguaggi diversi ecco perche’ in campo sistemistico resistono gli ottimi script Bash oppure l’ardimentoso Perl.

Se mi avete seguito e siete almeno parzialmente d’accordo con l’analisi fatta vi ricompenso con lo stesso consiglio che mi sono dato qualche settimana fa: Python.

Non mi voglio dilungare nella presentazione di questo linguaggio di cui credo abbiate per lo meno sentito nominare, le cui caratteristiche principali di funzionalita’, operabilita’, performance ecc… lo rendono tra i migliori da imparare anche per usi che esulano dalla programmazione allo stato puro; per altri dettagli od info potete leggere l’articolo dal seguente URL “caratteristiche del linguaggio Python“.

Quello che voglio segnalare e’ che molto spesso nella grande, a volte troppa, quantita’ di materiale recuperabile, spesso non si trova qualcosa adatto davvero alle nostre esigenze e che renda l’avvicinamento e la comprensione di un nuovo linguaggio facile, senza annoiare.

Pensare da Informatico e’ un libro che svolge bene il suo compito avvicinando i nuovi utenti a questo ottimo linguaggio in modo guidato e lineare proprio perche’ frutto delle esigenze di un’insegnante che voleva spiegare ai propri alunni un nuovo modo di programmare. Il libro originale e’ in inglese ma ne esiste un’ottima versione PDF tradotta in Italiano, questo e’ il link per il download PDF , mentre questo e’ il link per la versione WEB .

La versione originale “How to Think a Computer Scientist ” sottotitolo (Learning with Python) 3rd edizione e’ scritta da [Peter Wentworth, Jeffrey Elkner, Allen B. Downey, and Chris Meyers ] .

Buona lettura !

DB fate largo ai No-SQL

nosql_logoI Database NoSQL

NO-SQL è un movimento che negli ultimi anni si è molto affermato, producendo dei risultati soddisfacenti con la creazione di progetti e iniziative utilizzate anche su larga scala. Tale movimento vuole “rompere” la storica linea dei database relazionali e definire delle nuove linee guida per l’implementazione di database che non utilizzano il linguaggio di interrogazione SQL e non siano strettamente legati ad una definizione “rigida” dello schema dati.
La filosofia del NO-SQL si può riassumere nei seguenti punti, partendo dalla domanda “Perchè avere altri DBMS se esistono quelli relazionali?”:

  1. I database relazionali sono troppo costosi e spesso, quelli che svolgono bene il loro lavoro, sono solo commerciali. NO-SQL abbraccia totalmente la filosofia open-source;
  2. NO-SQL è semplice da usare e non occorre uno specialista di DBMS. Il paradigma di programmazione è, infatti, ad oggetti;
  3. I dati sono altamente portabili su sistemi differenti, da Macintosh a DOS;
  4. Non definisce uno schema “rigido” (schemaless) e non occorre prototipare i campi, per cui non esistono limiti o restrizioni ai dati memorizzati nei database NO-SQL;
  5. Velocità di esecuzione, di interrogazione di grosse quantità di dati e possibilità di distribuirli su più sistemi eterogenei (replicazione dei dati), con un meccanismo totalmente trasparente all’utilizzatore;
  6. I DBMS NO-SQL si focalizzano su una scalabilità orizzontale e non verticale come quelli relazionali.

A questo punto passiamo a fare una comparazione tra quelli che attualmente sono tra i piu’ utilizzati , quali :

Cassandra, MongoDB, CouchDB, Redis, Riak, HBase, Membase e Neo4j :

** (vedi anche precedente articolo Not Only Sql)
– CouchDB

Scritto in: Erlang
Punto principale: Consistenza DB consistency, facilità d’uso
Licenza: Apache
Protocolli: HTTP/REST
Replicazione bidirezionale continua o ad-hoc con individuazione dei conflitti, replicazione master-master
MVCC – le operazioni di scrittura non bloccano le letture
Sono disponibili le versioni precedenti dei documenti
Progettazione crash-only (reliable)
Necessità di compattazioni nel tempo
Viste: embedded map/reduce
Viste formattate: lists & shows
Possibilità di validazione server-side dei documenti
Possibile autenticazione
Aggiornamenti real-time attraverso _changes (!)
Gestione degli allegati e, CouchApps (standalone js apps)
libreria jQuery inclusa
Utilizzo ideale: Per accumulazione dei dati con cambi occasionali sui quali vengono eseguite query predefinite. Situazioni in cui la gestione delle versioni è importante.
Per esempio: CRM, sistemi CMS. Situazioni in cui la replicazione master-master è una caratteristica interessante (ad esempio multisito).

– Redis

Scritto in: C/C++
Punto principale: Velocità
Licenza: BSD
Protocolli: Telnet-like
Disk-backed in-memory database,
In questo momento non include il disk-swap (VM e Diskstore sono stati abbandonati)
Replicazione master-slave
Recupero di valori semplici o intere tables a partire da una chiave
suppporto ad operazioni complesse come ZREVRANGEBYSCORE.
INCR (incremento) e  simili (molto utili per gestire limitazioni di valore e statistiche)
permette l’uso di insiemi (sets) e operazioni su essi (unione/differenza/intersezione)
permette l’uso di liste (lists) e  operazioni su esse (queue; blocking pop)
permette l’uso di hashes (oggetti dotati di campi)
permette l’uso di insiemi ordinati (utili per classifiche, e ricerche su range di valori)
Redis implementa correttamente le transazioni (!)
I valori memorizzati possono avere una scadenza temporale (sistemi di cache)
Implementa facilmente il messaging Publisher/Subscriber (!)
Utilizzo ideale: Adatto a moli di dati (residenti in memoria) di dimensione nota che cambiano frequentemente .
Per esempio: Quotazioni azionistiche. Analisi. Gestione dati in Real-time. Comunicazioni in Real-time.

– MongoDB

Scritto in: C++
Punto principale: Mantiene alcune proprietà utili del modello SQL (Query, index) molto facili da usare.
Licenza: AGPL (Drivers: Apache)
Protocollo: Specifico, binario (BSON)
Replica Master/slave (munita di  failover quando si usano i  “replica sets”)
Lo Sharding è parte integrante del sistema
Le intterrogazioni a db (queries) sono espressioni javascript
Permette l’uso di funzion i javascript lato server
Update-in-place migliore rispetto a CouchDB
Usa “memory mapped files” per la persistenza dei dati
Favorisce la velocità rispetto alle funzionalità implementate
Journaling (opzione –journal) fortemente consigliato
Sui sistemi a 32bit risente di una  limitazione sulla quantità di dati a circa 2.5Gb
Un database vuoto occupa comunque 192Mb
GridFS per la memorizzazione di “big data + metadata” (effettivamente non è un  FS)
Indicizzazione geospaziale Geospatial indexing
Utilizzo ideale: se si necessita di query dinamiche. Se si preferisce lavorare con gli indici rispetto ad usare algoritmi map/reduce. Buono se si ha bisogno di velocità quando si lavora con grandi moli di dati.  Adatto a tutti gli scenari in cui si usa CouchDB e non si può scegliere quest’ultimo perchè i dati cambiano troppo riempiendo la memoria fisica.
Per esempio: tutte le situazioni in cui si vorrebbe usare MySQL o PostgreSQL senza avere colonne definite a priori.

– Riak

Scritto in: Erlang & C, some Javascript
Punto principale: Fault tolerance
Licenza: Apache
Protocollo: HTTP/REST o custom binary
Trade-offs modulabili per replica e distribuzione (N, R, W)
Hooks di pre- e post-commit in JavaScript o Erlang, per la validazione e la sicurezza.
Map/reduce in JavaScript o Erlang
Links & link walking per utilizzarlo come database a grafi
Indici secondari: ricerca nei metadati
Supporto per oggetti di grandi dimensioni (Luwak)
Edizioni sia “open source” che “enterprise”
Ricerca full-text, indexing e querying con il Riak Search server (beta)
Sta migrando lo storing di backend da “Bitcask” al “LevelDB” di Google
La multi-site replication replication senza alcun master e il monitoring SNMP necessitano di una licenza commerciale
Utilizzo ideale: se si vuole qualcosa di simile a Cassandra (Dynamo), ma non si ha nessuna intenzione di avere a che fare con la realtiva inerente complessità. Se si ha bisogno di un’ottima scalabilità, disponibilità e fault-tolerance per un solo sito ma si è disposti a pagare per la replica multi-sito.
Per esempio: Raccolta dei dati di point-of-sales. Sistemi di controllo aziendali. Situazioni in cui anche il downtime di alcuni secondi può essere rilevante. Potrebbe essere anche utilizzato come un web server estremamente aggiornabile.

– Membase

Scritto in: Erlang & C
Punto principale: Compatibile con memcache ma con persistenza e clustering
Licenza: Apache 2.0
Protocollo: memcached con estensioni
Accesso molto veloce ai dati mediante chiave (200k+/sec)
Persistenza su disco
Tutti i nodi sono identici (replicazione master-master)
Fornisce un sistema a buckets simile a memcached
De-duplicazione delle scritture per ridurre IO
Interfaccia GUI per la gestione dei cluster molto interessante
Aggiornamento software senza mettere offline il database
Proxy di connessione per il pooling e il multiplexing (Moxi)
Utilizzo ideale: Qualsiasi applicazione dove un bassa latenza dell’accesso ai dati, un’alta concorrenzialità e un’alta disponibilità degli stessi sono requisiti chiave.
Per esempio: Casi in cui c’è necessità di bassa latenza come l’erogazione di servizi di pubblicità mirata (ad targeting)  o alta concorrenza come il giochi online (per esempio Zynga).

– Neo4j

Scritto in: Java
Punto principale: Database a grafi o dati connessi
Licenza: GPL, salcune caratterstiche con AGPL/commerciale
Protocollo: HTTP/REST (o incluso in  Java)
Standalone, o includibile nelle applicazioni Java
Piena conformità ACID (incluso i dati durable)
Sia i nodi che le releazioni possono avere dei metadati
Linquaggio di query basato su pattern-matching (“Cypher”)
Può anche essere usato il linguaggio di attraversamento dei gravi “Gremlin”
Indicizzazione dei nodi, delle chiavi e delle relazioni
Piacevole interfaccia di amministrazione web
Sono disponibili diversi algoritmi di ricerca dei percorsi
Ottimizzato per le letture
Ha le transazioni (nelle API Java)
Si può usare il linguaggio di scripting Groovy
Backup online, monitoraggio avanzato e alta disponibilità con licenza AGPL/commerciale
Utilizzo ideale: Per dati interconnessi, semplici o complessi, con struttura a grafo. In questo senso Neo4j is è un po’ diverso dagli altri database noSQL.
Per esempio: Relazioni sociali, collegamenti nei trasposti pubblici, mappe di strade, topologie di rete.

– Cassandra

Scritto in: Java
Punto principale: Migliore di BigTable e Dynamo
Licenza: Apache
Protocollo: Proprietario, binario (Thrift)
Distribuzione e replicazione attivabile (N, R, W)
Query possibili mediante colonne e insiemi di chiavi
Carattersitiche simili a BigTable: colonne, famiglie di colonne
Indici secondati
La scrittura è molto più veloce della lettura(!)
Mappatura e riduzione possibile mediante Apache Hadoop
I admit being a bit biased against it, because of the bloat and complexity it has partly because of Java (configuration, seeing exceptions, etc)
Utilizzo ideale: Quando si scrive più che leggere (logging). Se ogni componente del sistema deve essere in Java.
Per esempio: Sistemi bancari e industria finanziaria.
Inoltre, siccome le scritture sono più veloci delle letture, una nicchia naturale è l’analisi dei dati in tempo reale.

– HBase

Scritto in: Java
Punto principale: miliardi di righe con milioni di colonne
Licenza: Apache
Protocollo: HTTP/REST (anche Thrift)
Modellato dopo BigTable
Mappatura e riduzione con Hadoop
Costrutti query push down attraverso scansione lato server e con filtri per il get
ottimizzazione per le query in tempo reale
E’ un gateway Thrift con alte performance
HTTP supports XML, Protobuf, and binary
Cascading, hive, and pig source and sink modules
Shell basata su Jruby (JIRB)
Punti di ripristino multipli
Rolling restart for configuration changes and minor upgrades
L’accesso random ai dati è paragonabile a quello di MySQL
Utilizzo ideale: Se siete innamorati di BigTable.   e quando c’è la necessità di un accesso in lettura e scrittura, random e in tempo reale alla grande quantità di dati.
Per esempio: il database dei messaggi in Facebook.

 

La scelta e’ davvero varia a seconda del compito che vi serve maggiormente venga svolto dal DB che avrete prescelto, quindi perche’ non provarli ?