Java非同期で非ブロッキング方法(つまり、1クエリではなくステートマシン= 1スレッド)でDNSクエリを解決する(ホスト名でIPを取得する)クリーンな方法はありますか?数万のクエリを同時に実行しますが、数万のスレッドは実行しません)?
私がこれまでに見つけたもの:
InetAddress.getByName()
実装はブロッキングであり、標準のJavaライブラリには非ブロッキング実装がないように見えます。Future
パラダイムの使用法などの最新のJava同時実行機能、そして残念ながら、非常に限られたキューのみの実装。Fun
クラスなどの多くの非標準的な手法を使用します私が見逃した他のアイデア/実装はありますか?
説明。かなり大量の(1日あたり数TB))ログがあります。すべてのログ行には、インターネット上のほぼどこからでも取得できるホスト名があり、そのホスト名のIPアドレスが必要です。私のさらなる統計計算のために。行の順序は実際には重要ではないので、基本的に、私の考えは2つのスレッドを開始することです:最初に行を反復します:
そして、次の2番目のスレッド:
epoll
/kqueue
のような手法を使用)AnyEvent
を使用したPerlでの単純なモデル実装は、私の考えが一般的に正しく、この方法で1秒あたり15〜20Kクエリのような速度を簡単に達成できることを示しています(ナイーブブロッキング実装は1秒あたり2〜3クエリのようになります-ちょうど比較のために-それは4桁の違いのようなものです)。今、私はJava-で同じものを実装する必要があります-そして私は自分のDNS実装の展開をスキップしたいと思います;)
DNSのApache Directory Services実装 MINAの上にあるのがあなたが探しているものかもしれません。 JavaDocsおよびその他の便利なガイドは、そのページの左側のサイドバーにあります。
netty で非ブロッキングDNSに関するいくつかの作業がありますが、まだ進行中の作業であり、おそらく5.0でのみリリースされる予定です。
基本ソケットサポートを使用して生のUDPの上に、またはNIOチャネルを使用してTCPの上に、DNSクライアントプロトコルを自分で実装する必要があると思います。
私はあなたの質問に対する答えを持っていません(あなたが望む非同期モードで動作するDNSライブラリがあるかどうかはわかりません)そしてこれはコメントするには長すぎます。
ただし、完全なDNSハンドラーを自分で作成しなくても、非同期のものをすばやく作成できるはずです。警告、私はこれを行っていないので、私はすべて間違っている可能性があります。
Dnsjavaコードから始めて、送信側と受信側の両方のメソッドを提供する独自のリゾルバーを実装できるようにする必要があります。 SimpleResolver をチェックして、send
メソッドを見てください。このメソッドを2つのメソッドに分割できる必要があります。1つは、TCPClientまたはUDPClientのいずれかに呼び出しまで実行されるリクエストを送信する方法です(説明したように、この時点で実際のネットワーク送信を処理します。最初のスレッドで)、および受信するソケット。これは、ソケット読み取りへの応答として2番目のスレッドによって呼び出され、応答の解析を処理します。 SimpleResolverからすべてのコードをコピーする必要があるかもしれません(必要な多くのプライベートメソッドと ライセンスで許可されています )、または独自のバージョンを作成して先にロードすることもできますクラスパス内のjarされたものの、または、問題のメソッドへの道を反映し、 アクセス可能に設定 。
netty または mina のいずれかを使用して、ネットワーククライアント側をすばやく構築できます。私はドキュメントにnettyを好みます。
もしあなたがこの道を進んで、それをオープンソースにすることができる/したいのなら、私はあなたがトラブルに巻き込まれた場合に助けるために少し時間を取っておくことができます。
Linuxには非同期DNSルックアップ機能があります: http://www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html
Linuxを使用している場合は、justでそれをJNIでラップする必要があります。