기본적으로 신경써야 하는 부분

데이터 구조 설계, Block 우회, reverse engineering 여부, 멀티 프로세스(worker, job, instance), 파이프라인 설계

1. 데이터 구조 설계

 - 요구사항이 무엇인지 정확히 확인하는 게 좋지만, 대부분의 요구사항은 뭉뚱그려질 때가 많다. 그래서 대부분은 초기에 기본 구조로 만들고 필요시 추가하는 게 낫다.

 - 컬럼을 target schema에 추가하는 경우 type을 신경써야 한다.

 - 요구사항에서 가장 중요한 점은 index값을 무엇으로 잡느냐인 거 같다. 나머지는 어차피 미리 정해 두어도 바뀐다.

 - 필수적인 data dimension 파악을 통해 설계해야 한다.

 - target db에 insert된 시각은 있으면 좋다. (mysql의 경우, CURRENT_TIMESTAMP 이용)

 - 시점에 대한 값은 잘 구분해주는 게 디버깅할 때도 유리하다. cron 기준 트리거된 시간과 실제 worker에서 작업이 시작된 시간 등을 이용하면 실제 어떤 Q의 duration을 계산할 수 있고, 퍼포먼스 계산을 용이하게 해준다.

2. Block 우회

 - 현실적인 문제이다. 거꾸로 어떻게 bot을 인식하는가를 체크하고 피해야 한다.

 - ip와 browser_id의 조합으로 인식하는 경우가 많다. 사실 그 2개를 철저히 refresh하면 잡아내기 쉽지 않다.

 - browserid는 사실 client 입장에서 server가 나를 어떻게 판별할지 추정하기 어렵고, ip 변경은 네트워크 속도 저하라는 cost가 있다.

 - VPN을 유료로 써야 그나마 IP 변경으로 인한 속도 저하의 cost를 줄일 수 있다.

 - VPN의 주요 위험 중 하나는 VPN의 연결이 제대로 안 돼있는 상태에서 연결이 시도되는 것이다. 이런 케이스에서 중요한 ip를 block 시키는 사례가 생길 수 있으니 웬만하면 외부ip임을 확인하고 거기서만 테스트 하는 것을 권장한다.

-외부망에 크롤링 서버를 만들면, 내부 target db에 접속하기 어려워질 수 있으므로, instance 추가 시 방화벽을 고려해야 한다. 예시로 SQS에 쌓아 놓고, 접근 가능한 다른 region의 instance에서 가져가는 방식도 채택 가능하다.

 - block이라는 게 꼭 접속이 차단되는 형태는 아니다. garbage data를 주는 경우도 있다. block 인식을 잘못하면 data가 오염될 수 있다.

3. reverse engineering 여부

 - 대부분 웹에 노출되는 정보들은 api를 통해 출력되는 경우가 많다. api를 통해 파라미터만 바꿔서 가져올 수 있다면, 크롤링의 cost는 대폭 낮아진다.

 - 그래서 보안이 강한 사이트들은 대부분 api를 post 형태로 숨기거나, auth를 요구하면서 hmac 같은 걸 활용해 임시 키를 발급한다.(요새는 네이버가 많이 쓰는 듯하다)

 - 이게 가능한지에 따라 크롤링 퍼포먼스, cost, 아키텍쳐 설계가 급격하게 달라지니 꼭 확인이 필요하다.

 - 불가능해서 front로 작업해야 한다면, 크로미움이나 playwright + xvfn 조합을 많이 쓴다.

 

4. 멀티 프로세스

 - 3번에서 전체 reverse engineering이 가능하다면, 요구 수준에 따라 멀티 프로세싱이 필요하지 않을 수도 있다.

 - 다만 그렇지 못 하다면, 대부분은 크롤링의 가성비를 위해 멀티 프로세싱 처리와 그를 위한 구조 설계가 필요하다.

 - instance의 메모리를 관리하기 위한 health check를 만들어 적절한 worker 수준을 찾는 테스트도 필요하다.

 - 1 instance -> n workers -> job processing 구조를 위해 Q를 관리할 무언가가 있으면 좋다. [SQS나 카프카]

 - instance는 EC2를 쓸 수도 있지만, heavy하지 않은 경우 lightsail이 가성비가 더 좋다.

 

5. 파이프라인 설계

 - master data => Event trigger(or airflow) => SQS(엄격한 관리가 필요하고 데이터가 많다면 Kafka) => (VPN converter) => workers => target db

 - 기본 구조는 이렇게 잡고, 이걸 무엇으로 달성할 것인지를 데이터양이나 필요 수준에 따라 선택해야 한다.

 - master data는 구글 시트는 안 쓰는 것이 좋다. 써야 한다면 구글 시트를 주기적으로 db에 업데이트 하는 프로세스를 만들고 해당 테이블을 참조하는 걸 권장한다. 생각보다 gcp는 에러가 많다.

- master data를 extract할 때, gcp는 생각보다 불안정하다. gcp를 쓰더라도 retry 간격이 1분은 되어야 한다. 궁극적으로는 db table 같은 곳에 cache를 하고 쓰는 걸 권장한다. cache했다면, master data를 주로 수정하는 사람은 업데이트 주기를 인지할 필요가 있다.(수정 시점과 cache 데이터의 기준 시점이 달라 의도하지 않은 결과가 나올 수 있음)

 

+ Recent posts