2020년 7월 25일 서버 사고

안녕하세요.

2020년 7월 25일 오후 2시부터 3시 58분까지 BOJ가 접속이 되지 않는 문제가 있었습니다. 이 문제 때문에, BOJ와 코드 플러스 사이트에 접속이 불가능했습니다.

BOJ 유저, 코드 플러스, 진행 중이던 한 대회 관계자와 참가자, 시작 예정이던 UCPC 2020의 대회 관계자와 참가자 모든 여러분께 사과드립니다.

UCPC는 이 글을 작성하고 있는 제가 초대 회장이었던 연합 동아리로 큰 관심을 가지고 있던 동아리인데, 대회의 진행과 관련된 큰 문제를 2년 연속으로 일으켜서 정말 죄송합니다.

앞으로는 이런 일이 발생하지 않도록 대안을 여러 가지 마련하려고 합니다.

이번 일이 왜 발생했는지 적어보겠습니다.

먼저, 작년 UCPC 2019의 서버 다운 사고와는 원인이 크게 다릅니다.

이번 사고를 이해하려면 온라인 저지 시스템을 이해해야 합니다.

온라인 저지 시스템

온라인 저지 시스템은 온라인으로 프로그래밍 문제를 해결하는 소스를 채점해주는 사이트입니다. BOJ는 지난 2010년 만들어진 온라인 저지 사이트로 최근 5년간 유저와 제출의 수가 크게 증가했으며, 최근 1-2년 사이의 증가는 이전 4년의 증가를 넘어섭니다.

하루 방문자가 1만명을 넘은지는 꽤 되었으며, 이 수치는 Google Analytics를 이용해 수집한 것이니, JS로 집계되지 않는 봇 접근을 포함하면 훨씬 더 많을 것으로 예상됩니다. 가장 많이 방문하는 시간대에는 동시 접속도 1천명을 넘기도 합니다.

온라인 저지 시스템은 동시 접속이나 방문자에 비해서 트래픽이 크게 발생하지는 않습니다. 게시판 기반의 웹사이트는 글 조회, 목록 조회, 글/댓글 작성 등이 빈번하게 일어납니다. 온라인 저지 시스템은 문제를 열고, 코딩을 하고, 제출을 합니다.

보통은 문제를 이해하는데도 긴 시간이 걸리고, 코딩을 하는데도 긴 시간이 걸립니다. 게시판 기반의 사이트와는 사이트 이용 형태가 매우 크게 차이나기 때문에, 접속자 수에 비해서 트래픽이 크게 발생하지 않습니다.

다른 사이트에는 잘 보이지 않는 기능이 하나 있는데 바로 채점입니다. 유저가 제출한 소스 코드를 별도의 채점 서버에서 컴파일 및 채점을 하는데, 빠르면 1-2초, 길면 5-6분까지도 걸리는 것이 이 작업입니다. 채점은 수많은 재채점을 통해서 매우 빠르게 진행할 수 있음을 보였기 때문에, BOJ에게는 크게 문제되지 않습니다.

온라인 프로그래밍 대회

온라인 프로그래밍 대회의 트래픽 역시 평상시 온라인 저지의 트래픽 유형과 유사합니다. 대회에 참가하는 것도 문제를 푸는 것이니 크게 트래픽이 발생하지 않습니다. 하지만, 큰 차이가 하나 있습니다.

대회는 특정 시간에 시작되기 때문에, 많은 유저가 미리 대회 시작 시간에 맞춰서 접속해있습니다. 또한, 대회가 시작되자마자 문제를 해결하기 위해 새로고침을 매우 많이 누르게 됩니다. 대회의 트래픽을 분석해보면 다음과 같습니다.

  • 대회 시작 10분 전 - 대회 시작 1분 전: 대회 홈페이지 및 대회 메인 화면에 참가자가 미리 접속
  • 대회 시작 1분 전 - 대회 시작: 대회 시작과 동시에 문제를 열기 위해 새로 고침을 많이 누름
  • 대회 시작 - 대회 시작 2분 후: 모든 문제를 열어 두기 위해 모든 문제를 새 탭에 띄움
  • 대회 시작 2분 후 - 대회 시작 1시간 후: 쉬운 문제들의 제출이 많이 발생함
  • 이후: 점점 트래픽이 줄면서 평상시 BOJ의 동시 접속자수 대비 트래픽과 비슷해짐

