BOJ의 Good Bye, BOJ 2020!

12월 26일

2020년 12월 26일 토요일, 이 날은 BOJ에서 7개의 대회가 동시에 열린 날이었습니다. 이 날은 17시 23분부터 48분까지 채점 현황이 너무 느린 문제가 발생했습니다. 제출은 정상적으로 되지만, 제출 후에 바로 넘어가야하는 채점 현황 페이지가 열리지 않아 제출이 정상으로 되었는지 확인을 할 수 없는 문제가 있었습니다. 채점 현황이 너무 느려 채점이 약 5분 정도 밀려 결과를 볼 수 없었습니다.

지난 블로그: 2020년 7월 25일 서버 사고 이후 약 2달간 당시 사고를 재현해보고, 원인이 무엇이었는지, 각 원인이 어떤 연관 과정을 가졌는지 파악하는데 성공했습니다. 이후 일부 대비를 했지만, 원활한 대회 진행에 방해가 되는 현상은 피할 수 없었습니다.

그래프로 보면 다음과 같이 대회 중반에 웹 서버의 평균 응답 시간이 매우 증가하는 것을 볼 수 있습니다.

당시의 접속자 수는 25일의 75% 수준밖에 되지 않았고, 25일부터 31일 중에 가장 접속자가 적은 날이었습니다. 제출은 25일보다 30%정도 많기는 했지만, 그렇게 채점에 문제가 될 정도는 아니었습니다.

분명 UCPC 2020 예선에서 문제가 되는 부분을 모두 고쳤는데, 왜 이렇게 되었는지 의문이었습니다. 원래는 26일 멋지게 대회 7개를 마무리하고 블로그에 글을 쓰려고 했으나, 서버 다운은 아니지만, 채점 현황이 느려져버린 상황이 발생해 아직 그정도는 아니라는 사실을 알았습니다.

당일 대회 중과 후에 열심히 원인 분석을 한 결과 저는 이 것이 사이트의 느린 속도가 중첩되서 나타나는 현상이라는 판단을 내렸고, 이 날부터 BOJ 페이지 곳곳의 속도를 빠르게 끌어올리는 작업을 시작했습니다.

12월 27일

대회가 종료된 26일 18시 이후부터 바로 작업에 시작했습니다. 가장 먼저 손을 볼 곳은 채점 현황입니다. 채점 현황에서 가장 문제가 되는 부분이라 생각했던 곳은 학교와 그룹의 채점 현황입니다.

791명이 있고, 제출이 57만개 정도가 되는 서울대학교의 채점 현황은 로딩이 60초가 넘어 504 Gateway Time-out이라 페이지를 보는 것이 불가능했습니다. 인원이 498명, 제출이 27만개인 KAIST의 채점 현황은 기존에 약 24초 정도 걸렸습니다.

그룹도 상황이 좋지는 않습니다. 제출이 많은 유저가 있는 그룹은 채점 현황이 10초 이상 걸렸었습니다.

관련된 작업이 오래 걸리기 때문에, 27일 오전 10시 정도에 마무리할 수 있었고, 이를 사이트에 공개했습니다. 현재는 모두 매우 빨라졌습니다.

학교와 그룹이 마무리된 이후 바로 유저 채점 현황도 살펴보기 시작했습니다. 슬랙을 통해 @yukariko 님의 채점 현황을 보는 것은 불가능하다는 제보를 받았습니다. 제출 수로 정렬해서 상위 5,000명의 채점 현황 첫 페이지가 로딩되는 시간을 조사해보았고, 가장 오래 걸리는 분은 1분 4초였습니다. 504 에러의 기준이 60초이니 채점 현황을 볼 수 없었습니다.

유저는 오전 11시에 작업을 마쳤고, 바로 BOJ에 공개했습니다.

이후 다른 곳을 살펴보니 대회 스코어보드를 만드는 부분에 문제가 있었습니다.

