2

ウェブクローラーを作っています。私は既に scala チュートリアルの scale-out-with-scala-and-akkaSprayのような非同期 http クライアントを試しましたが、うまく動作させることができません。今のところ、パフォーマンスは私にとって最も重要な部分ではありませんが、後でライブラリを変更せずに req/s 比率を簡単に改善したいと考えています。

ライブラリは http ヘッダーで動作できる必要があり、dns 解決でパフォーマンスの問題が発生することはありません。タスクに最適なライブラリはどれですか?

4

1 に答える 1

5

そのためにはスプレーで十分です。16 メガビット接続でこの非常に単純なコードを使用しても、1 秒あたり約 8 ページ、つまり 1 日あたり 700,000 ページを検索できます。ウィキペディアのメイン ページのすべてのリンクを取得し、それらのページをすべてロードしてから、それらのページのすべてのリンクを取得します。問題は、ウィキペディアのサーバーがおそらくクライアントごとのトラフィックを制限していることです。そのため、一度に複数のサイトにアクセスすると、速度が大幅に向上するはずです。並列コレクションを使用して速度を上げ、DNS 解決による遅延を回避します。しかし、これをアクターや先物で適切に記述し、スプレーのようなライブラリを使用すると、より高速になると思います。

import io.Source

def time[T](f: => T): T = {
  val start = System.nanoTime
  val r = f
  val end = System.nanoTime
  val time = (end - start)/1e6
  println("time = " + time +"ms")
  r
}

val domain = "https://en.wikipedia.org"
val startPage = "/wiki/Main_Page"
val linkRegex = """\"/wiki/[a-zA-Z\-_]+\"""".r


def getLinks(html: String): Set[String] =
  linkRegex.findAllMatchIn(html).map(_.toString.replace("\"", "")).toSet

def getHttp(url: String) = {
  val in = Source.fromURL(domain + url, "utf8")
  val response = in.getLines.mkString
  in.close()
  response
}

val links = getLinks(getHttp(startPage))
links.foreach(println)
println(links.size)

val allLinks = time(links.par.flatMap(link => getLinks(getHttp(link))))
println(allLinks.size)
于 2013-09-28T15:56:42.453 に答える