Обновить

Проектирование веб-краулера. Как решать System Design?

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели14K
Всего голосов 43: ↑41 и ↓2+42
Комментарии26

Комментарии 26

кратко и по делу, хорошая статья)

единое что - S3 юзать как кеш такое себе, равзе что на этапе отладки. А так можно сразу отдавать в очередь парсинга и в S3 хранить уже нужные данные (или хотя бы минифицированый документ без css и js) потому как некоторые сайты сырым текстом до 12МБ могут быть где полезной нагрузки хорошо если 100кб

Спасибо, в целом полностью согласен, хорошее замечание)

При проектировании краулеров часто забывают про нормализацию URL и content-based дедупликацию. В распределённой системе consistent hashing по доменам решает проблему дублирования работы между воркерами.

Что то я не увидел пункта про пул прокси, большой % сайтов за cloudflare , ваши ip забанят быстрее чем вы 100к страниц загрузите.

Я думаю прокси будут сильно дороже всего остального проекта для такого масштаба.

Да и 10к никто не отдаст. И следование лимитам не спасет, только слегка отсрочит.

Как извлечь - это буквально основная тут задача. Надо строить огромную толпу краулеров и гигантскую толпу прокси ими использовать. И совершенно нет смысла лимитам следовать, ддосить не надо конечно, надо оценивать время ответа и подбирать рейт соответственно.

В целом с нуля сроки совершенно нереальные.

Вообще это классическая задача и классическое решение.

Проблема выше тянет на отдельный сисдиз)

Классическая, не классическая, а было бы интересно увидеть разбор в этой статье)

Это не решение задачи. Задача решения не имеет. Вряд ли можно успеть за пять суток. Решение тут "мы не успеем, шансов ноль".

Более того, сама задача сформулирована странно. Надо хреналион страниц ? Любых ? Так я вам нагенерю :).

А вот если надо хреналион страниц с определенных ресурсов, ибо там есть нужная информация, то ограничивать их просто так глубиной обхода в 20 - это вредительство. Много вы так с какого-нибудь фейсбука напарсите ?

И вообще, сколько процентов страниц от общего надо собрать ? 10%? Или 99%? Разница в подходе огромная. В первом случае мы вообще можем длинное скипать. Во втором придется очень постараться.

Это уж не говоря о том, что делать с страницами, которые по сути 404/503, а возвращаются с кодом 200. Можете легко собрать кучу заглушек "Ваш лимит превышен" вместо реальных данных. И это совершенно обычная ситуация.

Как будете валидировать то, что получили ? Что делать с динамикой ? С страницами в тексте которых есть сообщения об ошибках.

Зачем вы вообще собираетесь помещать в очередь ссылки на сайты, которые не резолвятся в днс?

Итд итп.

Задача гораздо-гораздо обширнее того, в какую базу это сложить и какие очереди использовать.

Но все таки на собеседованиях в условную Meta вы получите ее в такой формулировке и ждать от вас будут такого решения)

С разным уровнем погруженности в разные детали*

Зависит от бекграунда интервьюера

Ну хоть не пузырьком сортировать....

Страшно далеки они от реальной жизни.

Тут не поспоришь)

Я тут пока душ принимал понял что меня сразу напрягло.

Какие 2мб ? Какие 200кб ? На типичной странице после удаления разметки, встроенной графики, скриптов итп дай бог останется 2килобайта текста.

Данных будет меньше на порядки.

Именно. Условный cloudfare и подобное положит ~80% запросов к значимым (не мусорным) сайтам. Это раз.

Также не совсем понятна идеализация облаков, особенно заграничных. Мол, раз "Безос подумал" (а он вряд ли думал), то и придумывать ничего не надо, и надо надеяться на AWS и S3, как будто они беспроблемные, оптимальные, и не существует например всяких распределенных бд и прочих infrastructure as code. Это два.

Фрибургер всем нашим

А как же точки сохранения для кролера на случай падения и рестартов, он же распределенный.

Какая-никакая админка нужна.

Можно сделать задачу попроще и ближе к реальности - репозиторий документов на 1 млд документов, есть текстовые, PDF, tiff. Нужно кролить разный контент (просто текст, текст из пдф, и OCR из тифф).

Вот тебе процессинг контента. Причем его можно делать синхронно, асинхронно, с честной очередью, общей и внутри процессоров, тот же оср можно на ллм сделать специализированной или классически и тд и тп. Можно сделать полиглотную схему на сервисах а можно в монолите (несколько инстансов каждый на свой сегмент документов).

Задно спросить - как обрабатывать документы разного размера - есть к примеру tiff, в основной массе 100 KB но пробегают до 1ГБ - их можно разбирать только однопоточно и с большим объемом памяти. Вот в реале так бывает - отдельно парсишь мелочевку в Н потоков а на крупные документы отдельный процесс в одну нитку.

Сырой контент можно класть в s3.

Распарсенный контент и метаданные в какой то базе кешировать и заодно лог обновлений создать. Для быстрого чтения потребителями без рекрола.

Хеш или чексум, версионирование.

Не люблю интервью если честно - последний раз проходил сисдизайн в Яндексе - какой то нервный пацан не в настроении попался, сбил мне настрой - не прошел хотя тема простая была.Вот по этой теме я бы тому интервьюверу с Яндекса мозги бы накрутил. Остальные кстати нормально себя вели.

