ECS에서 실행되는 Crawler를 Serverless로 설정합니다.

6663 단어 AWS

개시하다


예전에 EC2에서 직접 작동하는 Crawler를 ECS로 옮기는 이야기라는 기사를 썼는데, 이 Crawler가 느려서 고속화하고 싶어요.
지각한 이유는 ECS에 사용된 EC2 실례가 너무 쩨쩨해서 EC2 실례를 늘려 실행하는 용기를 늘리면 해결되기 때문이다.
하지만 취미활동인 크래블러에 돈을 쓰고 싶지 않아 비용을 들이지 않고 자원적인 제약에서 해방돼 신축 가능한 Serverless 크래블러를 만드는 것을 목표로 한다.
이 기고문은 서버 발레에서 신축 가능한 크라울러의 구상을 다듬기 위한 글이다.
아직 시행되지 않았기 때문에 이런 건의를 모집하고 있다.
※ 실제 가동은 아니므로 주의

구성도



Serverless Crawler의 구성도는 이런 느낌입니다.

각 구성 요소의 역할


Event Source (CloudWatch Event)


Event SourceConsumer를 호출합니다.
CloudWatch Event를 사용하면 일정 간격으로 호출Consumer할 수 있습니다.

Requst Queue (SQS)


Consumer 폴링의 Quee입니다.
Que에 키Request Block가 포함되어 있습니다.
FIFO Que를 사용하여 두 번의 실행을 구분합니다.

Consumer (Lambda Function)


Event Source에서 호출 및 윤문Request Queue.
Request Block에서 Request 데이터를 추출하여 Downloader의 역할을 호출합니다.
Downloader의 동시 집행수도 제어한다.

Downloader (Lambda Function)


Consumer에서 보낸 URL에서 요청을 보내면 HTML을 S3에 저장하고 호출Scraper의 역할을 합니다.
가능한 한 동시에 요청을 보냅니다.

Scraper (Lambda Function)


S3에서 HTML을 가져와 롤업을 하고 RDS에 저장하는 역할을 한다.
다시 로그인할 페이지가 있으면 DynamoDB에 추가합니다.

HTML Bucket (S3)


Downloader 저장된 HTML 문서의 S3 Bucket입니다.

Request Block (DynamoDB)


읽은 Request가 있는 DynamoDB의 테이블을 저장합니다.
잘 쓰면 무료로 이용할 수 있기 때문에 다이나모DB를 선택했다.
Table에는 Downloader와 Scraper가 사용하는 정보가 포함되어 있습니다.
Serverless Crawler에서는 다른 도메인의 요청을 동시에 병렬적으로 수행하고자 하기 때문에 DynamoDB의 한 줄에 다른 도메인의 URL을 목록으로 저장합니다.
데이터의 형식은 이런 느낌이다.
"key": "Number",
"next": "Number",
"requests": [
  {
    "url": "String",
    "downloader": "String",
    "scraper": {
      "type": "String",
      "id": "Number",
    },
    "option": "Map"
  },
  ...
]}
키는 해시 키로, SQSConsumer에는 이들 키의 값이 포함될 것으로 예상된다.
그러나 Queue에서pushkey가 필요하고sendMessageBatch에서 가장 많이push10개의 메시지만 있을 수 있기 때문에 서버발레에서 이 메시지를 실현하는 데 비용적으로도 소개팅이 불가능할 것 같아서 다음 키의 값을 저장하기 위해next열을 늘린다.
Queue에서next의 값을pushConsumer로push하고Queuenext의 값이 비어 있을 때까지Consumer호출합니다.

프로세스 처리


DynamoDB에서 데이터가 저장되어 있다는 전제로
  • CloudWatch Event
  • Consummer의 Lambda Function을 10~30초 간격으로 호출
  • 호출된 Consuumer의 간격은 같은 필드에 요청을 보내는 간격
  • Consumer (Lambda Function)
  • Queue에서 데이터 가져오기
  • 1.에서 얻은 데이터를 바탕으로 DynamoDB에서 요청한 내용을 얻기
  • 2.에서 요청한 내용을 Parse로 진행
  • Anguer나 React가 쓴 사이트와 단순한 사이트를 분리한다
  • Downloader의 유형에 따라 분할
  • Downloader가 실행하는 Job의 수량으로 Requests
  • 를 분할합니다
  • 3.parse로 만든 몫, invoke
  • next의 값을 Que
  • 로 push
  • Downloader (Lambda Function)
  • Consuumer에서 받은 값에 따라 Downloader
  • 생성
  • 병렬 처리를 통한 요청 전송
  • 노드로 쓰면 Non Blocking IO이기 때문에 병렬 처리가 쉬워야 합니다
  • Download가 완성되면 s3
  • 에 저장
  • Scraper를 invoke로 사용
  • s3의put 이벤트에서 Lambda를 호출할 수 있지만 Scrape에 필요한 정보를 보내기 위해 Lambda에서 invoke
  • { "key": "String", "scraper": "Map", "option": "Map" }
  • Scraper (Lambda Function)
  • Downloader에서 받은 정보를 바탕으로 s3에서 획득
  • Downloader에서 받은 정보를 바탕으로 Scraper
  • 생성
  • 실행 볼륨
  • 롤업 데이터를 RDS에 저장
  • Scraping을 다시 수행해야 하는 페이지가 나타나면 DynamoDB에 추가
  • DynamoDB에 추가된 경우 추가되지 않음
  • 끝말


    잠시 머릿속의 구상을 써보았는데 SQS 같은 것이 미묘하다.
    SQS를 사용하는 이유는 DynamoDB를 일정한 간격, 순서로 실행하고 싶어서일 뿐이다.
    CloudWatch Event에서 부르는 경우 증가된 값을 전송할 경우 SQS가 필요하지 않을 수 있습니다.
    이후 RDS에 저장된 부분을 서버로 완전히 전환하면 다이나모DB로 재설계하려 했으나 비용이 상당히 많이 들고 다이나모DB의 무료 상자가 넘어선 것 같아 RDS를 직접 사용하기로 했다.
    그다음에 이것만 실제로 한다

    좋은 웹페이지 즐겨찾기