‘아무도 나에게 대규모 트래픽을 경험시켜 주지 않는다’라는 말을 누군가 했다는 걸 지나가다 주워들었다. 뭘 바라고 한 말일지는 모르겠다.다만 도움이 될 수 있다면 나의 이야기를 들려주고 싶다.어떤 기대가 있었는지는 모르겠지만, 다 듣고 나면 환상이 깨질지도 모르겠다.서문주제는 ‘대규모 트래픽’이다. ‘트래픽’이라는 말이 들어간 이 글에서 어떤 키워드들이 나올지 간단히 그림으로 설명하자면 이렇다. <출처: 작가> 다시 키워드를 글로 나열하자면 이런 것들이 있을 것이다. 말 그대로, 유저의 트래픽트래픽이 1차적으로 접근하는 인프라인프라가 트래픽을 전달해 줄 시스템시스템의 프로세싱으로 발생하는 로그시스템을 수정하고 로그를 검색하는 관리 도구 배경개발자를 처음 하던 당시, 나는 이 모든 걸 다 겪었다. 2018년 6월부터 2020년 3월쯤까지였다.(나도 시작부터 지상 최강의 개발자였던 것은 아니었다.) 또한, 회사 이름은 따로 언급하지는 않겠다.(이 글을 읽는 여러분 역시 혹시나 알 것 같다 해도 언급하지 않길 바란다.) 당시 나는 웹 퍼블리셔를 그만두고 개발자로 첫 커리어를 시작했고, 새로 간 회사에는 상장폐지라는 사건이 터졌다.300명 넘던 직원들이 일제히 피난이라도 가듯 도망쳐버려 제대로 된 인수인계 문서를 남길 틈조차도 없었던 듯하다. 나는 그런 일련의 사건 이후에 입사를 했다. 제대로 인수인계를 받을 사람도, 문서도 없이, 나보다 조금 먼저 정보를 습득한 동료들에게 정보를 공유받는 것이 고작이었다. 내가 맡은 일은 회사의 모든 인프라 관리 및 개발이었다. 아래 쓸 일들은 순차적으로 일어났다기보단 동시다발적으로, 혹은 연속으로 터져서 하나하나 준비할 틈이 없었다. (신입 개발자가 감당하기에도 꽤나 벅찬 일들이었다) 그렇게 우리는 항상 야근에 시달렸다. <출처: Limbus Company, 작가 편집> 정시 퇴근을 언제 해봤는지는 기억도 안 날 정도로 힘들었지만, 그래도 우리들은 우리 회사를 사랑했고, 우리의 일을 사랑했고, 그렇게 고생하는 우리들을 사랑했기에 어떻게든 버텨냈던 것 같다. 회사 바깥의 모든 사람은 곧 회사가 무너지리라 알고 있었지만, 의외로 회사는 지금까지도 건재하다. (비록 나는 후세(?)에 지독한 빌런이라고 전승되었다 해도) 뭐가 어찌 되었든 우리들의 고생이 헛되지 않았고, 그 결과로 회사가 지금까지도 건재하다는 사실에 감개무량할 뿐이다. 트래픽그때 내가 다닌 회사는 게임 퍼블리싱 기업이었다. 우리 회사가 개발한 게임을 직접 유통하거나다른 회사가 개발한 게임을 유통해 주거나 이런 일을 해서 돈을 버는 회사였다는 뜻이다. <출처: 작가> 퍼블리싱사이기에 회사는 플랫폼 서버를 따로 운용했다. (나는 플랫폼 개발팀이었다.) 그렇기에 모든 트래픽의 근원은 각각 게임 서버에서 오는 유저들의 트래픽이었다. 게임 서버가 유저의 트래픽을 견딜 수 있도록 관리해야 했고, 게임 서버들은 일제히 플랫폼 서버로 요청을 했기에 플랫폼 서버가 트래픽에 견딜 수 있게 관리도 해야 했다. 일 접속자와 동접자 상황당시 운영하던 게임은 3개였다. 하나는 다른 개발사에서 만든 게임을 퍼블리싱하는 것이었고, 구글/애플 게임 순위 100위 안에 드는 게임으로, 일 접속자가 수만 명 수준이었다. 동접은 수천명 정도. 하나는 회사에서 직접 개발한 게임으로, 구글/애플 게임 순위 150위 안에 드는 게임이었으며, 일 접속자는 만 명 전후였던 것으로 기억한다. 동접은 100~700 정도 왔다 갔다 했다. (나머지 하나는… 그만 알아보도록 하자) 이벤트가 열리면…다만 내가 입사했던 시기는 기존에 관리하던 사람들도, 인수인계 문서도 없기에, 어떻게 관리해야 할지 모르는 상황이었다. 그러다 각각 게임에 이벤트라도 열리면, 평소 수만 명이 몰리던 서버에는 수십 만명이 몰렸고, 백만 명이 넘어갈 때도 종종 있었다. 동접자가 십만 명을 넘기기 시작하면 그 트래픽은 약하디약한 서버를 죽이기에 부족함이 없었다. <출처: Limbus Company, 작가 편집> 그래서 입사 초반에 어떻게 관리해야 하는지 파악하기 전까지는 서버 장애가 굉장히 잦았으며, 모든 인프라와 시스템이 삐걱거렸다. 모든 상황이 우리에게 매 순간 포기를 종용하는 것 같았다. <출처: Limbus Company, 작가 편집> 하지만 나는 혼자가 아니었고, 동료들과 힘을 합쳐 어떻게든 수많은 역경을 헤쳐나갔다.우리들은 우리들의 회사를 사랑했고, 일을 사랑했고, 그렇게 고생하는 서로를 사랑했기에 말이다. 이때 ‘우리’는 개발팀 말고도 운영팀, QA팀과 사업팀 등등의 회사 구성원 모두를 뜻한다. 그래서 당시 우리는 서버가 터져서 서비스가 중단이 되면, 하루, 이틀, 아니 일주일 내내 퇴근을 못하면서도, 겨울에 패딩을 뒤집어쓰고 의자에 웅크려 장애 복구 조치를 했다. 교대로 돌아가면서라도 최대한 빨리 서비스를 복구하기 위해 노력했다. 인프라회사에서는 AWS도 사용했고, 배어메탈 장비를 IDC에 넣어놓고 운용하기도 했다. IDC에 들어 있는 장비는 6~7년 정도 연식이 있었다. (곧 초등학교에 보내야 할 정도였다) 이런 다수 장비를 Docker Orchestration으로 운용하기 위해 선조(?)들은 IDC에 fleet(deprecated)을 구축해 두기도 했다. (후에 이것은 엄청난 재앙이 되었다) 서버의 증설과 네트워크 접근 제어에서 생긴 문제이벤트가 열렸을 때 터지는 건 게임 서버였으므로, 게임 서버를 증설하려고 처음 시도했을 때 생긴 일이다. 서버를 증설하고 나니 게임을 플레이하는 유저들이 랜덤하게 에러를 만나고 있다는 제보가 들어왔다. <출처: 작가> 이해하기 쉽게 설명하자면 위와 같은 그림의 상황인데, 이 상황까지 이해하는 데도 꽤나 애를 먹었다. 우리는 제대로 인수인계받은 게 없었다. (계정과 pem 키 말곤 받은 게 없다고 할 정도로) 플랫폼 서버가 접근 제어를 deny all을 기반으로 allow list를 만들어서 운영한다는 걸 뒤늦게 깨닫게 되었다. 지금이라면 게임 서버 쪽의 outbound 지점을 하나로 묶고, static IP를 구매하여 public IP를 하나로 만들었을 텐데, 당시 경험과 지식이 부족한 우리들은 그런 걸 몰랐다. 그래서 이후에 게임 서버에 장애가 나서 한동안 꺼져 있다가 다시 켤 때, public IP가 바뀌는 일이라도 생기면 매번 플랫폼 서버의 접근 제어를 수정해 줘야 했다. 잘못된 오케스트레이션 구성이 부른 대참사IDC의 배어메탈로 구성한 fleet(deprecated)에도 문제가 생겼는데, 여러 개의 노드 중 하나가 장비 노후화로 죽었다. 보통 이런 경우엔 죽은 노드에서 실행되던 컨테이너가 여유가 있는 다른 노드에 뜨는 게 정상적인 동작이다. 그러나 fleet에 등록된 모든 컨테이너가 꺼졌다 켜졌다 하는 파도타기를 하기 시작했다. 대체 선조(?)들이 어떻게 설정했길래 이리된 건지는 알 수 없으나, 아무튼 상황은 그러했다. IDC로 달려가 배어메탈 장비에 직접 접근해 fleet 연동을 끊고 컨테이너를 수동으로 올려서 조치하려고 했다. 그러나 거기서 엄청난 변수를 만나게 됐다. 우리에겐 이 fleet node에 접근할 수 있는 pem 키도, 배어메탈 장비에 직접 로그인할 계정과 패스워드도 없었다. 결국 디스크를 뽑아 다른 서버에 집어넣고 마운트시켜 필요한 데이터를 복사하고 끄집어낸 다음, 컨테이너를 수동으로 올리는 것으로 해결했다. 그 뒤, fleet으로 등록된 모든 배어메탈 장비를 뽑아서 회사에 가져왔다.(쏘카를 빌려서 가져왔는데, 트렁크에 장비를 실으니 차가 약간 뒤로 누웠다) 회사에 가져와서 하나씩 켜보니 참 가관이었다. 어딘가 고장이 나서 안 켜지는 장비부터, 싹 밀고 클린설치 하려고 하니 디스크에 손상이 가있어서 못 쓰는 것도 있었고, 그런 것들을 전부 뜯고 재조립해서 쓸 수 있는 상태로 만들어 클린설치 한 다음 다시 IDC에 갖다 넣은 일도 생겼다. 시스템MongoDB 배어메탈 서버에 용량이 가득 찼던 일다루던 게임 중에는 MongoDB를 쓰던 게임이 있었다. 그 게임은 1TB SSD가 꼽혀 있는 배어메탈 서버 하나를 통으로 쓰고 있었다. (사실 사건이 터질 때까지 MongoDB를 쓰는지도 모르고 있었다. 정확히는, 앞의 수많은 사건에 의해 알 여력이 없었다.) 처음엔 replication을 만들어 그걸로 어떻게든 해볼 생각이었는데, master node에 전체 용량의 40% 이상 여유가 있어야 한다는 걸 알고 좌절했다. 앞에 언급한 fleet 사건이 터진 직후 생긴 일이라, 디스크를 뽑아서 다른 데 꼽고 할 용기가 나지 않았다. 부팅 잘 되던 걸 뽑아 다른데 꼽자마자 손상되어 못 읽는 상태가 되는 걸 눈으로 봤던 직후였으니 말이다. 그래서 우리는 rsync로 로컬에 data 폴더 전체를 복사해 왔다. 대략 6시간쯤 걸렸는데, 겨울에 패딩을 뒤집어쓰고 의자에 웅크려 앉아, 새벽에는 교대로 지켜보며 복사하다 이상이 생기는지 보고 있었다. 복사가 끝나고 나서, 안전을 위해 로컬 to 로컬로 하나 더 복사하는 데만 해도 한 시간 정도 걸렸던 걸로 기억한다. (짜잘한 용량의 파일이 너무 많았다) 8주년을 맞은 게임이다 보니, MongoDB도 2.6 버전을 쓰고 있었다. 2019년인 당시에도 굉장히 구버전이었던 걸로 기억한다. 너무 구버전이라 더 높은 버전으로 올려보고자 했는데, 더 높은 버전에서는 해당 data 폴더를 읽어 들이질 못했다. 어쩔 수 없이 2.6 버전 그대로, 10TB짜리 SSD로 데이터를 이전시켜 IDC에 갖다넣는 걸로 해결했다. Redis를 DB처럼 쓰던 시스템에 생긴 참사Redis Cluster가 나오기 전에 나온 설계라, codis라는 걸 사용한 서버가 있었다. 그러다 64GB 클러스터의 메모리가 꽉 차 게임이 터진 일이 벌어졌다. 우리는 codis 구성에 대해 인수인계받은 바가 없었기에, 이 사태가 터지기 전까지 알 길이 전혀 없었다. 서버가 터진 덕에 구조를 다 뜯어 보게 됐다. sentinel, proxy, 그리고 나머지 노드의 분배를 위해 3개의 그룹과 여러 데이터 노드를 나눈 다음, 128GB로 클러스터를 늘려 서비스를 다시 복구했다. 글만 보면 간단해 보이지만 우리는 이 복구 작업에 3일 밤낮을 매달렸다. 하지만 복구를 해냈다고 다 된 것도 아니었다. 서비스가 죽기 전, BGSAVE가 끝나지 못한 부분부터 유실이 일어났고, 유실이 일어난 부분 외에 손실되고 깨진 데이터들도 존재했다. 그래서인지 특정 유저들은 길드 정보가 날아갔다든가, 인벤토리 정보가 꼬였다든가, 그런 이상 현상들이 발생했고 이 부분도 복구하기 위해 굉장히 애썼다. 사실 근본적인 복구는 불가능했다. 복구 요청이 오는 유저들을 대상으로 장애 이전 상태를 참고해 되돌려 준다든가 하며, 아무튼 2달 가까이 굉장히 고생했던 기억이다. 이 장애 이후로는 게임의 업데이트를 위해 서버를 잠시 중지시킬 때면, Codis 노드 전체의 foreground SAVE 이후 dump.rdb 파일 백업과 현재 메모리 상태를 체크하는 과정이 추가되었다. 로그시스템을 운용하면 로그는 필연적으로 쏟아진다. (말 그대로 쏟아진다고 할 수 있다.) 엄청난 양의 로그를 보관하고, 그 로그를 검색해 유저의 문의를 처리하거나 오류가 있었는지 판별하기 위해 로그를 확인할 필요도 있었다. 그렇기에 로그는 보관도, 검색도 할 수 있는 시스템을 만드는 것이 중요했다. 연 3억 쓰던 Redshift를 없애고 ElasticSearch를 도입한 일기존에는 월 3,000만 원 가까운 지출이 나가던 시스템을 썼다. 앞에 벌어진 수많은 사건사고들이 있었기에, 여기까지 눈을 돌릴 틈이 없었다. 다만 무언가가 터질 때마다 고치면서 조금씩이나마 보완되었기에, 나중에는 꽤나 안정적으로 운영을 할 수 있는 순간이 찾아왔다. 그리고 그즈음 경영진들의 요청이 있었다.지출 비용을 좀 줄일 수 없겠느냐는 그런. 그래서 고민 끝에 가장 지출이 컸던 Redshift를 어떻게 해보기로 했다. 그전에는 게임 서버에서 나오는 로그를 전부 안에다 집어넣고 쿼리를 이용해 검색하는 시스템이 있었다. 선조(?)들이 처음 구축했던 시기에는 괜찮았을지 모르겠으나, 이미 시간이 많이 지난 시점에서는 한 번 검색하는데 6~30분이 걸리는, 고객센터 업무를 하는 동료분들에겐 애물단지인 시스템이었다. (돈도 월 3,000만 원씩 나갔고 말이다.) 결론만 말하자면, 데스크탑 한대에 RAM을 꽉 채워 넣고, 거기에 ElasticSearch를 구축해 2년 치 로그만 검색이 가능한 시스템을 장장 3개월에 걸쳐 구축했다. 비록 검색하는 데 7초~2분 정도 걸렸으나, 기존에 비하면 훨씬 빨랐기에, 조악한 시스템이었지만 고객센터 업무를 하는 분들은 다들 고맙게도 만족해 주셨다. 연 지출 3억 원을 아낀 시점에서만 해도 얼티메이트 위업이다. 그런데 한 번 지출을 줄이는 데 성공하니 경영진 입장에서는 “하면 되는구만”으로 인식했는지, 더 줄일 수 있냐고 꾸준히 압박이 들어왔다. 관리 도구모니터링 도구를 만들 여력이 없어 메신저 알림이라도 만들었던 이야기그때의 우리라고 프로메테우스나 그라파나를 몰랐던 것은 아니다. 그러나 직접 이를 구성하려면 많은 노력이 들어가야 했다. 그때 역시 당장이라도 게임 서버가 종종 터졌기에, 실시간으로 파악하고 조치할 필요가 있어, 우선 서버가 살아있는지 죽었는지 확인하고 메신저로 발송하는 알림을 만들었다. 전문적으로 인프라만 담당하고 관리할 사람이 없었기에 어쩔 수 없었다. 그런데 이상하지 않은가? 맨 처음에 “내가 맡은 일은 회사의 모든 인프라 관리 및 개발이었다”라고 했는데 그런 일을 할 사람이 없었다니? 좀 더 자세히 말하자면, 회사에서 근무하던 기간 내내 사건 사고를 수습하느라 휩쓸려 다녔기 때문에, 모니터링 도구라든가, 알림 시스템이라든가 하는 것들을 체계적으로 구축할 여유가 없었다 말하는 게 정확할 것이다. 마치며흔히 말하는 ‘대규모 트래픽 경험’이라는 건 이런 험난한 경험을 뜻하는 거로 생각한다. 당시 우리는 경험이 많지 않고 미숙했기에, 이런저런 실수를 하며 더 많이 고생하긴 했다. 다만 경험이 많은 지금의 나라도 대규모 트래픽을 받는 서비스를 담당하면, 조금 더 능숙할 뿐 이런저런 험난한 일을 당하고 있겠지 하고 생각한다. 대규모 트래픽 경험이란, 쉽게 경험할 수 없는 일이기도 하고, 그 경험이 쉬운 일이 아닐 거라고도 장담할 수 있다. 그러니까, 이력서에 가볍게 한 줄 쓸 수 있는 그런 것이 아니라, 줄줄이 쓰며 눈물이 떨어지는 수준의 고생이 뒤따를 거라고 말이다. (그리고 눈물을 닦으며 한 두 줄로 줄여야겠지) 그럼에도 그 대규모 트래픽이라는 거 경험해 보고 싶다면, 왜인지 퇴근도 못 하고 개고생해야 할 것 같은 자리가 생기면, 뛰어들어 보길 바란다. 그게 회사 내에서의 일이든 그런 이직 자리가 생기든 뭐든 말이다. P.S“우리 회사는 체계가 없어” 라고 불평을 하는 사람들을 종종 본다. 내 경험에 따르면, 체계적이어야 할 곳에 들어가는 전문가들은 적응 기간 따위 따로 없어도 다들 알아서 몇 시간 만에 적응을 마친다. 그리고는 마치 몇 개월 있었던 사람처럼 익숙하게 행동하며, 체계가 정해진 게 없더라도 알아서들 무언의 약속이 있는 듯 행동한다. 체계가 없다는 말로 내가 무엇을 얻고 싶었던 건지 다시 생각해 보길 바란다.<원문>'대규모 트래픽 경험'이라는 환상 - 1부 ©요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.