////
Search
Duplicate
9️⃣

9장. 웹 크롤러 설계

웹 크롤러는 로봇 또는 스파이더라고도 부른다.
검색 엔진에서 널리 사용되는 기술로, 웹에 새로 올라오거나 갱신된 컨텐츠를 찾아내는 것이 주된 목적이다.
여기서 컨텐츠는 웹 페이지일 수도 있고 이미지나 비디오, PDF 파일일 수도 있다.
보통의 웹 크롤러는 특정 웹 페이지에서 시작하여 그 링크를 따라나가면서 새로운 컨텐츠를 수집한다.
크롤러는 다음과 같이 여러 목적으로 사용된다.
검색 엔진 인덱싱
웹 페이지를 모아 검색 엔진을 위한 로컬 인덱스를 만든다.
Googlebot은 구글 검색 엔진이 사용하는 대표적인 웹 크롤러다.
웹 아카이빙
나중에 사용할 목적으로 장기보관하기 위해 웹에서 정보를 모으는 절차를 말한다.
대표적으로는 미국 국회 도서관, EU 웹 아카이브가 있다.
웹 마이닝
웹 마이닝은 인터넷에서 유용한 지식을 도출해 내는 것이다.
유명 금융 기업들은 크롤러를 사용해 주주총회 자료나 연차 보고서를 다운받아 기업의 핵심 사업 방향을 결정하기도 한다.
웹 모니터링
크롤러를 사용하면 인터넷에서 저작권이나 상표권이 침해되는 사례를 모니터링할 수 있다.
디지마크사는 웹 크롤러를 사용해 해적판 저작물을 찾아내서 보고한다.
웹 크롤러 역시, 복잡도가 처리해야 하는 데이터의 규모에 따라 달라진다.
따라서 우리는 설계 시, 웹 크롤러가 감당해야 하는 데이터의 규모와 기능들을 알아내야만 한다.

1단계 문제 이해 및 설계 범위 확정

웹 크롤러의 기본 알고리즘은 다음과 같다.
1.
URL 집합이 입력으로 주어지면, 해당 URL들이 가리키는 모든 웹 페이지를 다운로드한다.
2.
다운받은 웹 페이지에서 URL들을 추출한다.
3.
추출된 URL들을 다운로드할 URL 목록에 추가하고 위의 과정을 재귀적으로 반복한다.
웹 크롤러 설계를 위해 다음과 같은 질문들을 해볼 수 있다.
크롤러의 주된 용도는 무엇인가요? 검색 엔진 인덱싱? 데이터 마이닝? 아니면 그 외의 다른 용도?
매달 얼마나 많은 웹 페이지를 수집해야 하나요?
새로 만들어진 웹 페이지나 수정된 웹 페이지도 고려해야 하나요?
수집한 웹 페이지는 저장해야 하나요? 저장한다면 얼마나 저장해두어야 하나요?
중복된 컨텐츠는 어떻게 해야 하나요?
외에도 기본적으로 좋은 웹 크롤러가 만족해야할 다음과 같은 속성에 주의를 기울이는 것도 좋다.
규모 확장성
안정성
비정상적인 입력이나 환경에 잘 대응할 수 있어야 한다.
예절
크롤러는 수집 대상 웹 사이트에 짧은 시간 동안 너무 많은 요청을 보내서는 안 된다.
확장성
새로운 형태의 콘텐츠를 지원하기가 쉬워야 한다.

개략적 규모 측정

매달 10억 개의 웹 페이지를 다운로드한다.
QPS = 1,000,000,000 / 30일 / 24시간 / 3600초 = 대략 1초에 400페이지
최대 QPS는 2배인 800으로 추정
웹 페이지의 크기 평균은 500kb로 가정
10억 페이지 * 500kb = 500TB/월
5년 간 보관하므로 최대 용량은 30PB

2단계 개략적 설계안 제시 및 동의 구하기

시작 URL 집합

웹 크롤러가 크롤링을 시작하는 출발점이다.
전체 웹을 크롤링해야 하는 경우, 시작 URL을 고를 때, 좀 더 창의적일 필요가 있다. 가능한 많은 링크를 탐색할 수 있도록 URL을 골라야할 것이다.
시작 URL로 무엇을 쓸 것이냐에 정답은 없다. 의도가 무엇인지만 정확히, 명확하게 전달하도록 하자.

미수집 URL 저장소

현대적 웹 크롤러는 대부분 크롤링 상태를 다운로드할 URL, 다운로드된 URL의 두 가지로 나눠 관리한다.
이 중, ‘다운로드할 URL’을 저장 관리하는 컴포넌트를 미수집 URL 저장소라고 부른다.
큐 형태라고 생각하면 쉽다.

HTML 다운로더

웹 페이지를 다운로드하는 컴포넌트다. URL은 미수집 URL 저장소가 제공한다.

도메인 이름 변환기

