자동 확장 가능한 콘서트 티켓 예매 사이트 구축하기

이재홍 http://www.pyrasis.com 2014.03.24 ~ 2014.06.30

이번에는 콘서트 티켓을 예매하는 사이트를 구축해보겠습니다. 콘서트 티켓 예매 사이트는 예매 시간에만 사람이 붐비고 예매가 끝나면 방문자가 급감합니다. 특히 인기가 많은 공연은 한 시간도 안되서 예매가 끝나기도 합니다. AWS의 Auto Scaling을 사용하면 방문자가 몰려도 자동으로 대처할 수 있고, 방문자가 없을 때는 서버를 줄여 비용을 절감할 수 있습니다. 학교 수강 신청 시스템도 이와 비슷합니다. 학년별로 나눠서 수강 신청하지 않아도 AWS로 구축하면 한 번에 수강 신청을 받을 수 있습니다.

콘서트 티켓 예매 사이트를 구축하려면 어떻게 해야 할까요? 사용할 AWS 리소스를 선택하기 전에 구축하려는 서비스의 요구사항을 먼저 파악해야 합니다.

콘서트 티켓 예매 사이트의 요구사항을 정리해보면 다음과 같습니다.

  • 짧은 시간에 사람이 많이 몰려도 서비스가 중단되지 않아야 한다.
  • 결제가 정확하게 이루어져야 한다.
  • 실시간으로 좌석 예매 상황을 표시해야 한다.

이제 요구사항에 맞게 사용할 AWS 리소스와 서비스 구조를 설계해보겠습니다.

  • 짧은 시간에 사람이 많이 몰렸을 때는 서비스를 자동으로 확장하고 부하를 분산하는 Auto Scaling과 ELB가 적합합니다.
  • 정확한 결제가 이루어져야 하므로 DynamoDB보다는 RDS가 적합합니다.
    • DynamoDB는 실제 처리량이 설정한 처리량을 넘어서면 읽기/쓰기 동작에 실패하게 됩니다. 좌석 결제가 정확하게 처리되지 않으면 큰 문제가 생길 수 있습니다.
    • 콘서트 티켓 예매 사이트는 대용량의 데이터를 저장할 필요도 없고, 데이터가 급속히 늘어나지 않으므로 DynamoDB의 자동 확장 기능은 사용할 일이 없습니다.
    • RDS는 많은 사용자를 처리할 수 있도록 DB 인스턴스 클래스와 IOPS를 높일 수 있습니다(수직 확장).
  • Auto Scaling으로 생성한 EC2 인스턴스끼리 실시간으로 좌석 예매 상황을 전파하려면 ElastiCache의 Redis가 적합합니다. Redis의 Pub/Sub 기능을 사용하면 좌석 상태를 손쉽게 공유할 수 있습니다.
    • 예약 및 결제 데이터의 일관성은 RDS가 보장하므로 ElastiCache를 사용한 실시간 좌석 예매 상황 표시는 부가적인 요소입니다. ElastiCache가 잠시 중단되거나, 실시간 데이터가 일치하지 않아도 서비스에는 큰 지장이 없습니다.
  • 웹 브라우저에서 실시간으로 좌석 상태를 갱신하기 위해 socket.io를 사용하겠습니다.
  • HTML, JavaScript 파일은 CloudFront로 배포합니다. socket.io로 실시간 통신할 때에는 EC2 인스턴스에 트래픽이 많이 몰리므로 정적인 HTML, JavaScript 파일은 CloudFront로 배포해서 EC2 인스턴스의 부하를 줄여주는 것이 중요합니다.
  • 사이트의 소스(HTML, JavaScript) 파일은 S3에 저장하겠습니다(GitHub, Bitbucket이나 자체 구축한 버전 관리 시스템 서버를 사용해도 됩니다).


그림 32-1 콘서트 티켓 예매 사이트 구성도

데이터베이스의 일관성(Consistency), 가용성(Availability), 분할 내성(Partition Tolerance)
DynamoDB는 여러 노드 및 가용 영역에서 분산처리를 하기 때문에 가용성과 분할 내성이 높습니다. 어지간해서는 데이터베이스가 중단되는 일이 없습니다. 하지만 가용성과 분할 내성, 대용량 데이터 저장에 초점을 맞춘 데이터베이스이기 때문에 처리량에 제한이 있고, 어느정도 일관성을 희생합니다. Strongly Consistent Read를 사용하면 데이터의 일관성을 보장받을 수 있지만 설정한 처리량을 넘어서면 데이터가 일치하지 않을 수 있습니다.

Oracle이나 MySQL과 같은 관계형 데이터베이스는 항상 일관성을 보장합니다. 즉 사용량이 늘어나서 데이터베이스가 중단되는 한이 있더라도 항상 데이터는 일치합니니다. 그래서 결제와 같이 정확성이 요구되는 분야에 적합합니다.

HBase와 같은 분산 파일시스템 기반 데이터베이스는 일관성과 분할 내성을 보장합니다. 서비스에서 가장 중요한 부분을 먼저 생각해보고, 그 부분에 적합한 데이터베이스를 선택하면 됩니다. 간단히 정리하면 용량과 가용성이 중요할 때는 DynamoDB, 정확성(일관성)이 중요할 때는 Oracle 또는 MySQL, 데이터의 용량이 크고 정확성이 필요할 때는 HBase를 사용합니다.

저는 프로젝트 이름은 ExampleTicket으로 하고, 코드양을 줄이기 위해 Node.js에 JavaScript로 구현하겠습니다. 실무에서는 각자 상황에 맞게 원하는 언어와 플랫폼을 사용하면 됩니다.

이제 ExampleTicket 서비스의 동작 흐름입니다.

  1. exampleticket.com에 접속하여 로그인한 뒤 좌석을 클릭합니다.
  2. EC2 인스턴스에서는 RDS에서 좌석 정보를 가져온 뒤 예약 가능 여부에 따라 RDS에 상태를 저장합니다.
  3. EC2 인스턴스에서는 Auto Scaling 그룹에 속한 모든 EC2 인스턴스가 받을 수 있도록 ElastiCache에 메시지를 보냅니다(Publish).
  4. Auto Scaling 그룹에 속한 EC2 인스턴스는 ElastiCache에서 메시지를 받은 뒤(Subscribe) 접속한 사용자들의 좌석 상태를 갱신합니다.
  5. 좌석을 클릭한 상태는 예약 상태이며 결제 창이 표시됩니다. 좌석은 오랜지색으로 바뀝니다.
  6. 결제 창에서 결제 버튼을 클릭합니다.
  7. EC2 인스턴스에서는 RDS에서 좌석 정보를 가져온 뒤 결제 가능 여부에 따라 RDS 상태를 저장합니다.
  8. EC2 인스턴스에서는 Auto Scaling 그룹에 속한 모든 EC2 인스턴스가 받을 수 있도록 ElastiCache에 메시지를 보냅니다(Publish).
  9. Auto Scaling 그룹에 속한 EC2 인스턴스는 ElastiCache에서 메시지를 받은 뒤(Subscribe) 접속한 사용자들의 좌석 상태를 갱신합니다.
  10. 결제가 끝나면 좌석은 초록색으로 바뀝니다.

예약 및 결제 상태에 따라 실시간으로 사용자들의 웹 브라우저에 표시된 좌석의 색상을 바꿉니다. 색상이 바뀐 좌석은 다른 사람이 예약하거나 결제할 수 없습니다.


그림 32-2 ExampleTicket 서비스의 동작 흐름

예제 소스 코드는 저의 GitHub 저장소에서 받을 수 있습니다.
https://github.com/pyrasis/awsbook


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.