Il Nodo (GPFS) che non se ne voleva andare

Se un nodo GPFS si rifiuta di essere eliminato da un cluster, non perdete la speranza. E leggete una man page aggiornata.

OK, qualcuno ha fatto una mossa che non andava fatta, ma capita anche ai migliori di fare una fesseria ogni tanto.

E' successo che una macchina facente parte di un cluster di server GPFS (il filesystem parallelo di IBM) è stata formattata, destinata a nuovo uso e reinstallata PRIMA che il cluster GPFS fosse stato opportunamente riconfigurato.

La mossa non ha causato nessun disservizio palese agli utenti, visto che GPFS è fatto per essere fault-tolerant, e che il quorum di server attivi rimaneva raggiunto. Però è come lavorare con un raid con un disco rotto... non si sta tranquilli fino a che non lo hai riparato. Per non parlare degli allarmi attivi del sistema di monitoraggio.

Quindi inizio a riconfigurare il cluster per portarlo in uno stato consistente. Molti comandi di gestione GPFS si lamentano dell'assenza del server incriminato, ma le cose bene o male sembrano andare fino al momento in cui tento di rimuovere il nodo dal pool: il comando

mmdelnode -N ilMioNodoRazzato

non si esegue, e si lamenta perché non riesce a connettersi al nodo reinstallato. La man page non è di nessun aiuto, e tra l'altro nessuna opzione per forzare il comando è disponibile. Improvviso un pò di imbrogli, ma non va nulla. Sembra che l'unica opzione sia reinstallare la macchina da un backup (e qua stendo un velo pietoso... diciamo che non si può fare).

Allora cerco in rete e ala fine mi accorgo che nella versione più recente della man page di mmdelnode ci sta scritto:

You cannot delete a node if both of the following are true:
    The node responds to a TCP/IP ping command from another node.
    The status of the node shows unknown when you use the mmgetstate command from another node in the cluster.
Note: You will probably be able to delete such a node if you physically power it off.

Quindi il maledetto comando si rifiuta di eseguire se trova un nodo con cui non riesce a comunicare con il demone gpfsd ma che risponde al ping.

Rileggo la man page sul mio sistema e questa informazione non c'è: ovviamente sto lavorando con una versione vecchia di GPFS.

Faccio un reboot del server reinstallato e contestualmente eseguo mmdelnode: funziona. Il comportamento è identico ma questa feature non è documentata nel man.

Poi ci si meraviglia se la gastrite diventa una malattia professionale degli ops.

Migliorare la gestione del purge caching in Plone: collective.purgebyid

collective.purgebyid è un approccio alternativo alla gestione del purge caching per Plone, perché si basa sugli UUID degli oggetti anzichè sulle URL.

Premessa

Quando il traffico di un sito web è elevato, è opportuno affiancare un servizio di HTTP accelerator al sistema di gestione dei contenuti. Quindi un layer che faccia da reverse proxy e allo stesso tempo da cache dei contenuti medesimi: in questo ambito Varnish è sicuramente uno dei sistemi free più flessibili e performanti.

Nella pratica si presente però spesso un tema sottovalutato, ma che è fondamentale: definire la corretta politica di cache invalidation. Qual è il tempo di vita degli oggetti nella cache ? Quali sono gli eventi con i quali si puó forzare la scadenza di un oggetto ?

Plone.app.caching: purge by URL

Il CMS Plone ha un ottimo prodotto in grado di gestire in maniera molto precisa queste regole: plone.app.caching. Con p.a.caching è possibile definire delle regole di validità per una pagina web o per una risorsa (immagine, css, javascript, ...) in modo molto preciso, ad esempio in base alla tipologia del contenuto o alla vista applicata allo stesso, oppure è possibile definire una validità condizionata alla data di modifica o all'E-tag e molto altro. È infine possibile definire delle regole di invalidazione immediata (purging) su un sistema esterno di caching (nel nostro caso appunto Varnish).

I tipi di cache