BOJ의 대회에는 거의 알려지지 않은 기능인 공식/비공식 참가자 기능이 있습니다. 이 기능은 스코어보드에는 "비공식" 참가자를 보여주지 않고, 대회 운영진만 볼 수 있는 전체 스코어보드에 보여주는 기능입니다. 이 기능을 추가한 것은 UCPC 2018 입니다. UCPC 2018 이후로 계속해서 스코어보드가 느려지고 있었던 것이었습니다. UCPC 2018 이전보다 대회 참가자의 수는 약 5배 정도 늘었기 때문에, 더욱 느려지고 있었습니다.

공식/비공식 참가자 기능을 조금 더 효율적으로 바꿔 스팟보드와 BOJ 보드의 json 생성 속도를 약 20배 끌어올렸습니다.

12월 28일

다음 느린 페이지는 랭킹입니다. 총 세 종류의 랭킹 페이지가 느린데, 전체 유저의 랭킹, 언어 랭킹, 결과 랭킹이었습니다. 이 페이지도 속도를 빠르게 하기 위해 작업을 시작했습니다.

그 사이 solved.ac 유저 티어를 유저 페이지에 보여주는 업데이트를 진행했습니다.

랭킹 페이지의 작업이 진행되는 동안 느린 맞은 사람 페이지를 업데이트하는 작업을 시작했습니다.

1000번과 같이 맞은 사람이 매우 많은 문제는 로딩하는데 시간이 너무 오래 걸렸었습니다. 이 부분도 빠르게 만드는 작업을 시작했습니다.

12월 29일

개선된 맞은 사람 페이지를 공개했습니다.

느린 다른 페이지를 찾다가 학교/그룹 채점 현황이 과거의 시점으로 넘어가면 다시 또 매우 느려지는 현상을 발견했습니다.

이 문제는 금방 해결했지만, 갑자기 27일의 해결책이 마음에 들지 않았습니다. 또 먼 미래에 이런 일을 적게 하기 위해서 27일에 했던 그룹/학교 채점 현황 관련 작업을 다시 하기로 했습니다. 27일보다 DB에서 할 일이 많아 레플리카를 만들고 거기서 작업하기로 결정했습니다.

12월 30일

DB 레플리카에서 BOJ의 미래를 위한 다양한 작업을 준비 및 수행했습니다.

일단 학교/그룹 채점 현황이 과거 시점에서 느린 문제는 DB 작업 없이도 해결할 수 있는 문제이기 때문에, 공개했습니다.

자려고 하는데 갑자기 채점 속도를 빠르게 만들 수 있다는 생각이 들었습니다. 채점 속도를 조금 빠르게 만들었습니다.

위 동영상은 같은 소스를 서로 다른 채점 프로그램으로 채점한 것입니다. 위는 채점의 진행 속도를 높인 채점 프로그램, 아래는 기존의 채점 프로그램입니다. 동일한 소스이기 때문에, 동일한 결과가 나오는 것은 맞지만, 결과를 조금 더 빠르게 받아볼 수 있습니다.

12월 31일

28일에 랭킹 페이지의 속도를 빠르게 만드는 작업을 했는데, 이를 공개하는 것을 잊고 있었습니다. 늦었지만 이를 공개했습니다.

이날은 무려 2년 3개월만에 BOJ를 닫고 점검을 했던 날입니다.

29일부터 DB 레플리카에서 진행했던 작업을 BOJ에 적용할 시점이 되었습니다. 곧 열릴 대회를 위한 속도 향상도 대폭 포함되어 있어 대회 전에 꼭 수행해야 했습니다.

오늘 해야 하는 작업은

  1. BOJ 점검 페이지 전환, 채점 프로그램 모두 종료
  2. 레플리카 승격
  3. 구 BOJ DB와 새 BOJ DB의 엔드포인트 교환
    1. 구 BOJ DB 엔드포인트 변경
    2. 새 BOJ DB 엔드포인트 변경

입니다.

대회가 7시 반부터 시작이기 때문에, 빨리 작업을 마쳐야 합니다.

작업은 5시 20분에 시작하는 것을 목표로 했으나, 레플리카의 싱크가 생각보다 더 오래걸려 5시 40분부터 시작하게 되었습니다.