웹 페이지를 다운받을 때, URL을 IP 주소로 변환하는 절차가 필요하다.
이는 도메인 이름 변환기를 사용하여 URL에 대응하는 IP 주소를 알아낸다.

컨텐츠 파서

웹 페이지 다운로드 시, 파싱과 검증이 필요한데, 크롤링 서버 안에 컨텐츠 파서를 구현하면 크롤링이 느릴 수 있으므로 독립된 컴포넌트로 사용할 수 있다.

중복 컨텐츠 체크

웹에 공개된 연구에 따르면 29% 가량의 웹 페이지는 중복이다. 따라서 중복 문제를 해결하기 위한 컴포넌트를 두어 데이터 처리에 소요되는 시간을 줄인다.
중복에 HTML을 비교하는 방법을 쓸 수 있겠지만 가장 효율적인 방법은 웹 페이지의 해시 값을 비교하는 것이다.

컨텐츠 저장소

HTML 문서를 보관하는 시스템으로, 데이터의 유형, 크기, 저장소 접근 빈도, 데이터의 유효 기간 등을 고려하여 설계해야 한다.
데이터 양이 너무 많은 경우 디스크를, 조회가 잦은 경우 메모리를 사용하는 등 적절히 선택하는 것이 좋다.

URL 추출기

URL 추출기는 HTML 페이지를 파싱하여 링크들을 골라내는 역할을 한다.
상대 경로는 전부 절대 경로로 변환한다.

URL 필터

이미 방문한 URL을 보관하는 저장소다.

웹 크롤러 작업 흐름

1.
시작 URL들을 미수집 URL 저장소에 저장한다.
2.
HTML 다운로더는 미수집 URL 저장소에서 URL 목록을 가져온다.
3.
HTML 다운로더는 도메인 이름 변환기를 사용하여 URL의 IP 주소를 알아낸 후, 해당 IP 주소로 접속하여 웹 페이지를 다운 받는다.
4.
컨텐츠 파서는 다운된 HTML 페이지에서 올바른 형식을 갖춘 페이지인지 검증한다.
5.
컨텐츠 파싱과 검증이 종료되면 중복 컨텐츠인지 확인하는 절차를 가진다.
6.
중복 컨텐츠인지 확인하기 위해서 해당 페이지가 저장소에 있는지 확인한다.
a.
이미 있는 경우, 처리하지 않고 버린다.
b.
저장소에 없는 컨텐츠인 경우, 저장소에 저장한 후, URL 추출기에 전달한다.
7.
URL 추출기는 해당 HTML 페이지에서 링크를 찾아낸다.
8.
찾아낸 링크를 URL 필터에 전달한다.
9.
필터링이 끝나고 남은 URL만 중복 URL 판별 단계로 전달한다.
10.
이미 처리한 URL인지 확인하기 위하여 URL 저장소에 보관되어있는지 확인한다.
a.
저장소에 없는 경우, URL 저장소에 저장한 후, 미수집 URL 저장소에 전달한다.

3단계 상세 설계

각 컴포넌트 별 그 구현 기술을 심도깊게 설계하자.

DFS를 쓸 것인가, BFS를 쓸 것인가

웹은 방향이 존재하는 그래프와 같다. 페이지는 노드이고 하이퍼링크는 엣지라고 보면 된다.
크롤링 프로세스는 이 그래프를 엣지를 따라 탐색하는 과정이다.
DFS는 그래프 크기가 클 경우, 어느 정도로 깊숙이 가게 될지 가늠하기 어려우므로 보통은 BFS를 사용한다.
하지만 이 구현법에는 다음 두 가지 문제가 존재한다.
한 페이지에 나오는 링크의 상당수는 같은 서버로 되돌아 간다.
때문에 예의없는 크롤러가 될 가능성이 있다.
표준적 BFS 알고리즘은 URL 간 우선순위를 두지 않는다.
보통 페이지에는 우선순위가 존재할 수 있다. 사용자 트래픽의 양, 페이지 순위, 업데이트 빈도 등 때문에 우선순위를 두어 처리하는 것이 바람직하다.

미수집 URL 저장소

BFS의 문제를 미수집 URL 저장소를 사용해 해결할 수 있다.
예의
동일한 웹 사이트로 보내는 요청을 한 번만 실행하도록 한다.
이 요구사항을 만족시키기 위해서는 웹사이트의 호스트명과 다운로드를 처리하는 작업 스레드 간의 상태를 유지하면 된다.
우선순위
URL의 우선순위를 결정하기 위해 페이지순위, 트래픽 양, 갱신 빈도 등 다양한 척도를 사용할 수 있다.
신선도
웹 페이지는 수시로 추가되고 삭제되고 변경된다. 따라서 데이터의 신선함을 유지하기 위해서 이미 다운로드한 페이지라고 해도 주기적으로 재수집할 필요가 있다.
웹 페이지의 변경이력을 활용할 수 있으며 우선순위를 활용하여 중요한 페이지는 더 자주 재수집하도록 할 수 있다.

미수집 URL 저장소를 위한 지속성 저장장치

