달력

52024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
반응형

얼마 전 웹 크롤러를 아예 처음부터 새로 만든 적이 있다.

단일 스레드에서 작동하는 코드에서 병렬 스레드로 작동하도록 만들고, 기능 개선을 하면서 코드가 지저분해진 것도 있고, 무엇보다 코드 저장소에 안 올려놔서 노트북을 포맷하면서 코드가 날아갔기 때문이다. 으흠.


웹 크롤러라고 하면 너무 애매하기 때문에 조금 더 자세히 부연 설명을 한다.

내가 제작한 것은 어떤 블로그에 있는 모든 글을 수집하여 그 페이지에 포함된 미디어를 받아오는 크롤러다.


기존 단일 스레드 프로그램에서의 흐름을 보면 다음과 같다.


1. 모든 글의 주소를 획득.

2. 크롤링할 글의 범위를 입력

3. 해당 범위를 되돌며 글을 받아온다.

3-1. 글을 파싱하며 미디어 주소를 획득한다.

3-2. 획득한 미디어 주소로부터 미디어를 다운로드한다.


미디어가 작은 크기가 아니기 때문에 모든 글을 크롤링하는데 굉장히 많은 시간이 걸렸다.

그래서 이를 병렬 스레드로 바꾸면서 위 흐름에서 3에 해당하는 부분을 병렬로 처리했다.

그러면 다음과 같은 흐름이 된다.


1. 모든 글의 주소를 획득.

2. 크롤링할 글의 범위를 입력

3. 해당 범위에서 복수의 스레드를 생성하여 글을 받아온다.

3-1. 글을 파싱하며 미디어 주소를 획득한다.

3-2. 획득한 미디어 주소로부터 미디어를 다운로드한다.


그러자 다양한 문제가 발생했다.


1. 동시에 수 십개를 다운로드하면서 네트워크 대역폭이 이를 다 처리하지 못한다.

2. 다운로드 속도가 느려지면서 다운로드 타임아웃 때문에 불완전 다운로드.

3. 또 디스크 사용률 100%가 되면서 다운로드 속도가 더 느려짐.

4. 간혹가다 자원 공유 문제 때문에 프로그램 죽음.


원래 혼자 쓰려고 만든 매우 간단한 프로그램이라 단일 클래스로 프로그램을 설계했었다.

그렇지만 이 정도 문제가 발생하면 설계를 수정해서 코드를 작성할 필요가 있었다.

이에 따라 (마침 코드도 날아갔고) 문제점을 생각하며 새롭게 코드를 작성하였다.


- 제한 없이 다운로드하는 것이 문제가 되는 것이기 때문에 동시 다운로드 수를 제한

- 다중 스레드에서 동시에 접근하는 자원에 공유 lock 적용


동시 다운로드 수를 제한하기 위해 다운로드만을 전담하는 클래스를 만들고, 인스턴스 생성/삭제 시 인스턴스 개수를 조정할 수 있도록 하였다.

또 각각의 스레드가 동시에 접근하는 Logger 클래스를 다중 스레드에서 실행시켜도 문제가 없도록 공유 lock 을 추가하였다.


이것으로 일단 내가 경험했던 문제는 모두 해결하였다.

이같은 문제를 겪는 사람이라면 대부분 이와 비슷하게 해결하겠지만.


내가 작성했던 코드는 Bitbucket 코드 저장소에 있다.

(원래 private 으로 쓰던 거라 공유를 위한 준비는 아무것도 되어 있지 않다)


코드 및 본 글에 대한 환호/개선/비난/불만 의견은 환영합니다.


반응형
Posted by Taekhan
|