[ 접속자가 한계점을 넘어서면 문피아 사이트가 심하게 버벅되어 이용이 어려워지고 결재에도 심각한 영향을 미친다 ]
[ 서버이전 작업을 공지하고 진행하려 했었다 ]
[ 데이터가 방대하여 이전작업이 얼마나 걸릴지 짐작하기 어려워 작업을 연기했다 ]
사전에 공지까지 하고 준비했던 서버이전 작업이 무기한 연기되었다는 공지를 보았습니다.
100원짜리 글 팔아 매출 100억원을 넘긴다는 문피아라면(이거 정말 대단한 거잖아요) 개발팀에 전문가들이 다수 포진해있을 거라는 짐작은 하고도 남지만, 확인된 세 가지 사실과 비약이 심한 추론, 그리고 노파심과 기우를 섞어 되나케나 지껄여보고자 합니다.
1. 병목점
병목점을 정확하게 파악하는 것은 쉬운 일이 아닙니다. CPU가 99% 사용률을 지속적으로 보이고 있다고 해서 CPU 클럭도 높이고 코어 수도 두 배로 늘리면 해결될 줄 알았는데, 그래도 99% 사용률을 유지하는 경우가 많습니다. 그래서 모든 자원에 대한 총체적인 해석을 통해 정확하게 병목점을 파악해야 합니다.
대표적인 병목점은 연산 자체가 느려서 대기 세션이 점점 증가하는 CPU 병목이 있겠고, 메모리를 모두 쓰고도 디스크 스와핑을 엄청나게 해댄다면 메모리 병목도 틀림 없습니다. 그 밖에 데이터 입출력이 느려서 I/O 병목이 일어나기도 하고, 트래픽이 한계량까지 소진되어 네트워크 병목이 일어나기도 합니다.
문제는 CPU 병목이 아닌 다른 병목을 통해서도 CPU 사용률 99%를 유발시킬 수 있다는 데 있습니다. 당연하겠지요. 세션을 처리하고 빨리빨리 클로징시켜야 하는데 디스크 I/O 때문에, 트래픽 때문에, 메모리 부족으로 인한 느려터진 하드디스크 스와핑 때문에 CPU에서 처리중인 세션이 종결이 느려지고 대기중은 세션은 점점 늘어나고, CPU는 지금 연산을 요청하면 언제 답을 내려줄지 모르겠다고 하는 상황이 오면 CPU 부하 100%가 됩니다.
그래서 병목점을 파악하려면 먼저 해당 서비스와 어플리케이션의 특성을 정확하게 인식해야 합니다.
저는 C도 자바도 php도, 심지어는 html 소스 보는 것도 모르니 문피아가 어떤 형태로 서비스하는 지 알 수도 없고 따라서 병목점을 추정할 수도 없습니다. 다만 동영상을 스트리밍하는 것도 아니고, 게임엔진을 돌리는 것도 아니기에 결론적으로 보면 사용자의 브라우저가 요청하는 연재 문서, 즉 작은 파일을 사용자의 브라우저에 배달(delivery)하는 서비스일 것이며, 따라서 핵심은 CPU가 아니고 파일 I/O와 트래픽이 아닐까 생각합니다.
트래픽 병목이라면 작업 공지에 회선증설이라고 올라왔을 겁니다. 디스크 I/O 병목이었다면 고속 스토리지로 교체한다고 했을 것 같습니다. 그런데 서버이전이라고 했거든요. 왜 그랬을까, 문피아 서비스에서 CPU는 별 역할이 없고, CPU 연산 자체가 거의 없는 파일 배달이 주된 작업이라면 메모리도 쓸 일이 거의 없는데, 왜 서버이전이라고 작업공지를 내보냈을까. 이 의문이 여전히 가시지 않습니다. TCP나 I/O 병목인데, 혹시 잘못 판단하지는 않았을까. 그럴 리는 없겠지만.......
2. 병목의 해소
1) 트래픽
회선이 1Gb인데, 동접자가 너무 많으면 1Gb 회선을 하나 더 구매해서 트렁킹하여 2Gb로 서비스하면 문제는 그냥 해결됩니다. 그거였다면 저런 작업공지도 없었고, 30분 내로 작업이 마무리 되었을 겁니다. 그 문제는 아니라는 뜻이겠지요.
1Gb 회선을 다 쓰지도 않는데 속도가 안나오고 신규 접속이 안되어 대기하는 세션이 늘어나는 경우가 있습니다. 트래픽에 여유가 있다고 해서 TCP 세션을 무한정 받을 수 없기 때문입니다. 예를 들어 5천 세션을 처리할 수 있는데, 그 중 활성세션(ESTABLISHED)는 천개고 4천개는 클로징 대기세션일 수도 있습니다. 그래서 TCP 튜닝이 필요합니다. 오픈할 수 있는 파일 개수나 디스크립터 수도 최적화시켜야 하고 TCP 세션을 클로징하기 위해 대기하는 세션들(TIME_WAIT)을 서비스 특성을 해치지 않는 범위 내에서 빠르게 강제로 클로징시킬 수 있는 튜닝도 필요합니다. TCP 튜닝의 항목들은 아주 많습니다.
TCP 튜닝은 OS 차원에서도 해야하고, 웹서버 차원에서도, 컨테이너나 미들웨어들(WAS나 검색엔진 등의 어플리케이션 서비스)에서도 해야합니다. 필요하다면 DB에서도 해야할지 모릅니다.
2) 디스크 I/O
(1) 파일 개수
스토리지의 로지컬 볼륨 내에 파일 개수가 일정한 한계를 넘어서면 모든 서비스가 끝장나고 백약이 무효한 상태가 됩니다. 이건 대부분 알고도 당하고 모르고도 당하는 흔한 문제입니다. 꼭 한 번 제대로 당하고 나서야 문제의 심각성을 인식합니다.
어떤 파일작업을 하기 위해서는 볼륨매니저에게 파일 관련된 테이블을 받아야 합니다. 그런데 파일 개수가 너무 많으면 그 테이블 값을 받는데 시간이 걸립니다. 디렉토리 복사를 명령하면 볼륨매니저는 먼저 그 디렉토리에 대한 정보를 넘겨주는데 파일 개수가 수백만 개라면 그 정보를 구성하는데 몇 분, 길면 몇 십분이 걸리기도 합니다. 아직 파일이 넘어가지도 않았는데 말이죠. 파일 개수가 천만개 넘어가는 볼륨도 있던데, 그럴 경우 데이터 이전은 아주 난감해 집니다. 신규 파일은 다른 볼륨으로 넘기고, 그 볼륨은 읽기전용으로 바꾼 뒤에야 작업할 수 있는데 어떤 때에는 일주일 걸리기도 합니다.
그래서 서비스에 연결되는 파일 개수는 무조건 줄여야 합니다. DB에 때려박든, 여러 개의 파일을 레이어를 주어서 바이너리로 묶든 간에 파일 개수는 무조건 최소화 하는 게 답이고, 지나치게 늘어난다면 새로운 볼륨으로 넘겨야 합니다.
(2) 스토리지의 성능
요즘 스토리지는 올플래시(SSD) 디스크를 장착한 고속 제품이 많이 보급되었습니다. 값이 비싸겠지요. 문피아는 서비스 특성상 이런 고속 스토리지를 전술적으로 활용할 여지가 큽니다.
베스트 연재, 포스팅 된 지 1개월 이내의 모든 연재물은 이 고속스토리지로 서비스하면 사용자들은 정말 쾌적한 서비스를 받을 수 있습니다. 데이터들은 무거운 영상이나 이미지가 아니기 때문에 실 용량은 얼마 되지 않을 겁니다. 나머지 연재물 중 1년 이내에 포스팅 된 데이터들은 중속 스토리지(1만 rpm 정도의 디스크 어레이)에 배치합니다. 그 밖의 모든 연재물은 초저속, 초저가 스토리지(7200 rpm SATA나 NAS)에 배치해도 됩니다. 요청자가 거의 없으므로 요청하는 세션이 있어도 디스크 I/O에서 경쟁이 없으므로 금방 찾아서 보내줄 수 있습니다.
큰 비용을 들이지 않고도 모든 연재물을 쾌적하게 서비스할 수 있는 방법은 찾아보면 꽤 있을 겁니다.
(3) 캐싱 장비
캐싱장비는 자주 입출력하는 파일을 메모리에 보관하고 있다가 디스크 I/O를 거치지 않고 바로 보내주는 서버 시스템입니다. 캐싱되지 않은 데이터는 실 경로를 찾아가서 서비스하고 그 파일은 그 순간부터 메모리에 캐싱됩니다. 효과 만빵입니다.
주식 시세나 환율 시세 같은 정보는 초 단위로 변경되는 값을 반영해줘야 하므로 캐싱하기가 곤란합니다. 그런 데이터를 캐싱하려면 실시간 파일 변화를 반영해주는 다이나믹 캐시 같은 장비를 써야하는데, 값도 비싸고 기대만큼 효과가 안나올 때도 많습니다.
문피아는 그 정도로 실시간 반영할 필요도 없고, 캐싱되지 않은 데이터는 스토리지에서 실제로 찾아다가 서비스 해주므로 캐싱 데이터를 1분 단위로 설정해도 무난하리라 생각합니다.
캐싱장비는 돈을 주고 구매해도 되지만, 리눅스 기반에 오픈소스 캐시 툴을 써서 직접 만들어도 됩니다. 비용대비 효과를 생각하면 10대 정도 만들어 돌려도 됩니다.
전산의 일반론에 따라 생각나는대로 지껄여봤습니다. 아마도 전문가들이 있으니 이 문제들 외의 다른 문제였겠지요. 만일 되나케나 지껄였다는 이 게시물이 문피아에 상당부분 부합하고 있다면 TCP 튜닝이고 스토리지고 나발이고 간에 우선 급한 일은 CTO를 영입하는 것일텐데, 설마 그 정도는 아니겠지요.
늘 애쓰는 개발팀~~ 화이링!
Comment ' 26