MySQLfs, un nuovo approccio al concetto di filesystem condiviso

Da alcuni mesi sto lavorando su un progetto in cui una certa mole di dati deve essere memorizzata su un filesystem condiviso tra più nodi attivi di un cluster, anche con replicazione distribuita su base geografica.

Abbiamo vagliato una serie di soluzioni differenti basate su tecnologie differenti e con approcci differenti al problema, ma abbiamo avuto parecchie difficoltà a trovare qualcosa che soddisfare tutti i nostri prerequisiti. Nell’ordine abbiamo valutato…

  • NBD: approccio alla replica block based. Ha una logica di funzionamento tale da far si che tutte le operazioni effettuate da un nodo su un dato disco vengano replicate su un altro nodo connesso via rete locale. La sincronizzazione è effettuata a livello di blocchi utilizzando delle tabelle bitmap per individuare, una volta effettuata la prima sincronizzazione iniziale, quali siano i blocchi modificati. Di fondo l’approccio di funzionamento è agnostico al filesystem ed è analogo a quello di md, il mirror software, di Linux. Questo approccio nativo pone due grandi limiti:
    • il primo è che una replica block level, proprio in quanto agnostica rispetto al filesystem, sarà sempre molto dispendiosa in termini di quantità di dati da far viaggiare tra un nodo e l’altro (i blocchi sono piccoli, le scritture non ottimizzabili o sequenziabili…) e soprattutto, per quanto ottimizzata dalle mappe bitmap nel momento in cui il nodo slave fosse momentaneamente sconnesso dal primario, dovrebbe forzatamente rifare un check sull’allineamento con l’intero volume intero – fattori molto importanti in quanto rendono praticamente impossibile utilizzare NDB in uno scenario in cui i due server non siano in rete locale
    • il secondo è che il nodo slave è un hot standby ed il nodo secondario non ha accesso ai dati che sono disponibili sul suo disco fintanto che questo non diventi il master. Per onestà intellettuale va detto che da un paio di anni NDB include anche una finta modalità multi master in cui entrambi i volumi possono essere montati contemporaneamente su entrambi i server e la sincronizzazione è bidirezionale, ma di fondo si tratta nuovamente di una mezza fregatura: NDB non è un filesystem (ed è agnostico al filesystem) quindi con lui da solo non potrete farci niente. Un eventuale filesystem ext3 creato nel volume NDB condiviso non potrà essere acceduto dal secondo server perché ext3 non è multi sessione. NDB non implementa partizioni di quorum, non implementa meccanismi di locking multinodo… Nulla. La soluzione che quindi viene suggerita è quella di usare un filesystem clustered tipo GFS di RedHat o OCFS2 di Oracle sul volume NDB che a questo punto farebbe solo finta di essere un improbabile storage condiviso via rete… A mio avviso una bella schifezza, considerato il forte impatto in termini di implicazioni tecniche e tecnologiche nell’implementare un filesystem cluster (il multi cast per GFS, l’uso di clvm, un filesystem non rimontabile facilmente in caso di Disaster Recovery nel caso di OCFS2)

    Qualora tutto ciò non vi fosse sembrato abbastanza, NDB non ha alcuna logica interna per la gestione stessa del cluster che secondo le menti dietro di esso dovrebbero essere demandate a qualcosa di esterno tipo HA. Insomma, in soldoni NDB dice di fare tutto ma fa piuttosto poco.

  • HAST di FreeBSD giusto per renderci conto che ha gli stessi esatti limiti di NDB. Che peccato per un progetto nato praticamente praticamente ora e che per di più sarà ancora più castrato dalla mancanza di filesystem come GFS ed OCFS2 su FreeBSD. In pratica quindi il fratello stupido di qualcosa che già non è completo. Epic Fail.
  • la DataReplication delle EVA-qualcosa di HP. Fichissima, incrementale e WAN aware (con tanto di compressione dei dati in transito), peccato che il nodo secondario sia nuovamente un hots-tandby inoperativo.
  • sincronizzazioni timerizzate a base di rsync: paradossalmente la soluzione che a conti fatti rispondeva alla maggior parte dei prerequisiti – è incrementale, funziona tramite internet, è compressa… Insomma mica male… Il problema è che dovendo schedulare la risincronizzazione ad intervalli temporali, proprio in quanto timerizzata ha dei buchi di disallineamento. Certo uno può pianificare le sincronizzazioni molto frequenti, ma il problema è che l’operazione di risincronizzazione, per quanto non trasferisca dati allineati, è piuttosto lenta a partire, soprattutto al crescere dei file memorizzati. Con poche decine di migliaia di file tramite internet la frequenza minima realistica di allineamento è di 10/15 minuti di intervallo.
  • ZFS su FreeBSD: ancora una volta una soluzione superganza, questa volta anche facilmente backuppabile, ma anche questa volta non compatibile con uno scenario dual master.
  • HDFS: multi master, geograficamente distribuito, incrementale… Ma… cluster di 64MB? Il dispatcher dei nodi non è clusterizzabile e non ha per design uno slave? Ma stiamo scherzando? diciamo che ho letto male la documentazione, dai.

