1

私はSunOSに取り組んでいます(これは少し頭がおかしいです)。以下は、上記の Solaris マシンのディスク スループットです。

bash-3.00$ iostat -d 1 10
    sd0           sd1           sd2           sd3
kps tps serv  kps tps serv  kps tps serv  kps tps serv
  0   0    0  551  16    8  553  16    8  554  16    8
  0   0    0  701  11   25    0   0    0  1148  17   33
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0

問題文

私は周りにいて1000 files、各ファイルのサイズは1GB. Stringそして、これらすべて1000 filesと、その特定の文字列を含むファイルを見つける必要があります。私は作業を行ってHadoop File Systemおり、それら1000 filesはすべて Hadoop ファイル システムにあります。

すべてフォルダの1000 filesreal-timeにあるので、以下のようにすると、すべての1000 files. そして、特定の文字列を含むファイルを見つける必要があります。

bash-3.00$ hadoop fs -ls /apps/technology/b_dps/real-time

したがって、上記の問題ステートメントでは、特定の文字列を含むすべてのファイルを見つける以下のコマンドを使用しています-

hadoop fs -ls /apps/technology/b_dps/real-time | awk '{print $8}' | while read f; do hadoop fs -cat $f | grep cec7051a1380a47a4497a107fecb84c1 >/dev/null && echo $f; done

したがって、上記の場合、この文字列cec7051a1380a47a4497a107fecb84c1を含むすべてのファイルが検索されます。そして、それは私にとってはうまく機能しており、特定の文字列を含むファイル名を取得できます。

私の質問は-

しかし、上記のコマンドの問題は、非常に遅いことです。では、上記のコマンドを実行する方法parallelize、または上記のコマンドを作成してファイルをより高速に検索する方法はありますか?

任意の提案をいただければ幸いです。

4

3 に答える 3

1

grep クラスからヒントを得ることができます。これは、example フォルダー内のディストリビューションに付属しています。

./bin/hadoop jar hadoop-mapred-examples-0.22.0.jar grep 入力 出力 正規表現

このクラスの実装に関するソースの詳細については、ディレクトリに移動できます。ディストリビューションに付属の「src\examples\org\apache\hadoop\examples」

したがって、メインクラスでこれを行うことができます:

 Job searchjob = new Job(conf);    
 FileInputFormat.setInputPaths("job Name", "input direcotory in hdfs");
      searchjob.setMapperClass(SearchMapper.class);    
      searchjob.setCombinerClass(LongSumReducer.class);
      searchjob.setReducerClass(LongSumReducer.class);

SearchMapper.class でこれを行うことができます。

   public void map(K key, Text value,
                      OutputCollector<Text, LongWritable> output,
                      Reporter reporter)
        throws IOException {
        String text = value.toString();
        Matcher matcher = pattern.matcher(text);
        if(matcher.find()) {
          output.collect(key,value);
}
于 2012-07-31T16:59:37.530 に答える
1

1000 個のファイルがある場合、粒度の細かい並列化手法を使用する理由はありますか? ファイル内で作業を分割するのではなく、単に xargs や gnu parallel を使用して、作業をファイルに分割してみませんか?

また、リテラル文字列 (正規表現ではない) を grep しているように見えます。-F grep フラグを使用して文字列リテラルを検索できます。これにより、grep の実装/最適化方法によっては速度が向上する場合があります。

特に mapReduce を使用したことはないので、この投稿は適切である場合とそうでない場合があります。

于 2012-08-01T02:57:32.773 に答える
1

必要に応じて、単純な MapReduce ジョブを作成してこれを実現できます。ただし、実際にはレデューサーは必要ないため、レデューサーの数はゼロに設定されます。このようにして、MapReduce とチャンクの並列処理能力を利用して、シリアル grep よりもはるかに高速にファイルを処理できます。

必要な文字列を検索するように構成できるマッパーをセットアップするだけです。おそらく、TextInputFormat を使用してファイルを読み込み、行を分割して、検索している値を確認します。次に、一致する Mapper の現在の入力ファイルの名前を書き出すことができます。

アップデート:

これを行うには、標準の単語カウントの例から始めることができます: http://wiki.apache.org/hadoop/WordCount。Reducer を削除して、Mapper を変更するだけです。行が値に Text オブジェクトとして含まれている場合、入力を一度に 1 行読み取ります。データの形式はわかりませんが、テキストを文字列に変換し、その値に対して .contains("") をハードコーディングして、検索している文字列を見つけることもできます(速度やベストプラクティスではなく、単純化のため) )。ヒットしたときにマッパーが処理していたファイルを調べてから、ファイル名を書き出すだけです。

于 2012-07-31T02:57:48.533 に答える