BOJ의 온라인 프로그래밍 대회 준비

참가자가 많은 온라인 프로그래밍 대회는 준비하는 시간이 꽤 많이 필요합니다. 다음 3가지를 준비해야 합니다.

  • 대회 인원 수 만큼의 동시 접속자를 버틸 수 있음
  • 대회 시작 1분 전 - 2분 후까지의 트래픽을 버틸 수 있어야 함
  • 대회 시작 1시간 이내의 제출을 밀리지 않고 평상시 BOJ처럼 처리할 수 있어야 함

이전에도 카카오 코드 페스티벌 2018 예선 대회 개최 후기 로 어떻게 준비했는지에 대한 긴 글을 작성한 적이 있었습니다.

위의 글에서 참가자가 많았던 대회인 Coder’s high 2016 Round 1: Online(이하 CH2016)를 언급합니다. 또, 이제는 카카오 코드 페스티벌 2018 예선 대회(KCF2018)도 이전 대회입니다.

위의 글에 따르면 CH2016은

  • 참가자 수: 648명
  • 예상 최대 동시 접속자: 1,944명 (3인 1팀 대회)
  • 실제 최대 동시 접속자: 900명
  • 제출: 6042개
  • 분당 페이지뷰: 최대 3100회

이고

KCF2018은

  • 참가자 수: 6,000여명
  • 예상 최대 동시 접속자: 6,000명
  • 실제 최대 동시 접속자: 648명
  • 제출: 29,629개
  • 분당 페이지뷰: 최대 4000회

이었습니다.

CH2016의 동시 접속과 분당 페이지뷰는 BOJ의 트래픽과 합쳐있는 수치입니다.

지금 와서 결과만 놓고 비교해보면 BOJ의 입장에서는 두 대회는 거의 비슷한 규모의 대회였습니다.

UCPC 2020의 준비

UCPC 2020은

  • 참가자 수: 298명
  • 예상 최대 동시 접속자: 894명 (3인 1팀 대회)

로 예상했습니다.

지난 두 대회의 경험으로 분당 페이지뷰도 최대 4,000번이었기 때문에, 40,000번 정도까지는 버틸 수 있을 정도로 미리 준비를 해두었습니다. 그 이유는 2016년 2018년에 비하면 이용자가 매우 크게 늘어, 위의 수치는 평상시에도 서버만 조금 느려지면서 버틸 수 있는 수치가 되었기 때문입니다.

UCPC 2020의 진행

13시부터 참가자들이 점점 들어오기 시작했습니다. UCPC 2020을 포함한 전체 동시 접속은 지금까지 보지 못했던 수였고, 평소 최댓값의 3배를 넘겼습니다. 평소에 토요일과 일요일은 BOJ의 동시 접속이 평일에 비하면 많이 적은데, 이번 토요일은 평일 수준이었습니다. 진행 중이던 대회의 동시 접속은 매우 적기 때문에, 이 수치에는 영향을 주지 않습니다.

13시 50분부터 점차 페이지뷰가 늘더니 59분에 엄청난 수치를 찍으면서 BOJ, 그리고 BOJ와 관련된 모든 서버와 서비스가 에러를 계속 발생시키면서 정상적인 기능을 하지 못했습니다.

아직은 정확한 수치를 언급할 수 없지만, 제가 예상했던 트래픽이 평소의 60배였으면, 약 600배 정도의 트래픽을 발생시켰습니다.

임시 조치

트래픽과 관련된 문제이니 DB의 인스턴스 크기를 크게 증가시키고, EC2의 개수와 인스턴스 크기를 크게 증가시켰습니다. 이 작업은 대회를 앞둔 오늘 새벽에 약 1시간 반에 걸쳐서 했던 작업과 같은 작업인데, 훨씬 더 크게 증가시켰습니다.

