Stormcrawler缓慢,具有高延迟,可爬行300个域

时间:2018-06-20 14:34:30

标签: elasticsearch web-crawler apache-storm stormcrawler

自大约3个月以来,我目前正在努力解决此问题。爬网程序似乎每10分钟获取一次页面,但在这之间似乎什么也没做。总体来说吞吐量很慢。我正在并行爬网300个域。这应该使大约30页/秒,并具有10秒的爬网延迟。目前约为每秒2页。

拓扑在具有以下条件的PC上运行

  • 8GB内存
  • 普通硬盘
  • Core Duo CPU
  • Ubuntu 16.04

Elasticsearch已安装在具有相同规格的另一台计算机上。

在这里您可以从Grafana仪表板中查看指标

The Grafana Dashboard

它们也反映在Storm UI中看到的流程延迟中:

Storm UI

我当前的Stormcrawler架构是:

spouts:
  - id: "spout"
    className: "com.digitalpebble.stormcrawler.elasticsearch.persistence.AggregationSpout"
    parallelism: 25

bolts:
  - id: "partitioner"
    className: "com.digitalpebble.stormcrawler.bolt.URLPartitionerBolt"
    parallelism: 1
  - id: "fetcher"
    className: "com.digitalpebble.stormcrawler.bolt.FetcherBolt"
    parallelism: 6
  - id: "sitemap"
    className: "com.digitalpebble.stormcrawler.bolt.SiteMapParserBolt"
    parallelism: 1
  - id: "parse"
    className: "com.digitalpebble.stormcrawler.bolt.JSoupParserBolt"
    parallelism: 1
  - id: "index"
    className: "de.hpi.bpStormcrawler.BPIndexerBolt"
    parallelism: 1
  - id: "status"
    className: "com.digitalpebble.stormcrawler.elasticsearch.persistence.StatusUpdaterBolt"
    parallelism: 4
  - id: "status_metrics"
    className: "com.digitalpebble.stormcrawler.elasticsearch.metrics.StatusMetricsBolt"
    parallelism: 1

具有配置(此处是最相关的部分):

config:
  topology.workers: 1
  topology.message.timeout.secs: 300
  topology.max.spout.pending: 100
  topology.debug: false

  fetcher.threads.number: 50

  worker.heap.memory.mb: 2049
  partition.url.mode: byDomain

  fetcher.server.delay: 10.0

,这里是风暴配置(也只是相关部分):

nimbus.childopts: "-Xmx1024m -Djava.net.preferIPv4Stack=true"

ui.childopts: "-Xmx768m -Djava.net.preferIPv4Stack=true"

supervisor.childopts: "-Djava.net.preferIPv4Stack=true"

worker.childopts: "-Xmx1500m -Djava.net.preferIPv4Stack=true"

您知道可能是什么问题吗?还是仅仅是硬件问题?

我已经尝试过的东西

  • 将fetcher.server.delay增大到一个较低且不变的值
  • 减少并增加获取程序线程的数量
  • 尝试并行处理
  • 计算是否为网络带宽。带宽为400mbit / s,平均页面大小为0.5MB,则为15MB / s,即为120mbit / s,这也不是问题
  • 增加了工人数量

您还有其他需要检查的想法或可以解释读取缓慢的原因吗?也许也只是速度较慢的硬件?还是瓶颈是Elasticsearch?

非常感谢您

编辑:

我将拓扑更改为两个工作器,并再次出现错误

2018-07-03 17:18:46.326 c.d.s.e.p.AggregationSpout Thread-33-spout-executor[26 26] [INFO] [spout #12]  Populating buffer with nextFetchDate <= 2018-06-21T17:52:42+02:00
2018-07-03 17:18:46.327 c.d.s.e.p.AggregationSpout I/O dispatcher 26 [ERROR] Exception with ES query
java.io.IOException: Unable to parse response body for Response{requestLine=POST /status/status/_search?typed_keys=true&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&preference=_shards%3A12&search_type=query_then_fetch&batched_reduce_size=512 HTTP/1.1, host=http://ts5565.byod.hpi.de:9200, response=HTTP/1.1 200 OK}
	at org.elasticsearch.client.RestHighLevelClient$1.onSuccess(RestHighLevelClient.java:548) [stormjar.jar:?]
	at org.elasticsearch.client.RestClient$FailureTrackingResponseListener.onSuccess(RestClient.java:600) [stormjar.jar:?]
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:355) [stormjar.jar:?]
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:346) [stormjar.jar:?]
	at org.apache.http.concurrent.BasicFuture.completed(BasicFuture.java:119) [stormjar.jar:?]
	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:177) [stormjar.jar:?]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.processResponse(HttpAsyncRequestExecutor.java:436) [stormjar.jar:?]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.inputReady(HttpAsyncRequestExecutor.java:326) [stormjar.jar:?]
	at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:265) [stormjar.jar:?]
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81) [stormjar.jar:?]
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) [stormjar.jar:?]
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588) [stormjar.jar:?]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
Caused by: java.lang.NullPointerException

虽然抓取过程似乎更加平衡,但仍然无法获取很多链接

enter image description here

在运行拓扑几周后,延迟也大大增加了

enter image description here

2 个答案:

答案 0 :(得分:2)

很抱歉,您刚刚从假期回来了。

从该图判断,该工作器重新启动,这使我认为某些东西正在阻止或崩溃拓扑。过了一会儿什么都没发生后,工作进程重新启动,它处理了一些URL,问题再次发生。

您是否检查了日志中的错误消息?日志中是否有内存转储?您可以隔离导致问题的网址吗?

答案 1 :(得分:2)

当您没有{em> all (自定义)螺栓中的所有元组都ack()fail()时,就会发生这种情况。 另外,从中间螺栓发射时,请确保将新元组正确锚定到先前的元组。 有关说明,请参见this SO answer

我在安装ES时遇到了同样的问题。我最初认为这与ES Spout的nextFetchDate逻辑有关,但是在禁用我的自定义螺栓后,此问题已解决。因此,我发现我错过了某个地方的ack()元组。 这导致未确认的元组在拓扑中丢失,然后在10分钟/ 600秒后重新发射。

尽管我没有找到10分钟重播超时的定义位置,因为将风暴重播机制通过以下方式设置为5分钟: topology.message.timeout.secs: 300