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;)
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
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
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