여기까지 무엇을 가져올지 정했습니다. 이제 가져오기 한 번의 비용을 봅니다. 이 비용이 예산을 얼마나 쓰는지 정합니다.
시간의 대부분이 내려받기가 아니다
가져오기는 세 단계입니다. 이름으로 주소를 찾고, 연결하고, 내려받습니다. 이름 찾기가 가장 오래 걸립니다.
이름 찾기 과정 자체는 DNS 조회 개념에서 다뤘습니다. 여기서 중요한 것은 크롤러의 특수한 사정입니다.
| 일반 사용자 | 크롤러 |
|---|---|
| 자주 가는 사이트가 몇 개 | 호스트 수십만 개를 돈다 |
| 캐시가 잘 맞는다 | 처음 보는 호스트가 계속 나온다 |
| 초당 몇 번 | 초당 수백 번 |
그래서 크롤러에서는 이름 찾기가 병목이 됩니다. 초당 386페이지를 가져오려면 이름 찾기도 그만큼 필요하고, 그것을 일반적인 방식으로 하면 응답을 기다리는 데 시간을 다 씁니다.
호스트별 큐가 캐시를 도와준다
한 호스트에서 여러 페이지를 연달아 가져오므로 이름 찾기 결과를 한 번만 하면 됩니다. 앞에서 예의 때문에 만든 구조가 여기서 이득을 냅니다.
호스트 큐 하나를 처리하는 동안 이름은 한 번만 찾는다
그 큐의 주소가 100개면 이름 찾기 비용이 100분의 1이 된다
한 결정이 다른 곳에서 이자를 내는 예입니다. 예의를 위해 나눈 큐가 캐시 적중률까지 올려 줍니다.
기다리지 않는 것도 설계다
크롤러는 응답이 느린 상대를 계속 만납니다. 기다리면 그 일꾼이 놀고 예산이 남습니다.
| 대상 | 상한 |
|---|---|
| 이름 찾기 | 짧게. 못 찾으면 뒤로 미룬다 |
| 연결 | 짧게 |
| 내려받기 | 페이지 크기에 상한을 함께 둔다 |
크기 상한이 특히 중요합니다. 아주 큰 파일을 만나면 그것 하나가 여러 페이지 몫의 시간과 대역폭을 씁니다. 우리가 원하는 것은 문서이므로 상한을 넘으면 중단합니다.
실패를 어떻게 다루나
실패에는 두 종류가 있습니다.
| 종류 | 대응 |
|---|---|
| 일시적 (연결 실패, 서버 오류) | 뒤로 미뤄 다시 시도한다 |
| 영구적 (없는 페이지, 차단) | 목록에서 빼고 기록한다 |
구분하지 않으면 없는 페이지를 영원히 다시 시도합니다. 그리고 반복 실패가 잦은 호스트는 우선순위를 낮춥니다. 상대가 죽어 있는데 계속 두드리는 것은 예의에도 어긋납니다.
무엇을 재야 하는지
가져오기 지표는 성공률만으로 부족합니다.
단계별 시간: 이름 찾기, 연결, 내려받기
실패 종류별 비율
호스트별 평균 응답 시간
단계를 나눠 재지 않으면 어디가 느린지 모릅니다. 그리고 이름 찾기 시간이 오르는 것은 캐시가 잘 안 맞고 있다는 신호라, 새 호스트를 너무 많이 열고 있다는 뜻일 수 있습니다.