- Published on
9월 5주 있었던 일 정리
- Authors
- Name
- 이건창
Introduction
안녕! 이번 주는 연휴가 겹쳐 있어서 지난주에 아쉬웠던 부분을 메우는 시간을 가졌어.
1. 성능 개선은 정말 어렵구나
1. 페이징
한 번 데이터를 조회할 때 12,000건
씩 조회되서 페이징을 고려했어.
가장 고민이 많았던 건 페이지를 얼만큼 나눌지 기준을 세우는 일이었어. 페이지 단위가 너무 적으면 데이터베이스 접근 레이턴시 횟수가 높아지고 I/O
비효율이 존재했고, 페이지 단위가 너무 크면 데이터베이스 읽기 레이턴시로 인해 커넥션을 얻기 위해 대기하는 친구들이 많아졌어.
10,000건
으로 테스트를 수행했을 경우 커넥션을 획득하지 못해 커넥션 획득 시간인 3초
를 넘어가면서 예외가 발생하더라,,, 그래서 1,000건
으로 변경한 다음 테스트를 수행하니 문제가 발생하지 않았어.
이 과정에서 페이지 단위를 계속 수정하는 번거로움이 존재하더라구. 그래서 실행할 때 조절할 수 있도록 환경변수로 추출했어!
처음에는 성능이 좋아지겠지!
라는 무식한 생각으로 접근 했는데, 읽는게 빨라지는 게 아니라 느려지지 않게 하기 위한 방법이라는 것을 체감하게 됐어.
막역하게 성능이 좋아진다.
, 효율이 좋아진다.
이런 말들을 습관적으로 내뱉었는데, 왜 좋아지는지 모르고 남발했던 것 같아. 반성 해야겠어.
2. Redis 사용 그러나 미약한 성능 개선
현재 작업 프로세스는 폴더 단위로 사용자의 정보들을 저장한 다음 압축해서 전달하는 과정을 거치고 있어. 이러한 과정 속에서 파일 I/O
횟수를 줄이기 위해 레디스에 데이터를 모아뒀다가 한 번에 압축하도록 수정하는게 빨라짐을 예상 할 수 있었어. 결과적으로 파일 I/O
를 1/3
로 줄여 다음처럼 성능이 개선됐어.

생각했던 것보다 드라마틱한 효과는 없더라. 파일 I/O 횟수
보다 데이터베이스 접근 횟수
가 더 많아서 생기는 문제로 보였어.
현재 프로세스의 큰 문제는 데이터베이스에서 데이터를 조회하는 레이턴시였고, 이 과정에서 성능을 개선하기 위해서 비율이 가장 높은 작업을 찾아 개선을 해야 함을 깨달았어.
3. 간헐적으로 발생하는 SQLTransientConnectionException
1번
과 2번
과정에서 느낀건 속도를 빠르게 하기 위해서는 비율이 가장 높은 작업을 빠르게 해결해야 한다.
였어. 그래서 작업 비율이 가장 높은 SQL 실행 과정을 병렬로 실행하게 됐어.
어떻게 했냐면 SQL 문을 병렬로 실행해 여러 개의 리스트를 가져와 Thread-safe
한 컬렉션에 담도록 구현했어. 구현한 코드는 다음과 같아.
final var collections = new ConcurrentLinkedQueue<Feed>();
IntStream.range(0, page + 1).parallel()
.forEach(p -> feeds.addAll(getCollection(groupSeq, userSeq, pageSize, p * pageSize)));
이때 값을 추가하거나 값을 이터레이션 도는 경우가 많아 큐가 적합해 보였어. 만약 배열을 사용했다면 값을 추가하는 과정이 느리고 메모리 낭비도 심했을 듯 해.
배치를 돌리는 중에 SQLTransientConnectionException
예외가 터졌어. 커넥션을 얻기 위해 30초
이상을 기다려서 문제가 발생한 듯 해. 실은 이 문제가 1번
에서 터졌던 문제야. 즉, 커넥션을 얻으려고 기다리는 시간이 길어지다 보니 이런 문제가 발생하나봐. 그래서 커넥션 대기 시간을 늘릴지 커넥션 풀을 늘릴지 아니면 병렬 처리를 수행하는 스레드를 제한할 지 고민이 많았어.
커넥션 풀을 늘리자니 가용 할 수 있는 커넥션이 적었고, 커넥션 탕미 아웃을 걸자니 성능은 그대로일거고,,,
운영 환경에서 작업하게 되면 운영 리소스 중 가용할 수있는 리소스에 의해 작업 속도가 의존되는 상황에 부딪히더라. 그래서 풀백업 데이터베이스를 생성하기로 했어. 그 과정은 아래에서 설명할게.
mysql dump
vs xtrabackup
4. 팀 분들과 시니어 개발자 분들과 함께 고민한 끝에 운영 데이터베이스의 백업본을 생성해 배치용으로 사용했어.

백업하는 과정은 인프라팀에서 도와줘서 어떤 방법으로 백업하지?
만 고민해봤어. 백문이불여일타
처럼 나도 직접 해보지 않으면 모른다!
가 신념이기 때문에 먼저 테스트를 진행해봤어.
결과를 먼저 이야기하자면 mysql dump
로는 한계가 있었어 백업 속도가 EXPONENTIAL
형태로 뜀을 예상 할 수 있었기 때문이야. 이러한 원인으로 생각되는 문제는 I/O 바운드
와 CPU 바운드
로 인한 레이턴시였어.

