앞 단계에서 최소 386개 호스트를 동시에 다뤄야 한다는 결론이 나왔습니다. 그것을 어떻게 만드는지가 이 절입니다.
한 줄에 섞으면 규칙을 지킬 수 없다
방문할 주소를 한 줄에 넣으면 같은 호스트의 주소가 연달아 나옵니다. 큰 사이트에서 나온 주소가 목록의 대부분을 차지하기 때문입니다.
그러면 일꾼들이 같은 호스트를 동시에 두드립니다. 예의 규칙을 지키려면 매번 "이 호스트를 마지막으로 언제 봤나" 를 확인해야 하고, 그 확인이 모든 일꾼 사이에서 공유돼야 합니다.
호스트마다 줄을 따로 세운다
호스트별로 큐를 만들고 한 큐는 한 일꾼만 봅니다. 그러면 그 일꾼이 자기 큐의 간격만 지키면 규칙이 지켜집니다. 일꾼 사이에 공유할 상태가 없어집니다.
호스트 큐를 일꾼에게 배정한다
일꾼은 자기 큐에서 하나 가져와 처리하고 1초 기다린다
규칙 확인이 지역 문제가 되는 것이 이 구조의 값입니다. 앞의 아키타입들에서 반복된 방식이고, 여기서는 호스트가 그 단위입니다.
큐 수가 곧 처리량이다
일꾼 하나가 한 호스트에서 초당 한 페이지를 가져오므로, 동시에 살아 있는 큐 수가 초당 페이지 수입니다.
| 살아 있는 큐 | 초당 페이지 |
|---|---|
| 100개 | 100 |
| 386개 | 386. 예산을 채운다 |
| 1,000개 | 1,000. 예산보다 많다 |
큐가 부족하면 일꾼이 놀고 예산이 남습니다. 그래서 주소 목록이 여러 호스트에 고르게 퍼져 있어야 합니다. 한 호스트의 주소만 많이 들고 있으면 처리량이 나오지 않습니다.
큰 사이트가 목록을 채운다
주소는 대형 사이트에서 압도적으로 많이 나옵니다. 그대로 두면 목록이 소수 호스트로 채워지고, 큐 수가 줄어 처리량이 떨어집니다.
| 대응 | 내용 |
|---|---|
| 호스트별로 목록 길이에 상한을 둔다 | 한 사이트가 목록을 독점하지 못한다 |
| 새 호스트 발견을 우선한다 | 큐 수를 늘려 처리량을 지킨다 |
대형 사이트를 다 가져오려는 것과 예산을 채우는 것이 충돌합니다. 요구사항이 넓은 범위를 원한다면 상한을 두는 편이 맞습니다.
간격을 호스트마다 다르게 준다
초당 한 번은 기본값입니다. 큰 사이트는 더 자주 받아도 괜찮고, 작은 사이트는 더 느리게 해야 할 수 있습니다.
상대가 알려 준 간격이 있으면 그것을 따른다
응답이 느려지거나 거절이 오면 간격을 늘린다
상대의 신호에 반응하는 것이 규칙을 숫자로 지키는 것보다 중요합니다. 상대가 힘들어하는데 규칙만 지키고 계속 두드리면 결국 차단됩니다.