4

この質問の文脈は、私が書いた豚のスクリプトでmaxmind Java APIを使用しようとしているということです...ただし、質問に答えるためにどちらかについて知る必要はないと思います。

maxmind API には、GeoIP.dat というファイルへのパスを必要とするコンストラクターがあります。このファイルは、必要な情報を含むコンマ区切りのファイルです。

API を含む jar ファイルと、クラスをインスタンス化して使用するラッピング クラスがあります。私の考えは、GeoIP.dat ファイルを jar にパッケージ化してから、jar ファイル内のリソースとしてアクセスすることです。問題は、コンストラクターが使用できるパスを構築する方法がわからないことです。

API を見ると、次のようにファイルが読み込まれます。

public LookupService(String databaseFile) throws IOException {
    this(new File(databaseFile));
}


public LookupService(File databaseFile) throws IOException {
    this.databaseFile = databaseFile;
    this.file = new RandomAccessFile(databaseFile, "r");
    init();
}

必要に応じてAPI自体を編集してこの機能を実現することを嫌うわけではないので、それを貼り付けるだけですが、機能自体をどのように複製できるかわかりません。理想的には、ファイル形式で取得したいと思いますが、そうしないと、API を編集するのが非常に面倒になります。

これは可能ですか?

4

6 に答える 6

2

試す:

new File(MyWrappingClass.class.getResource(<resource>).toURI())
于 2011-02-10T16:29:38.080 に答える
2

これは私にとってはうまくいきます。

GeoLiteCity.dat を含むパッケージ org.foo.bar.util があるとします。

URL fileURL = this.getClass().getResource("org/foo/bar/util/GeoLiteCity.dat");
File geoIPData = new File(fileURL.toURI());
LookupService cl = new LookupService(geoIPData, LookupService.GEOIP_MEMORY_CACHE );
于 2012-06-11T00:25:35.320 に答える
2

推奨される方法の 1 つは、jar にバンドルするのではなく、分散キャッシュを使用することです。

GeoIP.dat を圧縮して、hdfs://host:port/path/GeoIP.dat.zip にコピーする場合。次に、これらのオプションを Pig コマンドに追加します。

pig ...
  -Dmapred.cache.archives=hdfs://host:port/path/GeoIP.dat.zip#GeoIP.dat 
  -Dmapred.create.symlink=yes
...

ファイルは各ノードのタスクに対してローカルに存在するため、LookupService lookupService = new LookupService("./GeoIP.dat");UDF で動作するはずです。

于 2011-02-11T06:06:34.653 に答える
2

データを一時ファイルにダンプし、一時ファイルをそれにフィードします。

File tmpFile = File.createTempFile("XX", "dat");
tmpFile.deleteOnExit();

InputStream is = MyClass.class.getResourceAsStream("/path/in/jar/XX.dat");
OutputStream os = new FileOutputStream(tmpFile)

read from is, write to os, close
于 2011-02-10T16:31:43.370 に答える
1

メソッドを使用してclassloader.getResource(...)、クラスパスでファイル ルックアップを実行します。これにより、JAR ファイルからプルされます。

これは、既存のコードを変更して読み込みをオーバーライドする必要があることを意味します。その方法の詳細は、既存のコードと環境に大きく依存します。場合によっては、サブクラスをサブクラス化し、サブクラスをフレームワークに登録するとうまくいくことがあります。それ以外の場合は、クラスパスに沿ってクラスをロードする順序を決定し、同じ署名のクラスをクラスパスの「前」に配置する必要がある場合があります。

于 2011-02-10T16:28:19.850 に答える
1

maxmind geoIP の使用方法は次のとおりです。

ファイルをGeoIPCity.datクラウドに配置し、プロセスを起動するときにクラウドの場所を引数として使用します。ファイルを取得しGeoIPCity.dataて新しいファイルを作成するコードLookupServiceは次のとおりです。

if (DistributedCache.getLocalCacheFiles(context.getConfiguration()) != null) {
    List<Path> localFiles = Utility.arrayToList(DistributedCache.getLocalCacheFiles(context.getConfiguration()));
    for (Path localFile : localFiles) {
        if ((localFile.getName() != null) && (localFile.getName().equalsIgnoreCase("GeoIPCity.dat"))) {
            m_geoipLookupService = new LookupService(new File(localFile.toUri().getPath()));
        }
    }
}

これは、プロセスを実行するために使用するコマンドの短縮版です。

$HADOOP_HOME/bin/hadoop jar /usr/lib/COMPANY/analytics/libjars/MyJar.jar -files hdfs://PDHadoop1.corp.COMPANY.com:54310/data/geoip/GeoIPCity.dat -libjars /usr/lib/COMPANY/analytics/libjars/geoiplookup.jar

MindMax コンポーネントを実行するための重要なコンポーネントは、-files-libjarsです。これらはGenericOptionsParserの一般的なオプションです。

-files <comma separated list of files> specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars> specify comma separated jar files to include in the classpath.

GenericOptionsParserプロジェクトのどこにも参照が見つからないため、Hadoop は を使用していると想定しています。:)

GeoIPCity.datcould に を配置し、-files引数を使用して指定すると、ローカル キャッシュに配置され、マッパーがsetup関数で取得できるようになります。必須ではありませんが、setupマッパーごとに 1 回だけ実行する必要があるため、配置するのに最適な場所です。次に、-libjars引数を使用して geoiplookup.jar (または自分で呼び出したもの) を指定すると、それを使用できるようになります。geoiplookup.jar はクラウドに配置しません。Hadoop が必要に応じて jar を配布するという前提で進めています。

すべてが理にかなっていることを願っています。私は hadoop/mapreduce にかなり慣れてきましたが、プロジェクトで maxmind geoip コンポーネントを使用する部分を書いていませんでした。そのため、ここにある説明を行うのに十分なほどよく理解するために、少し掘り下げる必要がありました。

編集:-filesおよびの追加説明-libjars -files files 引数は、Hadoop 分散キャッシュを介してファイルを配布するために使用されます。上記の例では、Hadoop 分散キャッシュを介して Max Mind geo-ip データ ファイルを配布しています。ユーザーの IP アドレスを適切な国、地域、都市、タイムゾーンにマップするには、Max Mind geo-ip データ ファイルにアクセスする必要があります。API では、データ ファイルがローカルに存在する必要がありますが、これは分散処理環境では実現できません (クラスター内のどのノードがデータを処理するかは保証されません)。適切なデータを処理ノードに分散するために、Hadoop Distributed Cache インフラストラクチャを使用します。GenericOptionsParser と ToolRunner は、–file 引数を使用して自動的にこれを容易にします。配布するファイルは、クラウド (HDFS) で利用できる必要があることに注意してください。-libjars –libjars は、map-reduce ジョブに必要な追加の依存関係を配布するために使用されます。データ ファイルと同様に、依存ライブラリも、ジョブが実行されるクラスター内のノードにコピーする必要があります。GenericOptionsParser と ToolRunner は、–libjars 引数を使用してこれを自動的に促進します。

于 2011-02-10T20:49:16.027 に答える