2012-08-14 20 views
27

Esiste un modo pulito per risolvere una query DNS (ottenere IP tramite nome host) in Java in modo asincrono, in modalità non bloccante (ad es. Macchina di stato, non 1 query = 1 thread - Mi piacerebbe eseguire decine di migliaia di query contemporaneamente, ma non eseguire decine di migliaia di thread)?Risoluzione DNS non bloccante (asincrona) in Java

Quello che ho trovato finora:

  • standard InetAddress.getByName() implementazione sta bloccando e si presenta come librerie standard di Java mancano eventuali implementazioni non-blocking.
  • Resolving DNS in bulk domanda discute un problema simile, ma l'unica soluzione trovata è l'approccio multi-thread (cioè un thread che lavora su una sola query in un dato momento della volta), che non è realmente scalabile.
  • dnsjava anche la libreria sta bloccando.
  • Ci sono ancient non-blocking extensions to dnsjava risalenti al 2006, quindi privi di qualsiasi materiale moderno di concorrenza Java come l'uso del paradigma Future e, purtroppo, un'implementazione solo in coda molto limitata.
  • dnsjnio Il progetto è anche un'estensione di dnsjava, ma funziona anche nel modello di thread (cioè 1 query = 1 thread).
  • asyncorg sembra essere la migliore soluzione disponibile che ho trovato finora rivolgendosi a questo problema, ma:
    • è anche dal 2007 e sembra abbandonato
    • manca quasi tutta la documentazione/javadoc
    • utilizza un sacco di tecniche non standard, come Fun classe

altre idee/implementazioni che ho perso?

Chiarimento. Ho una quantità di registri abbastanza grande (parecchi TB al giorno). Ogni riga di log ha un nome host che può provenire praticamente da qualsiasi parte di Internet e ho bisogno di un indirizzo IP per quel nome host per i miei ulteriori calcoli statistici.Ordine di linee non importa, quindi, in fondo, la mia idea è quella di iniziare a 2 thread: primo a iterare linee:

  • leggere una riga, analizzarlo, ottenere il nome dell'host
  • una richiesta al server DNS per risolvere un determinato nome host, non bloccare per risposta
  • Conservare la linea e query DNS maniglia presa in qualche buffer nella memoria
  • Vai alla riga successiva

e un secondo thread che:

  • Attendere che il server DNS per rispondere a qualsiasi domanda (utilizzando epoll/kqueue come tecnica)
  • Leggi la risposta, trovare quale linea è stato per in un buffer
  • Write linea con deliberato IP all'uscita
  • Procedere ad attendere la risposta successiva

Un'implementazione modello semplice in Perl utilizzando AnyEvent mi dimostra che la mia idea è generalmente corretto e posso facilmente raggiungere velocità come 15-20K quer IES al secondo in questo modo (l'implementazione di un ingenuo blocco equivale a 2-3 query al secondo - solo per ragioni di confronto - quindi è come una differenza di 4 ordini di grandezza). Ora ho bisogno di implementare la stessa in Java - e mi piacerebbe saltare stendere la mia implementazione DNS;)

+4

In quale situazione avete bisogno di "decine di migliaia di domande", allo stesso tempo? Come in, qual è il problema che stai davvero cercando di risolvere? – HonkyTonk

+0

Ho aggiunto dei chiarimenti sull'algoritmo che sto cercando di implementare (in effetti, è una tecnica di parallelizzazione abbastanza standard che comprime un sacco di query lente in una piccola quantità di tempo, eseguendole in parallelo). – GreyCat

+3

Come circa 1 thread legge i dati, incapsula il nome host in un oggetto e lo inserisce in una coda per n thread per bloccare il processo DNS/fetch dalla coda se fatto, e i risultati vengono inviati a un thread che esegue il lavoro di ordinamento Il risultato? È probabile che la comunicazione non bloccante nasconda il fatto che esiste un thread separato che sta effettuando comunicazioni bloccate. – nhahtdh

risposta

0

Si dispone di più opzioni

Opzione 1: Java 5 Esecutori

  1. A Pool di thread fisso: Executors.newFixedThreadPool (int)
  2. Future: A Future rappresenta il risultato di un calcolo asincrono. Vengono forniti metodi per verificare se il calcolo è completo, per attendere il suo completamento e per recuperare il risultato del calcolo.

Opzione 2: JMS con MessageListener

  1. Richiede dipendenza da JMS Provider ecc

Opzione 2: framework basato Attore

è possibile scalare questo bene con questo.Look a Akka.

+1

Scusate, non sto chiedendo la metodologia di parallelizzazione - so già quale sarebbe il migliore per tale compito - è un lavoro classico per un computer con un numero minimo di thread. Non ho nemmeno bisogno di una * coda * - l'ordine delle righe che ho elaborato non ha importanza in quanto verrebbero comunque utilizzate nell'elaborazione successiva. Sto chiedendo le librerie di query DNS per Java che possono essere eseguite in modalità non bloccante. – GreyCat

3

Sarà, penso, necessario implementare il protocollo del client DNS direttamente su UDP non elaborato utilizzando il supporto dei socket di base o su TCP utilizzando i canali NIO.

2

Non ho una risposta alla tua domanda (non so se esiste una libreria DNS che funzionerà nella modalità asincrona che desideri) e questo è troppo lungo per un commento.

Tuttavia, si dovrebbe essere in grado di produrre rapidamente uno asincrono senza dover scrivere manualmente il gestore DNS completo. Attenzione, non l'ho fatto quindi potrei sbagliarmi.

A partire dal codice dnsjava si dovrebbe essere in grado di implementare il proprio resolver che fornirà sia un metodo di invio che di ricezione. Controlla SimpleResolver e guarda il metodo send. Dovresti essere in grado di suddividere questo metodo in due metodi, uno per inviare la tua richiesta che raggiunge la chiamata al TCPClient o all'UDPClient (si gestirà l'invio effettivo sul filo a questo punto, come hai descritto, con il tuo primo thread), e, uno per ricevere, che verrebbe chiamato dal tuo secondo thread come risposta a un socket letto, e gestire l'analisi della risposta. Potrebbe essere necessario copiare tutto il codice da SimpleResolver (molti metodi privati ​​di cui avrete bisogno e licensing allows for it), oppure, potete creare la vostra versione e caricarla semplicemente prima di quella jared nel classpath, oppure, il tuo potrebbe riflettere la tua strada verso i metodi in questione e set them accessible.

È possibile creare rapidamente il lato client di rete con netty o mina. Preferisco la piccola per i documenti.

Se si percorre questo percorso e si può/desidera aprirlo, posso dedicare del tempo ad aiutare se si mette nei guai.

5

V'è un certo lavoro sul DNS non bloccante in in netty, ma è ancora in corso lavori in sarà probabilmente rilasciato solo nel 5,0

+0

DnsNameResolver sarà incluso nella versione 4.1.0 che verrà rilasciata a breve (è attualmente in 4.1.0.CR2). Se si desidera utilizzare alcune estensioni DNS, è necessario creare e analizzare i record del protocollo da soli, ma non dovrebbe essere un problema. – Karry