Współbieżny web crawler

0

Witam, zastanawiam si,e nad pewnym wyzwniem, mianowicie mam do napisania web crawler - aplikacja pobiera linki z danej strony, później filtruje te które są z tej domeny (np. jak pobiera linki z last.fm to wchodzi dalej tylko na linki z last.fm) itd.
Zastanawiam się jakich narzędzi do obslugi wielowątkowośći uzyc. Na początku myślałem o ForkJoin ale to kiepski pomysł (deadlocki...) raczej
Może użyć puli wątków roboczych i kolejki blokującej?
@Shalom, jak Ty byś to zrobił
Edit:
To aplikacja konsolowa :)

0

offtop on
ZIO - jak uda Ci się zrozumieć jak uruchomić w tym równoległe wykonywanie kodu to masz u mnie piwo.
Pisałem Link Checkera na 4 sposobów, tylko dla Future i scalaz.concurrent.Task udało mi się uruchomić kod równoległe. ZIO to dla mnie jakaś zagadka
offtor off

Co jest złego w zwykłym CompletableFuture w Javie że nie chcesz tego użyć?

0

To nie jest specjalnie trudne: na każdej stronie masz X linków do sprawdzenia, każdy z tych linków wstawiasz do tabeli w bazie danych, następnie poszczególnym wątkom przydzielasz po kolei ich sprawdzanie i pobieranie HTML strony.

Masz więc jeden wątek - koordynator który skanuje tabelę z linkami do wykonania i przydziela po kolei wątkom, oraz pozostałe wątki do pobierania HTML i dodawania nowych, nie sprawdzonych linków do tabeli linków.

Sprawa tylko odpowiedniej koordynacji, każdy z linków może mieć status określający czy nie był jeszcze sprawdzamy, czy jest w trakcie pobierania przez jakiś wątek, oraz czy już jest gotowy.

Glówny wątek pobiera linki z tabeli ze statusem "nie sprawdzone", przydziela zadanie sprawdzenia wątkowi który jest wolny, zmeinia status na "w trakcie" i tak sobie działa w pętli przy każdym obrocie śpiąc sobie np. 1/10 sekundy co by nie męczyć procesora.

Wątek pobierający link kiedy skończy, zmienia status linku na "pobrane" i zapisuje do bazy HTML, oraz co już wyżej wspomniałem - uzupełnia tabelę linków o nowe linki, oraz zmienia swój status na gotowy do pobrania kolejnego linku.

Tak bym to mniej więcej zrobił, dwie klasy implementujące Runnable albo rozszerzające klasę Thread, to wystarczy - chociaż dawno już w Javie nic nie robiłem, więc może jakieś nowe klasy się pojawiły.

Tutaj większy problem polega na tym, że możesz dostać bana za abuse, dlatego coś takiego ma sens kiedy skanujesz kilka sajtów na raz, jeżeli jeden to spokojnie jeden wątek wystarczy, bo i tak nie ma co szaleć i złapać blokadę za DoS / DDoS.

Ja kiedy robię clawlera to nadaję ostre limity na ilość wywołań na sek (zazwyczaj 0.2 - 0.3) / minutę / godzinę / dobę.

0

Ja myśle ż CompletableFuture z timeoutem oraz jakimś sporym ForkJoinPoolem na pierwszy ogień starczy. Co innego jak chcesz to robić równolegle, wtedy w ogóle zrobiłbym bardziej złożoną architekturę:

  • osobny serwis A do pobierania źródła strony i wrzucania na kolejkę
  • osobny serwis B do pobierania źródła z kolejki i parsowania z niego linków i wrzucania tychże na kolejkę z której czyta jakiś cache C
  • osobny serwis C który filtruje linki już odwiedzone i wrzuca na kolejkę z której czyta A

Zauważ że A ogranicza I/O więc można ich dostawić więcej, a B ogranicza CPU więc można ich mieć mniej niż A (szczególnie że jedno źródło do sparsowania to wiele linków do odwiedzenia), tak żeby jakoś równo szły. C generalnie będzie turbo szybki i pewnie starczyłby jeden, ale można też dać tam jakiegoś Hazelcasta/Redisa jak chcesz to też zeskalować.

