Тика Парсер тормозит StormCrawler - PullRequest
2 голосов
/ 09 марта 2019

У меня довольно обычная задача - иметь несколько тысяч веб-сайтов и разбирать как можно больше (адекватным образом, конечно).

Во-первых, я настроил конфигурацию, похожую на штормовую драку., используя парсер JSoup.Производительность была довольно хорошей, очень стабильной, около 8 тысяч загрузок в минуту.

Тогда я хотел добавить возможность разбора PDF / doc / и т.д.Поэтому я добавил парсер Tika для разбора не-HTML документов.Но я вижу такие метрики: enter image description here

Так что иногда бывают хорошие минуты, иногда они падают до сотен в минуту.Когда я удаляю записи потока Тика - все возвращается к нормальной жизниТаким образом, вопрос в целом, как найти причину такого поведения, является узким местом.Может быть, я пропускаю некоторые настройки?

Вот что я вижу в топологии сканера в Storm UI: enter image description here

es-injector.flux:

name: "injector"

includes:
- resource: true
  file: "/crawler-default.yaml"
  override: false

- resource: false
  file: "crawler-custom-conf.yaml"
  override: true

- resource: false
  file: "es-conf.yaml"
  override: true

spouts:
  - id: "spout"
    className: "com.digitalpebble.stormcrawler.spout.FileSpout"
    parallelism: 1
    constructorArgs:
      - "."
      - "feeds.txt"
      - true

bolts:
  - id: "status"
    className: "com.digitalpebble.stormcrawler.elasticsearch.persistence.StatusUpdaterBol    t"
    parallelism: 1

streams:
  - from: "spout"
    to: "status"
    grouping:
      type: CUSTOM
      customClass:
        className:    "com.digitalpebble.stormcrawler.util.URLStreamGrouping"
        constructorArgs:
          - "byHost"
      streamId: "status"

es-crawler.flux:

name: "crawler"

includes:
- resource: true
  file: "/crawler-default.yaml"
  override: false

- resource: false
  file: "crawler-custom-conf.yaml"
  override: true

- resource: false
  file: "es-conf.yaml"
  override: true

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

bolts:
  - id: "partitioner"
    className:    "com.digitalpebble.stormcrawler.bolt.URLPartitionerBolt"
    parallelism: 1

  - id: "fetcher"
    className: "com.digitalpebble.stormcrawler.bolt.FetcherBolt"
    parallelism: 1

  - id: "sitemap"
    className: "com.digitalpebble.stormcrawler.bolt.SiteMapParserBolt"
    parallelism: 1

  - id: "parse"
    className: "com.digitalpebble.stormcrawler.bolt.JSoupParserBolt"
    parallelism: 5

  - id: "index"
    className:    "com.digitalpebble.stormcrawler.elasticsearch.bolt.IndexerBolt"
    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

  - id: "redirection_bolt"
    className: "com.digitalpebble.stormcrawler.tika.RedirectionBolt"
    parallelism: 1

  - id: "parser_bolt"
    className: "com.digitalpebble.stormcrawler.tika.ParserBolt"
    parallelism: 1

streams:
  - from: "spout"
    to: "partitioner"
    grouping:
      type: SHUFFLE

  - from: "spout"
    to: "status_metrics"
    grouping:
      type: SHUFFLE     

  - from: "partitioner"
    to: "fetcher"
    grouping:
      type: FIELDS
      args: ["key"]

  - from: "fetcher"
    to: "sitemap"
    grouping:
      type: LOCAL_OR_SHUFFLE

  - from: "sitemap"
    to: "parse"
    grouping:
      type: LOCAL_OR_SHUFFLE

  # This is not needed as long as redirect_bolt is sending html content to index?
  # - from: "parse"
  #   to: "index"
  #   grouping:
  #     type: LOCAL_OR_SHUFFLE

  - from: "fetcher"
    to: "status"
    grouping:
      type: FIELDS
      args: ["url"]
      streamId: "status"

  - from: "sitemap"
    to: "status"
    grouping:
      type: FIELDS
      args: ["url"]
      streamId: "status"

  - from: "parse"
    to: "status"
    grouping:
      type: FIELDS
      args: ["url"]
      streamId: "status"

  - from: "index"
    to: "status"
    grouping:
      type: FIELDS
      args: ["url"]
      streamId: "status"

  - from: "parse"
    to: "redirection_bolt"
    grouping:
      type: LOCAL_OR_SHUFFLE

  - from: "redirection_bolt"
    to: "parser_bolt"
    grouping:
      type: LOCAL_OR_SHUFFLE
      streamId: "tika"

  - from: "redirection_bolt"
    to: "index"
    grouping:
      type: LOCAL_OR_SHUFFLE

  - from: "parser_bolt"
    to: "index"
    grouping:
      type: LOCAL_OR_SHUFFLE

Обновление: Я обнаружил, что я получаю ошибки «Недостаточно памяти» в working.log, даже если я установил работников.heap.size до 4 ГБ, рабочий процесс повышается до 10-15 ГБ ..

Обновление 2: После ограниченного использования памяти я не вижу ошибок OutOfMemory, но производительность, если она очень низкая.enter image description here enter image description here

Без Тики - я вижу 15 тыс. Загрузок в минуту.С Tika - это все после высоких тактов, только сотни в минуту.

И я вижу это в рабочем журнале: https://paste.ubuntu.com/p/WKBTBf8HMV/

Загрузка ЦП очень высока, но ничего в журнале.

Ответы [ 2 ]

1 голос
/ 09 марта 2019

Как видно из статистики пользовательского интерфейса, болт парсера Tika является узким местом: его емкость составляет 1,6 (значение> 1 означает, что он не может обработать входные данные достаточно быстро).Это должно улучшиться, если вы дадите ему тот же параллелизм, что и синтаксический анализатор JSOUP, то есть 4 или более.

0 голосов
/ 30 апреля 2019

Поздний ответ, но может быть полезным для других.

Что происходит с использованием Tika в открытых обходах, так это то, что парсер Tika получает все, что не обрабатывал болт JSOUPParser: почтовые индексы, изображения, видео и т. Д.Обычно эти URL-адреса имеют тенденцию быть очень тяжелыми и медленными для обработки, и входящие кортежи быстро сохраняются во внутренней очереди, пока память не взорвется.

Я только что зафиксировал Установить белый список mimetype для Tika Parser # 712, который позволяет определить набор регулярных выражений, которые будут опробованы в типе содержимого документа.если есть совпадение, документ обрабатывается, если нет, кортеж отправляется в поток STATUS как ошибка.

Белый список можно настроить следующим образом:

parser.mimetype.whitelist:
 - application/.+word.*
 - application/.+excel.*
 - application/.+powerpoint.*
 - application/.*pdf.*

Это должно сделать вашу топологию намного быстрее и стабильнее.Дайте мне знать, как это происходит.

...