web-dev-qa-db-ja.com

Apacheを使用した分散WebクロールSpark-可能ですか?

Webマイニングに関するあるインタビューに参加したとき、興味深い質問がありました。問題は、Apache Sparkを使用してWebサイトをクロールすることは可能ですか?

Sparkの分散処理能力に対応しているので可能だと思いました。インタビューの後、私はこれを探しましたが、興味深い答えは見つかりませんでした。それはSparkで可能ですか?

14
New Man

この方法はどうですか:

アプリケーションは、クローラーの入力として一連のWebサイトURLを取得します。通常のアプリのみを実装している場合は、次のように実行できます。

  1. クロールするすべてのWebページを個別のサイトのリストに分割します。各サイトは1つのスレッドにうまく収まるほど小さいです:_for example: you have to crawl www.example.com/news from 20150301 to 20150401, split results can be: [www.example.com/news/20150301, www.example.com/news/20150302, ..., www.example.com/news/20150401]_
  2. 各ベースURL(_www.example.com/news/20150401_)を単一のスレッドに割り当てます。実際にデータフェッチが行われるのはスレッド内です。
  3. 各スレッドの結果をファイルシステムに保存します。

アプリケーションがspark 1になると、同じ手順が発生しますが、Sparkの概念:CrawlRDDをカスタマイズして同じスタッフを実行できます。

  1. 分割サイト:_def getPartitions: Array[Partition]_は分割タスクを実行するのに適した場所です。
  2. 各分割をクロールするスレッド:def compute(part: Partition, context: TaskContext): Iterator[X]は、アプリケーションのすべてのエグゼキュータに分散され、並行して実行されます。
  3. rddをHDFSに保存します。

最終的なプログラムは次のようになります。

_class CrawlPartition(rddId: Int, idx: Int, val baseURL: String) extends Partition {}

class CrawlRDD(baseURL: String, sc: SparkContext) extends RDD[X](sc, Nil) {

  override protected def getPartitions: Array[CrawlPartition] = {
    val partitions = new ArrayBuffer[CrawlPartition]
    //split baseURL to subsets and populate the partitions
    partitions.toArray
  }

  override def compute(part: Partition, context: TaskContext): Iterator[X] = {
    val p = part.asInstanceOf[CrawlPartition]
    val baseUrl = p.baseURL

    new Iterator[X] {
       var nextURL = _
       override def hasNext: Boolean = {
         //logic to find next url if has one, fill in nextURL and return true
         // else false
       }          

       override def next(): X = {
         //logic to crawl the web page nextURL and return the content in X
       }
    } 
  }
}

object Crawl {
  def main(args: Array[String]) {
    val sparkConf = new SparkConf().setAppName("Crawler")
    val sc = new SparkContext(sparkConf)
    val crdd = new CrawlRDD("baseURL", sc)
    crdd.saveAsTextFile("hdfs://path_here")
    sc.stop()
  }
}
_
6
yjshen

Sparkは、このタスクに本質的に価値を追加しません。

もちろん、分散クロールを実行できますが、優れたクロールツールはすでにこれをすぐにサポートしています。 Sparkによって提供されるRRDなどのデータ構造はここではほとんど役に立ちません。クロールジョブを起動するためだけに、YARN、Mesosなどをより少ないオーバーヘッドで直接使用できます。

確かに、あなたはcould Sparkでこれを行います。チューリング完全であるため、Sparkでワードプロセッサを実行できるのと同じように...しかし、これ以上簡単にはなりません。

はい。

オープンソースプロジェクトをチェックしてください:Sparkler(spark --crawler) https://github.com/USCDataScience/sparkler

チェックアウト Sparkler Internals フロー/パイプライン図。 (申し訳ありませんが、ここに投稿できなかったSVG画像です)

このプロジェクトは、質問が投稿された時点では利用できませんでしたが、2016年12月の時点で、非常に活発なプロジェクトの1つです。