이 작업을 시작하기 전에, DB 엔드포인트를 변경할때 걸리는 시간을 계산해보았는데, 길어야 약 5분 정도 시간이 걸렸었습니다. 따라서, 점검 시간 20분은 넉넉한 시간이라 생각했습니다. 이 작업이 5시 54분에 시작되는 바람에 시작과 동시에 점검 시간을 6시 10분까지로 연장했습니다.

문제는 레플리카 승격에 있었습니다. 레플리카가 승격될떄 DB를 백업하는 것이었습니다.

레플리카의 승격과 동시에 백업이 시작되었는데, 이 작업이 도저히 끝날 기미가 보이지 않았습니다.

백업이 얼마나 걸릴지 찾아보기 시작했고, 구 BOJ DB가 정기적인 백업을 수행하고 있다는 것이 생각났습니다. 이벤트 로그를 보니 28분 정도 걸렸습니다. 따라서, 점검 시간을 6시 40분까지로 연장하게되었습니다.

백업이 종료되는 예상 시간은 6시 23분이었습니다. 엔드포인트 변경은 5분도 정도 걸리니 시간은 넉넉합니다.

약속의 6시 23분이 되었고, 백업은 종료되지 않았습니다.

이때부터 비상 대책을 생각하기 시작합니다. 대회는 어떻게든 7시 30분에 시작되어야 하고, 대회 전에 미리 사이트를 열어 놓아야 사람들이 들어와서 기다리기 시작합니다.

구 BOJ는 혹시 모를 사태를 대비해 삭제하지 않았으니 다시 원래의 엔드포인트로 변경하고 다시 BOJ를 켜면 사이트는 정상 동작하게 됩니다. 이 작업은 서버 점검과 동시에 한 번 수행한 적이 있고, 시간이 얼마 걸리지 않습니다.

AWS CLI를 찾아보니 DB 스냅샷의 진행 비율을 볼 수 있습니다. 이것으로 진행 비율을 보니 6시 30분 경에 57%(정확하게 기억이 나지는 않지만 56-58 사이)였습니다. 진행 비율이 일정하게 오른다는 가정하에 백업 종료시간을 예상해보니 6시 58분입니다. 마지막으로 서버 점검을 7시 10분까지로 연장했습니다. 7시까지 이 작업이 되지 않으면 구 BOJ DB를 사용하기로 했습니다.

스냅샷 진행 비율은 1% 단위로 올라가지 않았습니다. 계속해서 같은 비율을 보여주다가 갑자기 바뀌는 모양입니다.

이후 60%대로 올라간 이후, 6시 37분 74%였고, 6시 44분에 94%로 올라갔습니다. 희망이 보입니다.

6시 51분 진행 비율이 100%가 되었고, 6시 53분에 드디어 백업이 완료되었습니다.

바로 엔드포인트 변경 작업을 시작했고, 이 작업은 6시 58분에 완료되었습니다. 7시 10분까지는 아직 남은 시간이라 BOJ 개발 서버에서 여러가지 테스트를 수행해보고 7시 7분에 BOJ를 다시 오픈했습니다.

위 그래프는 12월 31일 오후 5시부터 7시 30분까지의 웹 서버의 평균 응답 시간으로 점검이 진행 중인 동안 요청이 없어 응답 시간이 0인 것을 볼 수 있습니다.

대회는 항상 시작하는 시점이 가장 트래픽이 많은데, 시작하는 시점 7시 30분을 보면 점검 이전과 평균 응답 시간이 크게 차이가 없다는 것을 볼 수 있습니다.

그런데, 문제는 갑자기 7시 45분에 발생합니다. 평균 응답 시간이 급증하는 것입니다. 이 현상은 8시 46분까지 지속되었습니다.

이 사실을 8시에 눈치채고 원인 분석을 시작했고, 주최자로부터 스코어보드가 조금 느린것 같다는 연락이 19분에 왔습니다. 8시 20분 지금까지 수 많은 작업에도 숨어있으면서 살아남은 문제의 부분을 발견했고, 이를 모두 수정, 26분에 배포를 시작합니다. 배포는 8시 46분 정도에 완료되었고, 이후 평상시와 다름없는 평균 응답 시간을 보여주게 되었습니다.