a questo punto della mia ricerca devo dire che iniziavo ad essere piuttosto sconfortato, quando mi sono ricordato di aver letto un po’ di tempo fa di un progetto per creare un filesystem virtuale operante su database MySQL: MySQLfs.

Ho cercato e su sourceforge ho trovato la pagina del progetto, purtroppo apparentemente non otto attivo, visto che l’ultima versione, la 0.4.0 è del 2009… In un impeto di ottimismo ho deciso di provare comunque a scaricarlo e compilarlo.

MySQLfs è, in verità, un modulo per FUSE, il progetto che permette di scrivere dei filesystem custom operanti in userland invece che a livello kernel. I vantaggi sono molti, tra cui la possibilità di scrivere facilmente un modulo che si interfacci con le librerie standard mysql. Nel caso specifico, mysqlfs si limita a “tradurre” in SQL le write e le effettuate verso il filesystem che astrae. La cosa interessante è che il database dentro cui vengono memorizzati i dati può essere replicato su altri nodi mysql. La replicazione di mysql è ovviamente incrementale, trasformando indirettamente il filesystem risultante in un vero e proprio filesystem journaled di tipo copy on write, ed il database è ovviamente intrinsecamente multi sessione e quindi può essere tranquillamente montato in modalità multi master su più nodi. Il protocollo mysql su cui è basata la replicazione è compresso e si comporta molto bene anche su tratte geografiche.
Il database è facilmente backuppabile sia in maniera integrale (dump) sia in maniera incrementale (ad esempio backuppando i binary log stessi della replication), è atomico e transazionale…

Insomma sulla carta sembrerebbe essere la soluzione di tutti i mali.

Ma ovviamente c’è sempre un “ma”

Allo stato attuale mysqlfs 0.4.0 è piuttosto lento.

Fortunatamente ci ho lavorato un po’ per portarlo al passo con i tempi e per ottimizzare alcune cose tra cui:

  • passaggio alla versione 26 delle api di fuse, più perforanti e che supportano la modalità “big writes” che, in soldoni, leggono e scrivono blocchi di dati più grossi riducendo drasticamente il numero di QUERY eseguite
  • implementazione del supporto alle transazioni, che ottimizza drasticamente l’uso del binary log da parte di mysql, evitando le racing conditions tra le scritture al disco da parte del db engine e quelle da parte del thread del binary log

I risultati preliminari sono ottimi e spero di rilasciare una versione pubblica di questa nuova release di mysqlfs al più presto.

Cercherò di contattare gli autori originali per far includere le mie modifiche nella distribuzione ufficiale.

Ravioli ai pistacchi con zucchine e speck

Ieri mi sono imbattuto in un negozio che prepara pasta fresca artigianale. Al suo interno ho trovato dei ravioli ai pistacchi ed ho deciso di provarli. Per celebrarli meglio ho inventato una ricetta ad-hoc.

Stasera l’ho provata e, per essere la prima volta, mi pare il risultato sia venuto ottimo.

Ingredienti per 4 persone:

  • 400 gr di ravioli ricotta e pistacchio
  • 100 gr di speck a dadini (o un culetto di speck da tagliare a dadini)
  • 250 gr di zucchine
  • una confezione (250gr, di cui useremo la metà) di panna di soia (più leggera, più delicata e soprattutto non litiga con il vostro intestino!)
  • una confezione di noci, possibilmente già aperte…
  • una confezione di pistacchi