1

Trochę taka akademicko godka (albo plebiscyt kto zna więcej technologii ;) ), bo nie znamy żadnych wymagań odnośnie tego systemu. Na początku lecisz po prostu z kolejka urli do obsłużenia i masz jeden wątek, który pobiera sobie urla i dociąga stronę, potem filtruje etc. Oczywiście must have jest implementacja jakiegoś rejestru stron wcześniej odwiedzonych, żeby nie wpaść w cykl - w końcu chodzisz po grafie, co nie? Jak to zaimplementować? MySQL + ExecutorService.

0

Sory wszyscy że was rozczarowałem, ale chyba źle na początku zrozumiałem co trzeba zrobić, ino wystarczy tylko że web crawler odwiedzi linki z głównej strony, nie musi to byc rekursja :D
Choć wątek ciekawy :D

No i zgodze sie z z @jarekr000000 używanie SQL do tego jest hmm... dosyć dziwnym pomysłem jak dla mnie

0

@scibi92: dlaczego dziwnym? Wiesz ile serwisów o niebotycznej skali stoi na relacyjnej bazie danych? Nie twierdze, ze SQL rozwiązuje wszystkie problemy, ale bez jaj - Ty chcesz zrobić crawlera, a nie Netfliksa

2
Charles_Ray napisał(a):

@scibi92: dlaczego dziwnym? Wiesz ile serwisów o niebotycznej skali stoi na relacyjnej bazie danych? Nie twierdze, ze SQL rozwiązuje wszystkie problemy, ale bez jaj - Ty chcesz zrobić crawlera, a nie Netfliksa

Może @scibi92 nie che zrobić

https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition

bo ten projekt juz jest - i wystarczy.

0

Ale Kotlina z Arrow już jak najbardziej xD bez kitu, sqlowa baza danych to jest taki overengineering żeby trzymać sobie stan (zakładając, ze jest potrzebna persystencja)?

1

Myśle, że to miała być próba wycieczki osobistej.... ale nie wpadłem na tego ArrowKt, to akurat może być dobry pomysł, trzeba by sprawdzić :-)
(chociaż to porada pomocna na poziomie, użyj prywatnych metod).

0

@Charles_Ray:
Żeby wyjaśnic sytuacje
1)Niczyim psychofanem nie jestem
2) Może @Charles_Ray nie widziałeś że dodałem w 1 poście -> to ma być jednorazowy konsolowy webcrawler, tzn raz puszczam i później to gdzies zapisuje i tyle. Dlatego IMO SQL jest to overkillem. Z pewnością trakowanite bazy danych SQL do trzymania tylko pary klucz-wartość jest dla mnie dziwnym pomysłem, skoro można to trzymać albo w pamięci (jeśli nie ma potrzeby persystencji) albo w jakimś Redisie.
3)

Ale Kotlina z Arrow już jak najbardziej

Akurat wyszło dosyc zabawnie że mam coś do zrobienia co jest bardzo podobne do tego co chciałem wcześniej zrobić sam dla siebie just for fun. Arrow to biblioteka do programowania funkcyjnego ktorego chciałem się nauczyć,a jeszcze funcyjnie operacji I/O czy obsługi wątków nie robiłem. To jest chęć poznania nowego podejścia i co do zasady myślałem że to powinno się chwalić.
A swoją drogą ciekawe czemu jeszcze nikt nie nazwał mnie np. psychofanem Uncla Boba :)

1
Charles_Ray napisał(a):

Ale Kotlina z Arrow już jak najbardziej xD bez kitu, sqlowa baza danych to jest taki overengineering żeby trzymać sobie stan (zakładając, ze jest potrzebna persystencja)?

Arrow służy między innymi do obsługi asynchroniczności

0

Spoko :) z ciekawości - co jest używane pod spodem?

EDIT: ok widzę, że to śmiga na korutynach

1 użytkowników online, w tym zalogowanych: 0, gości: 1