Apache Sparkを使用してWebサイトをクロールすることは可能ですか?

次の部分は、誰かがそのような質問をする理由を理解するのに役立ち、またそれに答えるのに役立ちます。

  • Sparkフレームワークの作成者は、独創的な論文[1]で、RDDは、ストレージなど、共有状態に対して非同期のきめ細かい更新を行うアプリケーションにはあまり適していないだろうと書いています。 WebアプリケーションまたはインクリメンタルWebクローラー用のシステム
  • RDDはSparkの主要コンポーネントです。ただし、従来のマップリデュースアプリケーションを作成できます(RDDをほとんどまたはまったく乱用せずに)
  • Nutch [2]と呼ばれる広く普及している分散型Webクローラーがあります。 NutchはHadoopMap-Reduceで構築されています(実際、Hadoop Map ReduceはNutchコードベースから抽出されました)
  • Hadoop Map Reduceでいくつかのタスクを実行できる場合は、ApacheSparkを使用して実行することもできます。

[1] http://dl.acm.org/citation.cfm?id=2228301
[2] http://nutch.Apache.org/


PS:私はSparklerとコミッターの共同作成者であり、ApacheNutchのPMCです。


Sparklerを設計したときに、Solr/Luceneベースのインデックス付きストレージのプロキシであるRDDを作成しました。これにより、crawler-databse RDDが共有状態に対して非同期のきめ細かい更新を行うことができるようになりました。これがなければ、ネイティブでは不可能です。

3
Thamme Gowda

受け入れられた答えは、1つの基本的な点で間違っていると思います。実際の大規模なWeb抽出は、プルプロセスです。

これは、多くの場合、HTTPコンテンツを要求する方が、応答を作成するよりもはるかに手間のかからない作業であるためです。私は小さなプログラムを作成しました。このプログラムは、4つのCPUコアと3GB RAMで、1日1600万ページをクロールできますが、あまり最適化されていません。同様のサーバーの場合、このような負荷(〜200 1秒あたりのリクエスト数)は簡単ではなく、通常は多くの最適化レイヤーが必要です。

実際のWebサイトは、たとえば、クロールが速すぎるとキャッシュシステムを壊す可能性があります(最も人気のあるページをキャッシュに入れる代わりに、クロールのロングテールコンテンツで溢れる可能性があります)。その意味で、優れたWebスクレイパーは常にrobots.txtなどを尊重します。

分散クローラーの本当の利点は、1つのドメインのワークロードを分割することではなく、多くのドメインの作業負荷を1つの分散プロセスに分割して、1つのプロセスがシステムが通過する要求の数を自信を持って追跡できるようにすることです。

もちろん、場合によっては、あなたは悪い子になり、ルールを台無しにしたいことがあります。ただし、私の経験では、Webサイトの所有者は、DoS攻撃のように見えるものから資産を保護することを好むため、このような製品は長くは存続しません。

Golangは、ネイティブデータ型としてチャネルを持ち、プルキューを非常によくサポートしているため、Webスクレイパーの構築に非常に適しています。 HTTPプロトコルとスクレイピングは一般に遅いため、プロセスの一部として抽出パイプラインを含めることができます。これにより、データウェアハウスシステムに格納されるデータの量が削減されます。 1つをクロールできますTB 1ドル未満のリソースを使用して、GolangとGoogle Cloudを使用すると高速に実行できます(おそらくAWSとAzureでも実行できます)。

Sparkはあなたに付加価値を与えません。 wgetをクライアントとして使用すると、robots.txtが自動的に適切に尊重されるため、賢い方法です。専門的に作業している場合は、wgetへの並列ドメイン固有のプルキューが最適です。

1
Ahti Ahde

SpookyStuff というプロジェクトがあります。

Apache Sparkを利用した、Webスクレイピング/データマッシュアップ/アクセプタンスQA用のスケーラブルなクエリエンジン

それが役に立てば幸い!

1
Aito