일단 대회는 진행시켜야 하니 위의 작업으로도 해결이 안될 때를 대비해서, 새로운 환경도 함께 세팅하고 있었는데, 다행히 이 방법까지는 쓸 필요가 없어서 다행이었습니다.

작업이 진행되던 중에도 정말 매우 크게 낮은 확률로 새로 고침을 하다 보면 한 번 정도는 사이트 접속이 되기도 했었습니다. 이때문인지 3시까지의 트래픽은 평소보다 계속해서 많았습니다.

앞으로

이러한 문제의 발생을 막기 위해서 지난 1년간 BOJ의 구조도 바꾸고, 여러가지 수많은 개발을 했습니다. 그 동안 BOJ의 기능과 관련된 업데이트가 늦은 이유는 다 이러한 문제를 사전에 막기 위해서였습니다.

원인은 다르지만 작년 UCPC 2019의 문제에 비하면 해결 속도가 매우 빨라졌기는 합니다만, 이러한 문제가 다시는 발생하지 않는 것이 가장 중요합니다. 이러한 일이 발생하지 않게 하기 위해서 더욱 최선의 노력을 할 것이며, 이 일이 BOJ의 대회 시스템에 대한 신뢰를 잃어버린 것이 아니었으면 좋겠습니다.

앞으로는

  1. BOJ와 연결되지 않은 독립된 페이지에 서버 상태를 볼 수 있는 페이지를 만드려고 합니다.
  2. BOJ의 접속이 되지 않을때 이와 관련된 메시지를 BOJ에 볼 수 있게 하려고 합니다.
  3. 접속자가 많을 것으로 예상되는 큰 대회 뿐만 아니고, 작은 대회도 차질이 없게 하기 위해서, 위의 계산을 타이트 하지 않게 매우 넉넉하게 해서 어떤 상황도 대비하려고 합니다.
  4. 3번을 준비해도 혹시나 또 비슷한 사고가 발생할 수 있기 때문에, 대회의 전에 미리 백업(웹, DB, 채점 서버)을 상시 대기 시켜서 문제가 생기면 실시간으로 교체해 바로 대응할 수 있는 시스템의 구축

이 사건은 제가 예상했던 수치를 훨씬 넘어서는 값 때문에 발생한 사건입니다. 유저에게 트래픽을 위해 "대회 시작 전에 새로 고침을 누르지 말 것", "문제는 하나가 로딩 다 되고 다른 문제를 열 것" 이라고 얘기하는 것은 생각도 해본 적이 없는 말도 안되는 소리입니다. 악의적인 공격이 아니면 모든 것을 허용해야 하고, 악의적인 공격이라면 대비하고 막는 것이 올바른 웹사이트 운영의 자세라고 생각합니다.

대회 운영진이 대회가 진행되는 도중에 밥을 먹으면서 수다를 떨며, 참가자의 답안을 보면서 토론할 수 있는 환경을 약속드립니다.

다시 한 번 이런 서버 문제가 생겨서 죄송합니다.

모든 BOJ 유저 분들께 사과드립니다.

댓글 (2개) 댓글 쓰기


dbfldkfdbgml 13일 전

백준님 존경합니다.


baekjoon 11일 전

7/27 서버 점검을 통해 긴급 복구 시스템을 테스트했습니다.

오전 2시부터 UCPC 2020 예선 진행 중에 발생한 사고를 재현하기 시작했고, 2시 5분에 같은 상황을 만드는데 성공했습니다.

그 사이에 웹 서버와 DB서버에 접속해서 이것 저것 자료를 수집했고, 이 자료 분석을 통해서 같은 상황을 만든 것을 확신했습니다.

이후 2시 17분에 준비한 긴급 복구 시스템을 작동시켰고, 개발 서버는 그 즉시, BOJ는 2시 18분 정도 부터 정상 접근이 되었습니다.

이런 사고가 다시는 발생하지 않게 미리 막겠으며, 이 긴급 복구 시스템을 이용할 일이 없게 운영하겠습니다.