I tipi definiti in p.a.caching sono quattro (c'è anche una modalità di concatenazione - Chain - che peró non ci interessa): Strong Caching, Moderate Caching, Weak Caching, No Caching. Le ultime due si basano essenzialmente su una verifica della validità del contenuto fatta direttamente da Plone, la prima cerca di sfruttare al massimo la cache del browser e per questo motivo è usata in genere unicamente per contenuti che variano al variare della url richiesta, mentre la seconda (Moderate) è per noi la più interessante:

Moderate caching
Cache in browser but expire immediately (same as weak caching), and cache in proxy (default: 24 hours). Use a purgable caching reverse proxy for best results. Caution: If proxy cannot be purged reliably (for example, in the case of composite pages where it may be difficult to track when a dependency has changed) then stale responses might be seen until the cached entry expires. A similar caution applies even if in the purgeable case, if the proxy cannot be configured to disallow caching in other intermediate proxies that may exist between the local proxies and the browser (see the example proxy configs included with this package for some solutions to this problem).

In genere quando si ha a che fare con siti ad alto traffico, l'approccio è quello di minimizzare il numero di richieste all'application server (nel nostro caso il CMS Plone) rispetto al numero totale di richieste. Quando è possibile controllare l'aggiornamento di un contenuto, è conveniente definire dei tempi lunghi di permanenza nella cache ed invalidarla puntualmente solo a fronte della modifica del contenuto stesso. Questa modalità viene proposta usualmente per i contenuti di tipo file e immagini.

È fondamentale, per il corretto funzionamento del servizio, che il sistema di notifica invalidi immediatamente tutti i contenuti modificati, altrimenti si rischia di visualizzare, ad esempio, delle immagini non aggiornate e questo è assolutamente fastidioso per qualsiasi redattore di contenuti web.

plone.cachepurging e il problema di definire le tutte URL da invalidare

p.a.caching a propra volta usa plone.cachepurging per determinare tutte le URL da invalidare nel sistema di caching e fare le opportune chiamate di purge al medesimo. Il funzionamento di base di p.cachepurging è quello di invalidare delle pagine a fronte della modifica, rinomina o  cancellazione di un contenuto e quindi la difficoltà e la complessità dell'operazione deriva dal fatto che le URL da invalidare sono determinate in base al contenuto e alla propria tipologia. Prendiamo ad esempio questa immagine: http://2013.ploneconf.org/ploneconf/images/ccug: nel momento in cui essa venisse modificata probabilmente i sistemi di caching riceverebbero le seguenti richieste (o qualcosa di simile a queste):

PURGE http://2013.ploneconf.org/ploneconf/images/ccug
PURGE http://2013.ploneconf.org/ploneconf/images/ccug/
PURGE http://2013.ploneconf.org/ploneconf/images/ccug/view
PURGE http://2013.ploneconf.org/ploneconf/images/ccug/image_mini
PURGE http://2013.ploneconf.org/ploneconf/images/ccug/image_thumb
...

e molte altre simili: il problema risiede nel fatto che non si può avere sempre la certezza di avere intercettato tutte le URL possibili utilizzate per visualizzare quell'immagine. Essa potrebbe essere stata scalata dinamicamente in altri contesti (usando plone.scale ad esempio) o qualche prodotto simile, oppure, in modo errato o consapevole, potrebbe essere stata riferita con un URL come la seguente http://2013.ploneconf.org/ploneconf/images/ploneconf/ccug, o con una querystring.

Per risolvere questi casi d'uso, l'approccio di p.a.caching è quello di creare di volta in volta dei nuovi adapter, volti a determinare le nuove URL di cui fare il purge per Plone, e in alcuni casi questa soluzione non risulta essere molto efficace.

Enter purge by id: invalidare la cache con gli uuid

Leggendo un interessante articolo nel blog di varnish sulla cache invalidation mi è venuta l'idea di utilizzare gli identificativi univoci delle risorse Plone (uuid) per identificarle e utilizzare quell'informazione ai fini dell'invalidazione. L'idea è molto semplice e dalle prime verifiche anche efficace: collective.purgebyid è un'implementazione di questa idea, liberamente utilizzabile (GPL).

Come funziona

In breve, il protocollo è il seguente:

  1. alla response di Plone viene aggiunto un nuovo header X-Ids-Involved con gli uuid degli oggetti coinvolti. Per esempio, nel caso base di un'immagine, il singolo uuid dell'oggetto immagine:

    % wget -S http://localhost:8080/Plone/image01
    ...
      X-Ids-Involved: #c8d7c0bc2b794325b916d990de91d7ee#
  2. una nuova regola di purge rewrite aggiunge alle URL di cui fare il purge una URL particolare nella forma /@@purgebyid/<UUID> con lo uuid dell'oggetto relativo alla URL di cui fare il purge,
  3. nella configurazione dell'HTTP accelerator a fronte di una operazione di purge e di una URL nella forma /@@purgebyid viene fatto un ban specifico (termine usato da Varnish, si veda la configurazione sottostante) per eliminare dalla cache tutti gli oggetti che abbiano nell'header X-Ids-Involved un'occorrenza dello UUID segnalato.

Un esempio di configurazione

Un esempio di configurazione per Varnish è il seguente:

sub vcl_recv {
    if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
            error 405 "Not allowed.";
        }
        if (req.url ~ "^/@@purgebyid/") {
            ban("obj.http.x-ids-involved ~ #" + regsub(req.url, "^/@@purgebyid/", "") + "#");
            error 200 "Ban added";
        }
    }
}

sub vcl_deliver {
    unset resp.http.x-ids-involved;
}

Come si vede, è piuttosto semplice. Al momento la versione presente su https://github.com/collective/collective.purgebyid è ancora da considerarsi beta, ma le prove sono soddisfacenti: se pensate di utilizzare questo prodotto, dateci un feedback a riguardo !

Un po' di documentazione old style

Caricata sul sito la presentazione in PDF.

Nonostante la socialità imperante, ogni tanto un PDF da stampare fa comodo, sia da tenere sotto mano ad una riunione, che da consegnare brevi manu ad una riunione: visto che lo avevamo già scritto in antiquîs temporibus, tanto valeva caricarlo sul sito e renderlo disponibile a tutti.

Pertanto, per i curiosi e gli sfaccendati, ecco il link alla Offerta commerciale BioDec.

Agile Day 2012 presentation

I gave a presentation on BioDec hybrid methodology of Agile IT.

I gave a talk at Agile Day 2012 in Milan, last saturday (the video should be available soon on the conference web site, the slides are here).

The main topic was about the hybrid partially-Scrum / some-of-Kanban methodology that we adopted in BioDec. The results have been good, and the presentation tells how we got them.

FB tlaks to FB

JPEG image icon CCPZ0L4WAAAZ99p.jpg-large — JPEG image, 83 kB (85281 bytes)

People, listening

JPEG image icon CCNvSWWUIAAmid1.jpg-medium — JPEG image, 52 kB (54204 bytes)

Me, pontificating

JPEG image icon CCNvCS1UEAAVF_k.jpg-medium — JPEG image, 36 kB (37058 bytes)