Preparazione:
Tagliate le zucchine alla julienne, possibilmente togliendogli un po’ di buccia (diventa amara). Non dico di pelarle (mai!), ma se come me usando il robot multiuso vi rimane la buccia intera gettatela.
Mettete l’acqua per la pasta sul fuoco. In una padella grande mettete un goccino di acqua e quando inizia a scaldarsi gettateci dentro le zucchine julienne aggiungendo anche un pizzichino di pepe e sale. Lasciatele sbollentare un po’ dato che butteranno fuori l’acqua. Quando si iniziano ad asciugare ed ad essere cotte buttate dentro lo speck a dadini mescolando tutto per bene di modo che lo speck si cuocia. Quando inizia a tirare aggiungete un po’ di panna di soia. Poca, diciamo una 70 di grammi circa, un quarto di confezione. Mescolate e dato che la panna di soia è molto liquida lasciatela stringere un po’. Quando la panna si è un po’ addensata spegnete il fuoco. A questo punto l’acqua probabilmente starà bollendo. Mettete il sale e buttate i ravioli che presumibilmente cuoceranno per almeno una decina di minuti.
Nel frattempo prendete un pugno di noci pulite ed un pugno di pistacchi puliti e frullateli. Metteteli in un pentolino con il fuoco al minimo e lasciateli tostare. Attenzione perché nel giro di dieci secondi passano da tostati a bruciati.
Quando i ravioli sono cotti, anzi, qualche secondo prima, scolateli e buttateli nella padella con il condimento rimettendola sul fuoco. Aggiungeteci un altro quarto di panna (quindi altri 70gr circa) per ravvivare e legare condimento e ravioli. Se vi piace e vi ispira metteteci un po’ di parmigiano, per legare, ma attenzione perché potrebbe diventare salato.
Dopo circa un minuto di padella spegnete il fuoco ed impiattate cospargendo leggermente il piatto con la granella di noci e pistacchi che avete preparato prima,

Buon appetito.

Fuori dal tempo

Sono a Lecce, per suonare con gli Shots in The Dark.

Per arrivare abbiamo percorso la Napoli Bari. Non è la prima volta che la faccio, assolutamente, eppure ogni volta che la percorro, superato l’orrendo tratto Beneventino tutto curve in discesa, ho sempre l’impressione di iniziare un viaggio che mi porta fuori dallo spazio e dal tempo…

Le montagne si addolciscono e si abbassano a diventare colline. Le case spariscono. La vegetazione si dirada. Compaiono le enormi pale eoliche.

Ci sono un paio di stazioni di servizio in quella zone. Fermatevici, merita. Almeno secondo me.

Silenzio assoluto, vento – quasi sempre, non a caso ci sono le pale… – ma non essendoci vegetazione il mondo rimane immobile, tranne per questi moderni mulini a vento che maestosi, bianchi, si stagliano nel cielo roteando,

Lo so, è bizzarro, ma sono un techno freak ed una cosa del genere per me ha del magico: la natura incontaminata che incontra la tecnica e la tecnologia umana – e non una qualsiasi tecnologia che distrugga la nostra culla, ma una tecnologia buona – ed insieme a quello da la mano al cielo.


Ascoli Satriano
(tipo il chitarrista)

PHP: CURL – Upload di un file in POST, dietro proxy.

PHPRecentemente mi sono trovato a dovere simulare il comportamendo di un browser interagendo con un web server in PHP. L’obiettivo dello script PHP che si stava facendo era quello di simulare il caricamento in POST di un documento. L’obiettivo è facilmente raggiungibile in PHP tramite le librerie CURL. Cercando su internet si trovano numerosi esempi da cui se ne deduce che l’uso-tipo è il seguente:


/* L'url a cui inviare il POST */
$request_url = "http://www.ciccio.com/upload.php";

/* Indico a CURL quale sia il file da inviare:
 * nel form c'è un <input type="file" name="FileUP" /> */
$post_params['FileUP'] = "@/home/io/TestPdf2.pdf";

/* Nel Form ho un qualsivoglia altro parametro da passare
 * in post */
$post_params['AltroParametro'] = "Ezekiel";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
$result = curl_exec($ch);
curl_close($ch);

Il trucco sta nello specificare con la @ davanti il nome del file da inviare: in questo modo CURL capisce che parliamo di un file e si regola di conseguenza. Tutto ha funzionato bene fino a che non ho provato ad eseguire lo stesso codice da dietro SQUID in modalità trasparente, che ha iniziato a rispondermi “Invalid request”. Dopo ore ed ore di tentativi (inutili), ho scoperto che il punto è molto semplice: CURL utilizza un’intestazione HTTP non supportata da Squid, la “Expect: 100-continue”. Per impedire questo comportamento è sufficiente aggiungere un’opzione:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

E tutto magicamente funzionerà.

FreeBSD Ports: installazioni tramite proxy http