모든 데이터를 디스크에 저장하는 경우, 성능 병목지점이 될 수 있고 메모리에 저장하는 경우 비용이 많이 발생하기 때문에, 적절한 절충지점을 설정하는 것이 좋다.
대부분의 URL은 디스크에 두지만 입출력 비용을 줄이기 위해 메모리 버퍼에 큐를 두어 관리할 수 있따.

HTML 다운로더

HTML 다운로더는 HTTP 프로토콜을 활용해서 웹 페이지를 다운받는다.
다운로더에 대해 알아보기 전 로봇 제외 프로토콜부터 살펴보고 넘어가자.
Robots.txt
이는 웹사이트가 크롤러와 소통하는 표준적 방법으로, 이 파일에는 크롤러가 수집해도 되는 페이지 목록이 들어있다.
웹 사이트를 긁어 가기 전 크롤러는 해당 파일에 나열된 규칙을 먼저 확인해야 한다.
성능 최적화
아래는 HTML 다운로더에 사용할 수 있는 성능 최적화 기법들이다.
1.
분산 크롤링
성능을 높이고자 크롤링 작업을 여러 서버에 분산하는 기법이다.
각 서버는 각자의 스레드 풀을 이용해 다운로드 작업을 처리한다.
2.
도메인 이름 변환 결과 캐시
DNS Resolver는 크롤러 성능의 병목 중 하나인데, 이는 DNS 요청을 보내고 결과를 받는 작업의 동기적 특성때문이다.
따라서 DNS 조회 결과로 얻어진 도메인 이름과 IP 주소 사이의 관계를 캐시에 매핑해놓고 크론 잡 등을 돌려 주기적으로 갱신하도록 해놓으면 병목을 해결할 수 있다.
3.
지역성
크롤링 작업을 수행하는 서버를 지역별로 분산하는 방법이다.
이는 크롤링 서버, 캐시, 큐, 저장소 등 대부분의 컴포넌트에 적용할 수 있다.
4.
짧은 타임아웃
어떤 웹 서버는 응답이 느리거나 응답하지 않으므로 이런 경우, 타임아웃을 짧게 서렂ㅇ해두면 좋다.
안정성
최적화 뿐만 아니라 안정성도 다운로더 설계 시 고려해야할 부분이다.
안정 해시
다운로더 서버들에 부하를 분산할 때, 적용 가능한 기술이다.
크롤링 상태 및 수집 데이터 저장
장애가 발생한 경우, 쉽게 복구할 수 있도록 크롤링의 상태와 수집된 데이터를 지속적 저장장치에 기록해두는 것오 바람직하다.
예외 처리
대규모 시스템에서 에러는 불가피하므로 예외가 발생하도록 시스템이 중단되지 않도록 해야한다.
확장성
데이터를 처리하는 부분에 데이터 가공을 최적화시키기 위해 별도의 모듈을 둔다던가 등의 행위가 가능하다.
문제 있는 컨텐츠 감지 및 회피
1.
중복 컨텐츠
해시나 체크섬을 이용해 중복 컨텐츠를 쉽게 탐지할 수 있다.
2.
거미 덫
크롤러를 무한 루프에 빠뜨리도록 설계한 웹피이지다. 이런 덫은 URL의 최대 길이를 제한하면 회피할 수 있다.
그렇게 탐지가 불가능한 경우, 로그를 확인하여 추후 작업이 필요할 수도 있다.
3.
데이터 노이즈
광고나 스크립트 코드 등의 경우 필요가 없으므로 가능하다면 제외해야 한다.

4단계 마무리

이번 장에서는 좋은 크롤러가 갖추어야 하는 특성들을 살펴보았다.
규모 확장성, 예의, 확장성, 안정성이 그것이다.
아울러 크롤러의 설계안을 제시하고 핵심 컴포넌트 별로 쓰이는 기술들도 간략하게 살펴보았다.
시간이 허락한다면 면접관과 다음을 추가로 논의해보면 좋다.
서버 측 렌더링
서버 측 렌더링을 적용하여 동적으로 생성되는 링크를 추가적으로 크롤링할 수 있다.
원치 않는 페이지 필터링
자원은 유한하기 때문에, 스팸 방지 컴포넌트를 추가하여 불필요한 페이지를 거르면 좋다.
데이터베이스 다중화 및 샤딩
다중화, 샤딩 기법을 적용하여 데이터 계층의 가용성, 규모 확장성, 안정성을 향상시킬 수 있다.
수평적 규모 확장성
다운로드를 실행할 서버가 매우 많이 필요할 수 있다. 따라서 수평적 규모 확장성을 달성해야하므로 무상태 서버로 만드는 것이 좋다.
가용성, 일관성, 안정성
이런 개념들은 성공적인 대형 시스템을 만들기 위해 필수적으로 고려해야 하는 것들이다.
데이터 분석 솔루션
데이터를 수집하고 분석하는 것 역시 어느 시스템에나 중요하다.