2013-06-11 16 views
5

Sono un nodo noob e sto cercando di capire come implementare auto discovery in un'applicazione node.js. Userò lo cluster module e voglio che ogni processo di lavoro sia tenuto aggiornato (e connesso permanentemente) ai nodi elasticache.Come implementare il rilevamento automatico di AWS Elasticache per node.js

Poiché non esiste un concetto di memoria condivisa (come APC PHP), è necessario disporre del codice che viene eseguito in ciascun worker, che si attiva ogni X secondi e in qualche modo aggiorna l'elenco di IP e ricollega il client memcache?

Come fanno le persone a risolvere questo oggi? Il codice di esempio sarebbe molto apprezzato.

risposta

3

Si noti che in questo momento, Auto Discovery è disponibile solo per i cluster di cache che eseguono il motore memcached.

Per Cache Engine versione 1.4.14 o superiore è necessario creare un socket TCP/IP alla cache Cluster configurazione degli endpoint (o qualsiasi cache del nodo Endpoint) ed invia il comando:

config get cluster 

Con Nodo. js puoi usare lo net.Socket class su quello.

La risposta è composta da due linee:

  • Il numero di versione delle informazioni di configurazione. Ogni volta che un nodo viene aggiunto o rimosso dal cluster di cache, il numero di versione aumenta di uno.

  • Un elenco di nodi della cache. Ogni nodo nell'elenco è rappresentato da un nome host | ip-address | port group e ogni nodo è delimitato da uno spazio.

Un ritorno a capo e un carattere di avanzamento riga (CR + LF) viene visualizzato alla fine di ogni riga.

Qui puoi trovare una descrizione più dettagliata di come add Auto Discovery to your client library.

Utilizzando il modulo cluster è necessario memorizzare le stesse informazioni in ogni processo (es. Bambino) e vorrei utilizzare "setInterval" per bambino per controllare periodicamente (ad esempio ogni 60 secondi) l'elenco dei nodi e riconnettere solo se la lista è cambiata (questo non dovrebbe accadere molto spesso).

È possibile aggiornare l'elenco solo sul master e utilizzare "worker.send" per aggiornare i lavoratori. Questo potrebbe mantenere tutti i processi in esecuzione in un singolo server più sincronizzati, ma non sarebbe di aiuto in un'architettura multi server, quindi è molto importante usare l'hashing costante per poter modificare l'elenco dei nodi e perdere la quantità "minima" di chiavi memorizzate nel cluster memcached.

Vorrei utilizzare una variabile globale per memorizzare questo tipo di configurazione.

Pensando due volte è possibile utilizzare l'SDK AWS per Node.js per ottenere l'elenco dei nodi ElastiCache (e che funziona anche per il motore Redis).

In tal caso il codice sarebbe qualcosa di simile:

var util = require('util'), 
    AWS = require('aws-sdk'), 
    Memcached = require('memcached'); 

global.AWS_REGION = 'eu-west-1'; // Just as a sample I'm using the EU West region                      
global.CACHE_CLUSTER_ID = 'test'; 
global.CACHE_ENDPOINTS = []; 
global.MEMCACHED = null; 

function init() { 

    AWS.config.update({ 
     region: global.AWS_REGION 
    }); 
    elasticache = new AWS.ElastiCache(); 

    function getElastiCacheEndpoints() { 

     function sameEndpoints(list1, list2) { 
      if (list1.length != list2.length) 
       return false; 
      return list1.every(
       function(e) { 
        return list2.indexOf(e) > -1; 
       }); 
     } 

     function logElastiCacheEndpoints() { 
      global.CACHE_ENDPOINTS.forEach(
       function(e) { 
        util.log('Memcached Endpoint: ' + e); 
       }); 
     } 

     elasticache.describeCacheClusters({ 
       CacheClusterId: global.CACHE_CLUSTER_ID, 
       ShowCacheNodeInfo: true 
      }, 
      function(err, data) { 
       if (!err) { 
        util.log('Describe Cache Cluster Id:' + global.CACHE_CLUSTER_ID); 
        if (data.CacheClusters[0].CacheClusterStatus == 'available') { 
         var endpoints = []; 

         data.CacheClusters[0].CacheNodes.forEach(
          function(n) { 
           var e = n.Endpoint.Address + ':' + n.Endpoint.Port; 
           endpoints.push(e); 
          }); 
         if (!sameEndpoints(endpoints, global.CACHE_ENDPOINTS)) { 
          util.log('Memached Endpoints changed'); 
          global.CACHE_ENDPOINTS = endpoints; 
          if (global.MEMCACHED) 
           global.MEMCACHED.end(); 
          global.MEMCACHED = new Memcached(global.CACHE_ENDPOINTS); 
          process.nextTick(logElastiCacheEndpoints); 
          setInterval(getElastiCacheEndpoints, 60000); // From now on, update every 60 seconds       
         } 
        } else { 
         setTimeout(getElastiCacheEndpoints, 10000); // Try again after 10 seconds until 'available'      
        } 
       } else { 
        util.log('Error describing Cache Cluster:' + err); 
       } 
      }); 
    } 

    getElastiCacheEndpoints(); 

} 

init(); 
+0

Sì, ma dove si fa a memorizzare l'elenco di IP? Var globale? E come lo risolvete con il modulo cluster? Un 'setTimeout()' che imposta una variabile globale per figlio? – rynop

+0

Ho aggiunto alcuni chiarimenti, fammi sapere se questo aiuta. – danilop

+0

Grazie. Se io/qualcuno forniremo un esempio completo, contrassegnerò quell'an come corretto. – rynop

Problemi correlati