Это проблема вообще формата единого найма в корпорациях, что за частую результат чисто от настроения интервьюера зависит и в целом от его душности.

В этом плане когда тебя ребята из команды куда смотрят собесят намного лучше подход

подтверждаю что найм это процесс случайный - совпадение фантазии нанимателя и нанимаемого.

У меня была мысль на эту тему, что лучше делать и очередь для доменов, и очередь URL для каждого домена. Обходим все домены, берем с каждого по 1 URL, чтобы не отправлять много запросов подряд к одному. Также если домен недоступен, можно его пометить и не брать URL из его очереди.

краулер хэширует HTML и кладёт хэш в ContentHash, а перед отправкой страницы в parsing-очередь проверяем, не видели ли мы уже такой хэш

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

Я бы не рассматривал кролинг веб - это сложная задача на самом деле.

Выше написал коммент что кролинг и индексирование документов из источника попроще (репозиторий документов) может быть уже нетривиальным.

Веб страница может получать обновление при вызове, типа timestamp где то и все, приехали - текст отличается. Или каптча или версия кода или айди запроса или еще какое то одноразовое и мусорное отличие.

То есть нужно извлекать полезный контент осмысленно по темплейтам по старинке или моделями специализированными (мелкими), с определенной онтологией и таксидермией того что же мы извлекаем со страницы.

Кролинг веба это сложно. Хуже чем кролинг SharePoint с учетом security (то еще дерьмо). В веб нет событий по которым можно понять что произошли изменения, сложно сделать обход, сложно сделать кролпоинт (точку сохранения) - она может быть огромной, сложно согласовать обход для тысяч доменов - то есть сразу шардирование, проверка уникальности, очередность для парсинга разного контента, там кстати вероятностные структуры типа CMS локальные или на основе редис могут быть полезны, а Блум может пригодиться если нам нужен твердый нет - к примеру не ходить куда то лишний раз - в кролере это может быть что то типа диспетчера который прикидывает какой узел точно не обрабатывает указанный домен к примеру и не шлет в этот узел запрос на обработку этого домена. При желании если прям нужно - Блум засунуть не проблема в дизайн

и это я забыл еще одну тему - поддержку удаления в источнике данных - веб как раз случай когда событий нет на удаление и это требует обратного кролинга и сравнение а жив ли ресурс в источнике? Рекролить поверх с нуля? У меня это была одна из больших головных болей - поддержка консистентности двусторонняя

Понятно, что статья – рассуждение об абстрактном краулере в вакууме, но все же есть несколько замечаний по тексту.

для S3 это вообще не проблема: оно ровно для такого и сделано, масштабируется бесконечно, а за надёжность хранения уже подумал Безос

Вряд ли что-то там думал Безос. S3 – это протокол объектного хранилища, и реализаций у него множество: Minio, CephFS, AWS Cloud S3 и т.д. У каждой реализации свои особенности, потому без указания конкретной реализации рассуждения выглядят немного сомнительно.

топовые network-optimized инстансы AWS тянут порядка 400 Гбит/с;

400гбит это ведь максимум на вход, а с какой скоростью будут отдавать сканируемые хосты, если они находятся в другом ДЦ, городе, стране? Реальная скорость будет намного ниже, и это надо тоже учитывать.

при первом обращении к домену тянем его robots.txt

Вообще при первом обращении надо еще парсить sitemap.xml и получать список конечных урлов сразу.

По заголовку Content-Length слишком большие файлы можно просто скипать.

В случае с transfer-encoding: chunked / content-encoding: gzip и т.п. такое уже не пройдет. Размер заранее не узнать.

вводим максимальную глубину обхода (Depth, например 20)

К этому у меня самый большой вопрос. Если наша общая задача – просканировать весь интернет, тогда кажется более разумным сканировать по доменам, а не урлам. Сканирование по доменам дает сразу несколько плюсов: у нас вся инфа по домену (robots, sitemap), мы обходим страницы в ширину, имеем set посещенных страниц, и петли находим мгновенно. В случае отказа хоста домена (временный сбой или сгорел ДЦ), мы не делаем ненужные попытки сканирования, а можем вернуться через какое-то время позже. В общем, имеем бОльшую локальность и управляемость данных, нежели при сканировании по-странично.

Можно несколько вопросов?

1. Почему сообщение с ретраями просто не класть в туже очередь новым сообщением, поменяв таймштамп и счетчик ретраев? По исчерапнию ретраев, данные нужно складывать в лог с ошибкой, последним таймстамом и счетчиком ретраев.

2. Для корректной работы ведь нужна нормализация и дедупликация URL-ов, а возможно - и контента?

3. S3 зачем? Это оверинжиенеринг для такой задачи, очереди хватит за глаза, так как у нас текст страницы, который врядли перевалит условно разрешенный 1мб - в любом случае это можно залогировать. Да, сообщения стараются минимизировать, но, ИМХО в данной задаче в этом нет необходимости, KAFKA и даже RMQ вполне себя хорошо чувствуют и при 20мб сообщениях.

Я очень много делал таких штук, и реально RMQ + любая БД выше крыши для таких задач, все остальное решается масштабированием. Оно еще и отказоустойчивое будет.

Это задачка для позиции на которой никогда в жизни не придется потом создавать вебкраулеры

Все так

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации