호스트별 큐를 만들었습니다. 그 큐를 채우는 주소 목록이 이 절의 주제입니다. 크롤러에서 가장 크고 가장 다루기 어려운 자료입니다.
발견이 크롤보다 빨리 자란다
페이지 하나에서 주소 수십 개가 나옵니다. 월 10억 페이지 을 가져오면 발견되는 주소는 그보다 훨씬 많습니다.
대부분은 이미 본 주소입니다. 사이트 안에서 서로 링크하기 때문입니다. 그래서 목록 관리의 핵심은 담는 것이 아니라 이미 본 것을 걸러내는 것입니다.
본 주소를 어떻게 기억하나
수십억 개의 주소를 그대로 기억할 수는 없습니다. 주소는 길고 개수가 많습니다.
| 방법 | 비용 |
|---|---|
| 주소 전체를 담는다 | 주소 하나가 수백 바이트. 수십억이면 수 테라 |
| 주소의 지문만 담는다 | 하나에 8바이트. 수십억이면 수십 기가 |
| 있을 수 있는지만 값싸게 답한다 | 메모리를 훨씬 덜 쓴다. 드물게 틀린다 |
지문만 담아도 메모리에 겨우 들어갑니다. 그래서 값싼 판정 장치를 앞에 두고 거기서 "없다" 고 하면 새 주소로 처리합니다. 키-값 저장소의 읽기 경로에서 본 것과 같은 장치입니다.
드물게 틀리면 이미 본 주소를 새 것으로 여겨 한 번 더 가져옵니다. 반대 방향으로 틀리지 않으므로 놓치는 주소는 없습니다. 이 비대칭이 여기서도 쓸모가 있습니다.
주소를 정규화한다
같은 페이지를 가리키는 주소가 여러 형태로 나옵니다. 끝의 빗금, 대소문자, 순서가 다른 질의 문자열, 추적용 매개변수가 그렇습니다.
정규화하지 않으면 같은 페이지를 여러 번 가져온다
목록도 그만큼 부풀어 오른다
어디까지 정규화할지가 판단입니다. 질의 문자열을 다 버리면 실제로 다른 페이지를 하나로 취급하고, 하나도 안 버리면 추적용 매개변수 때문에 같은 페이지가 수백 개로 늘어납니다.
목록을 어디에 두나
수십억 개를 메모리에 둘 수 없으므로 디스크에 둡니다. 그런데 큐에서 꺼내는 일은 빨라야 합니다.
| 층 | 담는 것 |
|---|---|
| 메모리 | 지금 처리 중인 호스트 큐의 앞부분 |
| 디스크 | 나머지 전부 |
앞부분만 메모리에 두고 뒤는 디스크에서 채웁니다. 순서대로 읽고 쓰므로 디스크에 유리한 접근입니다. 키-값 저장소에서 본 순차 쓰기의 이유와 같습니다.
목록이 사라지면 다시 시작해야 한다
크롤러를 재시작할 때 목록이 없으면 처음부터 다시 발견해야 합니다. 그러면 이미 가져온 페이지를 또 가져오게 되고 예산이 낭비됩니다.
그래서 목록은 크롤 결과보다 더 중요하게 지킵니다. 페이지는 다시 가져올 수 있지만, 목록을 잃으면 어디까지 했는지를 잃습니다.