Crawler에 대한 추가 생각들

주말에 blog comment를 구하기 위해 오랫동안 썩혀 두었던 웹 크롤러를 꺼내들고 오랜만에 돌려 봤다. 테크노라티 분야별  top 블로거의 양질의 comment 1만건을 뽑아 왔다.  데이터를 뽑아서 좀 보니 색다른 아이디어도 생각나더라.

내 크롤러는 대용량이나 웹검색을 위해서 만든건 아니고, 100만건 이하의 웹을 크롤링 하는데 적합한 크롤러다.

노트북에 크롤러를 돌려보면서 크롤러를 대용량 검색을 위해서 바꾼다면 어떻게 해볼까 생각을 해봤다.

그럼

기본적인 웹 크롤러가 반드시 가지고 있어야 하는것은 무엇인가?

1. 강건함

spider trap같은곳에 걸리지 않도록 해야한다. 사이트 내에서 나오지 못하고 무한루프를 돌게 되는것인데, 뭐 달력이 있는 사이트나 하는 그런곳은 조심 하도록 해야 겠다.

2. 예의(?)

한곳만 집중 크롤링 되지 않게 해야한다. 아마도 그런다면 crawler를 닫히고 말것이다.

참고로 3년전에 만든 크롤러는 예의가 없다. url feeding queue를 하나를 유지하니 그럴 수 밖에 없다.

그래서 예의 있게 만들기 위해서 어떻게 하면 될까 생각을 해봤다.

host별로 url feeding을 하는 queue를 만들어 번갈아 가면서 큐를 참조하게 만들면 한개의 호스트에 집중 크롤링 되는것은 막을 수 있다. 물론 host의 갯수가 한정된다면 별도의 시간을 sync시키는 데이터 구조가 필요하겠지만 말이다.

위의 필수 조건 말고 옵션으로 가지면 좋을것은?

Distribute : 분산으로 크롤링이 가능해야 할것이다.

Performance : 크롤러는 제공된 리소스를 최대한 활용할 수 있어야 한다.

Quality : 좋은 사이트를 먼저 가져와야 할것이다.

Freshness : 자주 변경되는 사이트는 자주 크롤링 되어야 할것이다.

Extensible : 다른 새로운 데이터 포멧의 문서도 크롤링 가능해야 한다.

대용량을 하자면 분산이 필수 인데, 뭘 분산하는게 나을까?

먼저 문서 dedup을 판단하는 서버를 분산할 수 있겠고, url 중복 처리 하는 서버를 분산 시킬 수 있겠고, 또한 크롤러 자신을 분산을 시키면 될것이다.

url 문서 중복 처리 하는 서버는 url host별로 hash function을 이용해 분산하고 그 내부에서 정렬된 url을 룩업하는 방식으로 처리하면 나을거 같다. 동시에 여러 url에 대한 중복 처리가 가능 할것이다.
하지만 문서 dedup은 문서를 분산시키더라도 각 노드의 적중 확률은 같기 때문에 동시에 모든 노드에 룩업을 하는 방식으로 해야할것이다.

크롤러는 fetch 하는 작업만 하는 분야로 분산이 가능하겠다.

그러면 Freshness와 Quality부분은 어떻게 보강할까?

이것은 url을 feed 하는 feed 서버가 담당할 일이라고 생각한다. 먼저 위에서 이야기 한(Politeness) host별로 feeding queue를 구성한다고 했는데, 그 이전 작업으로 Freshness와 Quality를 유지하기 위한 Queue를 추가 구현하면 될거 같다. 그러니까 레이어 하나를 더 둬서 url을 feeding 하자는 것이다.  이것은 일반적인 그래프 traverse방식인 depth first, breath first 방식에서 약간 발전된 형태이다.

물론 Freshness나 Quality에 대한 기준이 필요하다.
freshness를 위해서는 이전 크롤링 history를 참조해 사이트의 변경 주기를 판단하는 것이고, Quality는 Page Rank값같은것을 이용해서 우선순위 Queue를 구성하면 될것이다.

우선 Freshness와 Politeness를 위해 feed server를 구현한다면, Freshness에 대한 등급을 둬서 (1~F) 까지 각 큐를 할당하고 URL을 분배해서 유지한다.
그리고 각 Queue에서 순서대로 데이터를 가져와 host별로 유지되는 Queue에 입력하는 것이다. 아마도 이런 Queue는 급변하는 Host url에 적응하기 위해서 host, queue number 쌍을 저장하는 구조도 별도로 필요 할 것이다.

그리고 그 존재하는 host별로 최종 크롤링 시간이 오래된 순으로 정렬된 heap를 유지해 url을 feeding하는 것이다. (이렇게 하면 정확하게 host를 hit하는 속도를 조절할 수 있을 것이다.)

물론 Quality에 대한 것들도 위의 방법을 응용하면 되리라 생각된다.

뭐 이것말고 DNS Server구현이라든지, URL normalization 이라든지, html parser라든지 세부 구현이 많지만. 조금은 전체적인 관점에서 그림을 그려봤다.

진짜 그림을 그려서 설명하고 싶지만, 그럴만한 시간이 없군.. 잠도 자야하니…

CC BY-NC 4.0 Crawler에 대한 추가 생각들 by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.