DB 쓰기 작업이라 I/O 바운딩 을 예상했지만, CPU 바운딩 발생은 도커 메트릭으로 확인 할 수 있었어.

시행착오를 겪으면서 xtrabackup
으로 백업하는 시간을 현저히 줄일 수 있다는 것을 몸소 체감했지. 직접 경험을 정리하면 다음과 같아.
덤프 생성 | 물리적 백업 | |
---|---|---|
저장 방법 | mysqldump를 활용한 백업 | xtrabackup을 활용한 압축 백업 |
장점 | - 쿼리로 데이터가 관리되기 때문에 서로 다른 DB 버전에서도 사용할 수 있다. | - 백업 과정이 빠르다. |
단점 | - 덤프를 읽는 과정에서 일치하지 않는 데이터 형식으로 인해 일부 데이터를 읽을 수 없게 된다. - 추출하고 다시 백업하는 과정이 느리다. | - 지정된 버정이 아니면 백업이 불가능하다. |
데이터베이스를 직접 백업하 지는 않았지만 여러 방법으로 백업을 시도하고 테스트했던 시간은 굉장히 귀중했어. dump
를 수행하면서 중간에 오류나는 쿼리도 만나면서 어떻게 해결할지 고민도 많이 했어. (수천만건의 덤프 중 하나의 쿼리만 실패하면 정말 난감하겠더라구.) 이런 경험이 내가 어떤 개발자가 되고 싶은지를 확고하게 만들어주는 것 같아.
2. 실무와 테스트
1. 정책을 이해하는 것도 정말 중요하구나
정책 오류는 테스트로 잡기 어려웠어. 현재까지 느슨한 정책으로 수월하게 프로젝트를 구성했지만, 오픈에 가까워지면서 이러면 사용자들이 불편하지 않을까?
이런 고민들을 하게 됐어. 뒤늦게 발생하는 고민들이지만, 내가 불편하더라도 사용자들이 편한게 맞다는 생각이 들었다. 솔직히 열심히 만든건데 사용자들이 안써주는게 더 싫더라...
그리고 이런 고민들을 이해관계자들과 상의하면서 편리함과 제약을 동시에 경험했어. 내가 고민해야 할 범위가 줄어드는 장점이 있었지만, 상의하고 결정하는 과정이 오래걸렸어. 반대로 혼자 결정해야 했다면 자신감이 없어져서 행동에 제약이 있었겠다는 생각도 들었어.
코드로 모든 문제를 해결하는 건 불가능 해. 코드를 작성하기 전에는 정책을 최대한 이해하고 코드를 작성할 떄는 정책에서 풀어나가는 문제 만 해결하려고 신경써야겠어.
2. 정말 필요한 테스트가 무엇일까?
여유가 생기면 꼼꼼해지더라. 급할 때는 이슈 쳐내기 급급했는데 말이야. 어떻게 하면 이슈를 쳐내면서 테스트를 작성 할 수 있을지 고민이 되더라. 즉, 효율적인 테스팅이 주 관심사가 됐지. 그래서 추석동안 이펙티브 소프트웨어 테스팅
책을 읽으면서 어떤 코드를 테스트하지?
, 이 관심사는 격리해서 관리하는게 앞으로 편하지 않을까?
등의 고민을 했어.
첫 번째로 깨달았던 건 상태는 Null
, Empty
, One
, Many
단위로 관리하는 일이었어. 예시로 여러 개(Many
) 인 경우 순서 등을 테스트 해 볼 수 있어. 총 네가지 부류를 기준으로 어떤 테스트를 할 지 고민 할 수 있었지.
두 번째는 상용 버전에서 발생하는 버그 비용은 예방하는 비용보다 더 크다
는 말이었아. 상용 버전에서 버그가 발생한다면 클라이언트의 신뢰와 함께 손해를 배상해야 함을 생각한다면 수긍 할 수 있었지.
아직 책 초입이지만 저자의 경험을 체화하기 위해 어떤 지식을 바로 적용 할 수 있을까?
를 고민해보고 있어. 적용하게 된다면 바로 다음주 글에 작성해볼게!
3. 마지막으로
실무를 경험하면서 모든 상황에서 트레이드 오프를 고려해야하는 복잡함을 느겼어. 또한 성능 개선은 꾸준함을 느꼈어. 해도해도 개선 할 부분이 계속 나오더라.
그리고 결정을 내릴 때마다 더 좋은 방법이 있지 않을까 하는 아쉬움이 남았어. 결정 과정에서 복잡성을 낮추고 업무 이해를 높이기 위해서는 주변 지식이 풍부해야 함을 느꼈어.
제일 중요한 건 안정적인 시스템을 만들기 위해서 효율적으로 테스팅 하는 방법이 필요함을 느꼈다는 거야. 만들고 있는 서비스를 안정적으로 구축하기 위해서는 테스팅 지식이 꼭 필요해. 그래서 추석 동안 테스팅 책을 읽어볼 생각이야.