대회는 이후 문제 없이 종료되었습니다.

대회 종료

참가자는 총 578명으로 BOJ에서 열린 오픈 대회의 규모로는 역대 최대입니다. 큰 문제없이 대회가 종료되어서 다행이며, 다행히 대회 중에 발견되지 않은 문제점을 하나 발견해 수정했고, 이후 사이트의 속도가 매우 정상으로 돌아왔습니다.

대회가 종료되면 BOJ는 대회 문제를 공개해야 합니다. 대회 문제는 대회 주최자가 공개를 요청한 시점부터 공개 절차에 들어가며, 전체 문제의 공개는 약 30분-1시간 정도 소요됩니다.

대회의 주최자는 저에게 가능한 이른 시점에 공개를 요청했고, 바로 대회 문제 공개 절차를 시작했습니다.

이와 동시에 대회의 모든 정보와 제출을 덤프떠서 주최자에게 제공했고, A번 문제의 solved.ac 리딤 코드도 모두 제공했습니다.

대회의 문제가 스코어보드 오픈 방송의 종료보다 먼저 공개되어버려 새로 추가된 문제가 대회 결과의 스포일러를 해버리고 말았습니다.

과거 대회 주최자와의 소통이 원활하지 못해, 문제가 있던 적이 있었습니다. 이것도 역시 가장 큰 문제 중 하나라 생각되어 대회 시간 내내 계속해서 지속적으로 대회 주최자에게 현재의 BOJ 현황에 대해서 업데이트 하고 있습니다. 앞으로도 원활한 소통을 유지하겠으며, 더욱 많은 정보를 대회 주최자에게 제공하겠습니다.

카카오 코드 페스티벌 2018 예선 대회 개최 후기를 보면, 대회가 진행될 수록 서버의 평균 응답 시간이 점점 늘어나는 현상에 대해서 설명하고 있습니다. 이 현상을 발견했을 때 미리 수정했더라면 UCPC 2019, UCPC 2020와 같은 사건은 일어나지 않았을 수도 있는데 많이 아쉽습니다.

이 사이트는 제가 2010년 오픈 소스 프로젝트를 설치해서 운영하는 것으로 시작해, 2012년 새롭게 다시 전체를 작성, 현재까지 이어지고 있는 사이트입니다. 과거 웹 프로그래밍의 수준이 높지 않은 시절 작성했던 수많은 코드들이 현재 문제를 일으키고 있어, 사이트의 내부 소스를 전면 수정 중입니다. 블로그: BOJ의 2020년 마무리에 약속한 것 처럼 2021년 많은 일을 해보겠습니다. 사이트의 방문자가 10만, 100만명 처럼 그렇게 높은 수치도 아닌데, 자꾸 서버 문제를 일으켰던 과거가 너무 후회됩니다.

앞으로 대회 때도 아무 문제 없고, 평상시에도 아무 문제 없는 BOJ를 만들기 위해서 노력하겠습니다.

새해 복 많이 받으세요. Happy New Year!


댓글 (6개) 댓글 쓰기


xkdlaldfjtnl 18일 전

ㄱㅏㅁㅅㅏㅎㅏㅂㄴㅣㄷㅏ ㅅㅐㅎㅐㅂㅗㄱ ㅁㅏㄴㅎㅇㅣ ㅂㅏㄷㅇㅡㅅㅔㅇㅛ ㅇㅗㅐ ㅇㅣㄹㅓㄴㅡㄴㅈㅣ ㅁㅗㄹㅡㄱㅔㅆㄴㅖㅇㅛ


xkdlaldfjtnl 18일 전

ㅁㅗㄷㅜ happy AC year ㄷㅗㅣㅅㅔㅇㅛ


nahwasa 15일 전

좋은 시스템 만들어주셔서 감사합니다.


bally14 15일 전

새해 복 많이 받으세요^^


spectaclehong 15일 전

매 대회에 좋은 환경을 꾸리는 데 힘써주셔서 정말 감사합니다 ^0^


yedamdamdam007 8일 전

아이구 백준 제출량이 늘어서 오류가 생겼는데...좋아해야 할지...ㅎ