Al fine di superare eventuali blocchi topologici, o semplicemente per ottimizzare l’utilizzo della connessione ad internet è possibile specificare le impostazioni relative ad un server Proxy HTTP ed FTP da usarsi durante le operazioni di compilazione dei Ports.

La cosa è piuttosto semplice: i ports scaricano ogni pacchetto utilizzando l’utility di sistema fetch la quale referenzia due variabili di ambiente per leggere le impostazioni relative ai proxy:

  • HTTP_PROXY
  • FTP_PROXY

Per far si, quindi, che i ports utilizzino il proxy in fase di installazione del software basterà modificare il file RC del proprio profilo (ad esempio .cshrc per l’utente root) aggiungendo le seguenti righe:

setenv HTTP_PROXY http://192.168.1.200:3128/
setenv FTP_PROXY http://192.168.1.200:3128/

Al fine di risolvere alcuni problemi di compatibilità con alcuni software di scuola linux (ad esempio wget) può essere utile specificare le stesse variabili anche in lower-case:

setenv http_proxy http://192.168.1.200:3128/
setenv ftp_proxy http://192.168.1.200:3128/

Da notare, inoltre, che è molto importante specificare le impostazioni del proxy con la sintassi http://utente:password@host:porta/ al fine di specificare che il proxy che si sta utilizzando è di tipo HTTP (ad esempio nel caso di SQUID). Discorso diverso invece qualora si stia utilizzando un ftp-gateway, in tal caso l’impostazione del FTP_PROXY dovrà seguire l’apposita sintassi.

FreeBSD Ports: condivisione distfiles

Al fine di ottimizzare al massimo i tempi di installazione dei pacchetti scaricati tramite ports e minimizzare i trasferimenti da web, è possibile realizzare una struttura condivisa di gestione della directory distfiles dei ports di FreeBSD.

La directory, normalmente situata in /usr/ports/distfiles, contiene infatti tutti i pacchetti scaricati da internet per effettuare l’installazione dei ports.

La logica alla base dell’ottimizzazione è quella di creare una singola macchina repository che condivida a tutte le altre macchine la directory distfiles. La tecnologia “nativa” per la condivisione delle directory via rete sotto FreeBSD/Unix è l’NFS. La sua configurazione è piuttosto semplice, ed essendo parte del base-system, non richiede alcuna installazione di software aggiuntivo.

Condivisione lato Repository

Per condividere la cartella sulla macchina di Repository sarà sufficiente attivare il servizio nfsserver ed esportare la directory.

Il primo step da effettuare è quello di configurare il file export indicando quali directory si voglia esportare ed a quali server. Il file è situato in /etc/export e la sua sintassi è piuttosto basilare: ogni riga contiene il path da esportare e l’indirizzo IP (o gli indirizzi IP) che potranno accederci. Sarà possibile inoltre specificare alcuni parametri aggiuntivi quali -ro per indicare che l’export debba essere effettuato “read-only”. Nel nostro caso, però, non è così:

/usr/ports/distfiles 192.168.1.10 192.168.1.24 192.168.1.45

A questo punto per attivare il servizio nfsserver bisogna modificare il file /etc/rc.conf aggiungendo le seguenti righe:

rpcbind_enable="YES"
nfs_server_enable="YES"
mountd_flags="-r"

A questo punto per avviare manualmente il server (che comunque si avvierà al reboot della macchina) è sufficiente eseguire:

/etc/rc.d/rpcbind start
/etc/rc.d/nfsserver start
/etc/rc.d/nfsd start

Per verificare di aver effettuato tutto correttamente a questo punto si può eseguire il comando showmount -e che elencherà tutti i filesystem condivisi sull’attuale macchina (nonché chi possa accedere alle condivisioni).

Accesso al Repository

L’accesso al Repository lato client è ancora più semplice: sarà infatti sufficiente attivare il client NFS e provvedere al mount del volume remoto. Per attivare il client NFS bisogna modificare il file /etc/rc.conf aggiungendo le seguenti righe:

nfs_client_enable="YES"

A questo punto per avviare manualmente il client (che comunque si avvierà al reboot della macchina) è sufficiente eseguire:

/etc/rc.d/nfsclient start

Bene, a questo punto è possibile effettuare il mount del volume remoto. Per far ciò la cosa migliore è rinominare l’eventuale vecchia distfiles già presente sul client ed effettuare il mount.

mv /usr/ports/distfiles /usr/ports/distfiles.old
mount <server>:/usr/ports/distfiles /usr/ports/distfiles

