menuhwang

[PUBG Analyzer] MySQL에서 MongoDB와 File System으로 변경 본문

프로젝트/개인

[PUBG Analyzer] MySQL에서 MongoDB와 File System으로 변경

menuhwang 2023. 8. 3. 15:30

문제

 Match 데이터 저장과 Telemetry 데이터 저장하는데 또 다른 문제가 생겨 MySQL에서 MongoDB와 File System 으로 변경하게 되었다.

Match와 Telemetry의 공통된 문제는 한 번에 너무 많은 데이터를 저장한다는 것이었다.

Match 데이터 하나 저장을 위해 약 125 + 1개에서 200 + 1개의 데이터가 저장되고, Match 데이터가 많을 때는 한 번 요청에 Match 250개를 저장해야하는 경우도 생겼다. 그럼 최대 250 * 200 = 50,000 개의 레코드를 저장해야하는 것이다.

 

로컬 환경에서 직접 테스트해본 결과 120개의 Match를 MySQL에 저장하는데 약 37초가 걸렸다. 그렇기 때문에 이전에는 데이터 저장 이벤트를 발행하고 핸들러가 비동기적으로 처리하도록 구현해둔 상태였다.

사용자 입장에서의 응답 속도는 개선되었지만, 서버의 리소스가 데이터 저장에 오랜 시간 사용되는 것은 변하지 않았다.

 

두 번째로 Telemetry의 경우, 하나 당 약 35,000개의 레코드가 존재하고 여러 로그 타입(데미지 로그, 킬 로그, 캐릭터 위치 등등)이 섞여있는 비정형 데이터인것이 문제였다. 기존에 사용하지 않는 데이터들은 버리고 필요한 데이터만 저장하도록 구현되어 있었지만, 다른 데이터들을 버리는 것이 아까워 모두 저장할 방법이 없을까 고민했다.

 

 

MySQL vs MongoDB : Match 데이터 저장 

MySQL에서 MongoDB로 넘어가고자 하는 이유는 성능때문이었다. 특히 저장 속도가 중요했다.

 

MySQL과 MongoDB 비교는 유튜브 영상을 참고했다.

 

MongoDB가 읽기성능 및 쓰기성능 모두 우수했다. 하지만, MongoDB의 경우 필드 하나를 수정하더라도 Document(레코드)를 다시 써야 하기에 MySQL보다 수정성능은 떨어졌다.

 

Match 데이터는 한 번 쓰여지면 수정할 일이 아예 없었기 때문에, 이 경우는 MySQL보다 MongoDB를 사용하는 것이 더 좋다고 판단했다.

 

MongoDB로 교체하고 로컬 환경에서 다시 테스트해본 결과 같은 120개 매치를 저장하는데 1초가 채 걸리지 않았다.

데이터 저장 시간이 눈에 띄게 단축되어 데이터 저장을 비동기적으로 처리하는 로직도 삭제하고, 캐싱 레이어도 PUBG API 호출 유틸에만 남겨두었다.

 

File System

Telemetry를 다 저장하자니 Match 하나 당 약 35,000 이상의 레코드를 저장해야해 시간이 오래걸리고 비정형 데이터이다 보니, RDBMS에 저장할 수 있도록 파싱하는 과정에 너무 많은 비용이 들었다.

또 다른 문제로는 동시에 같은 Match의 Telemetry를 '처음' 조회하는 경우(DB에 데이터가 존재하지 않아 PUBG API 호출 후 DB에 저장) 또는 조회 시간이 길어 새로고침을 하는 경우, 같은 데이터가 중복으로 두 세트 이상 저장되는 문제가 있었다.

이 문제는 더티 리드로 더블 체크를 하여 해결하였지만, 격리수준으로 READ UNCOMMITED를 사용하는 것은 권장되지 않는다고 하여 수정하고 싶은 생각이 있었다.

 

마침 Match도 MongoDB에 저장하기로 하였기 때문에 Telemetry도 MongoDB에 저장하기로 했다.

아래와 같은 형태로 하나의 Document에 Telemetry를 저장하려고 하니 에러가 발생했다.

{
    "matchId" : "~~~~~",
    "telemetries" : [...]
}

Document 사이즈가 16MB 이상이라 GridFS를 사용해서 저장하라는 에러였다.

 

MongoDB도 아직 다 제대로 못 써봤는데 GridFS까지...?

 

그래서 우선 File System으로 직접 json 파일을 저장하도록 했다. 추후 aws s3로 유연하게 변경할 수 있다고 생각했다.

 

FileSystem을 사용하면 동시에 요청이 들어오는 경우에 같은 파일 이름으로 같은 데이터가 저장돼 데이터 중복이 발생하지 않았고, 데이터를 저장하는데 걸리는 시간도 MySQL보다 더 빨랐다.

 

정리

Match 저장에 MongoDB를 사용한 이유

1. 많은 데이터의 빠른 쓰기 필요.

2. 데이터 수정이 없음. (MongoDB의 느린 수정 속도가 단점이 되지 않음)

 

MySQL보다 MongoDB가 성능적 측면에서 적합하다고 판단.

Telemetry 저장에 File System을 사용한 이유

1. 버려지는 데이터 없이 모두 저장 필요.

2. 비정형 데이터이다. (RDBMS에 맞게 파싱하는데 비용이 많이듬)

3. 역시 많은 데이터의 빠른 쓰기 필요.

4. 데이터 수정 없음.

 

 

Comments