Per essere sicuri che il volume remoto venga automaticamente rimontato al boot sarà sufficiente modificare il file /etc/fstab aggiungendo una riga relativa al mount remoto:

<server>:/usr/ports/distfiles /usr/ports/distfiles nfs rw 0 0

1 gennaio 2010

Buona sera Londra.

Prima di tutto vi prego di scusarmi per questa interruzione. Come molti di voi io apprezzo il benessere della routine quotidiana, la sicurezza di ciò che è familiare, la tranquillità della ripetizione. Ne godo quanto chiunque altro. Ma nello spirito della commemorazione, affinché gli eventi importanti del passato, generalmente associati alla morte di qualcuno o al termine di una lotta atroce e cruenta vengano celebrati con una bella festa, ho pensato che avremmo potuto dare risalto a questo 5 novembre, un giorno ahimè sprofondato nell’oblio, sottraendo un po’ di tempo alla vita quotidiana, per sederci e fare due chiacchiere. Alcuni vorranno toglierci la parola, sospetto che in questo momento stiano strillando ordini al telefono e che presto arriveranno gli uomini armati. Perché? Perché, mentre il manganello può sostituire il dialogo, le parole non perderanno mai il loro potere; perché esse sono il mezzo per giungere al significato, e per coloro che vorranno ascoltare, all’affermazione della verità. E la verità è che c’è qualcosa di terribilmente marcio in questo paese. Crudeltà e ingiustizia, intolleranza e oppressione. E lì dove una volta c’era la libertà di obiettare, di pensare, di parlare nel modo ritenuto più opportuno, lì ora avete censori e sistemi di sorveglianza, che vi costringono ad accondiscendere a ciò. Com’è accaduto? Di chi è la colpa? Sicuramente ci sono alcuni più responsabili di altri che dovranno rispondere di tutto ciò; ma ancora una volta, a dire la verità, se cercate il colpevole… non c’è che da guardarsi allo specchio. Io so perché l’avete fatto. So che avevate paura. E chi non ne avrebbe avuta? Guerre, terrore, malattie. C’era una quantità enorme di problemi, una macchinazione diabolica atta a corrompere la vostra ragione e a privarvi del vostro buon senso. La paura si è impadronita di voi, ed il Caos mentale ha fatto sì che vi rivolgeste all’attuale Alto Cancelliere, Adam Sutler. Vi ha promesso ordine e pace in cambio del vostro silenzioso, obbediente consenso. Ieri sera ho cercato di porre fine a questo silenzio. Ieri sera io ho distrutto il vecchio Bailey, per ricordare a questo paese quello che ha dimenticato. Più di quattrocento anni fa, un grande cittadino ha voluto imprimere per sempre nella nostra memoria il 5 novembre. La sua speranza, quella di ricordare al mondo che l’equità, la giustizia, la libertà sono più che parole: sono prospettive. Quindi, se non avete visto niente, se i crimini di questo governo vi rimangono ignoti, vi consiglio di lasciar passare inosservato il 5 novembre. Ma se vedete ciò che vedo io, se la pensate come la penso io, e se siete alla ricerca come lo sono io, vi chiedo di mettervi al mio fianco, ad un anno da questa notte, fuori dai cancelli del Parlamento, e insieme offriremo loro un 5 novembre che non verrà mai più dimenticato.

Material drummer

Per anni ho sostenuto con amici e conoscenti che il vero successo di “material girl” di madonna si basasse sul fatto che il batterista in quella canzone spigne come un treno. Oggi avendola ascoltata per l’ennesima volta ed essendomi di nuovo venuta la pelle d’oca sentendo la precisione chirurgica di quel rullante “avanti al tempo il giusto e non un capello di più” mi sono fatto curioso e ho cercato su internet chi ci fosse dietro ai fusti….

Trattasi di Tony Thompson… un batteristino qualunque che casualmente nella sua vita, oltre a suonare per il disco di Madonna, si da il caso che sia stato il batteria dei Chic, dei Sister Sledge, di Diana Ross, Rod Stewart (non so perché ma mi sa che se cerco scopro che ha suonato anche su “Do you think I’m sexy”… lo stilo è quello, ora mi informo…), Robert Palmer, i Led Zeppelin, Mick Jagger, David Bowie e qualche fuggitivo dei Duran Duran.

Come si dice… questione di manico

Inutile studiare se non c’è la materia prima… e se c’è basta anche un quattro quarti dritto sotto quella sgallettata di Madonna affinché la cosa si senta…