일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 생성 패턴
- 논문 정리
- 오블완
- amazon ecs
- terraform
- 지표
- 14일 공부
- 도커 주의사항
- leetcode
- 청첩장 모임
- 신혼 여행
- ssh
- MAPF
- Playwright
- github
- PostgreSQL
- Go-lang
- 실용주의 프로그래머
- DevOps
- AWS
- 디자인 패턴
- Monthly Checklist
- 티스토리챌린지
- AWS 비용 절감
- Rust
- 경로 계획 알고리즘
- docker
- 구조 패턴
- Til
- study
- Today
- Total
밤 늦게까지 여는 카페
[번역] 2023-04-04 피그마 인프라팀의 "The growing pains of database architecture" 본문
안녕하세요. 날씨가 선선해져서 그런가 주변에 결혼하시는 분들이 많네요 ㅎㅎ
이번에는 2023년 4월 4일 작성되었던 피그마 인프라팀의 "The growing pains of database architecture" 글을 간단하게 정리하려고 합니다.
1. 피그마 인프라팀이 발견한 DB 병목 문제
2020년도에는 단일 RDS 서비스에 데이터베이스 인스턴스를 1개만 사용하고 있어서
사용자가 늘어났을 때의 트래픽을 충분히 대응하지 못하는 상황이었다고 합니다.
- 실제로 당시 트래픽에서도 DB 인스턴스의 CPU 사용률이 65%까지 치솟는 것을 확인했다고 합니다.!
=> 피그마 인프라팀은 개선의 필요성을 느꼈습니다!
하지만 피그마는 이미 서비스 되고 있는 제품이었기 때문에
서비스를 잠깐 중단하고 DB 성능을 개선하는 시간을 가질 수 없었죠...
그래서 근본적인 해결책을 찾기 전까지 늘어나는 트래픽에 대응할 수 있는 방법이 필요했습니다.
2. 늘어나는 트래픽에 피그마 서비스를 지켜줄 임시 방편
피그마 인프라팀이 찾은 임시 방편은 다음과 같습니다.
- RDS 인스턴스 r5.12xlarge 에서 r5.24xlarge로 업그레이드
- 읽기 복사본 인스턴스 생성
- 기존 데이터베이스의 성능 부하가 늘어나지 않도록 기존에 제공하던 기능들까지만 기존 데이터베이스를 사용하도록 함
- PgBouncer를 사용해서 connection pool도 관리함
저는 PgBouncer를 Postgres 서버용 로드밸런서라고 이해하고 글을 읽었습니다.
혹시 더 궁금하신 분들은 https://www.pgbouncer.org/ 를 참고해주세요!
=> 피그마 인프라팀은 여기까지 작업을 진행하고, DB를 어떻게 개선해야 할지 고민했다고 합니다.
Q. 이 작업들만으로도 충분한 거 아니에요? 읽기 복사본도 만들었던데
피그마 인프라팀은 위의 작업들을 진행하면서 DB 트래픽을 분석해봤는데
수정, 삭제 등의 write 작업이 DB utilization에 큰 영향을 끼치는 것을 알게 되었다고 합니다.
write 작업의 영향이 크므로 읽기 복사본만으로 문제를 해결할 수 없었고,
read 작업 또한 읽기 복사본으로의 데이터 복사 지연 시간이 어플리케이션에 꽤나 영향을 많이 줬다고 합니다.
write, read 작업 모두 근본적인 한계가 있었기에 보다 장기적인 해결책을 찾게 되었다고 합니다.
3. 첫번째로 알아본 방법: horizontally scaling(수평 확장)
피그마 인프라팀이 가장 먼저 알아본 방법은 수평 확장이었다고 합니다.
하지만 당시에 많이 쓰였던 관리형 수평 확장 솔루션들은 피그마가 사용하고 있는 Postgres을 지원하지 않았다고 합니다.
그래서 가능한 선택지가 NoSQL을 사용하거나 self-hosting(셀프 호스팅)을 하는 것이었다고 합니다.
하지만 다음과 같은 이유로 모두 기각되었습니다...
1. NoSQL로의 전환은 너무 큰 어플리케이션의 변경사항을 요구해서 기각
2. self-hosting은 피그마 인프라팀이 수행하기에 역량도 부족하고, 지출하는 비용도 너무 크다고 판단해서 기각
결국 수평 확장으로 문제를 해결할 수 없었습니다.
4. 다음 희망: vertically partitioning(수직 파티셔닝)
다음으로 알아본 방법은 수직 파티셔닝이었다고 합니다.
테이블의 데이터를 여러 DB 인스턴스에 분배하는 대신 - 수평 확장
테이블들을 그룹화하여 각 그룹들만의 DB 인스턴스를 만들기로 결정한 것이죠! - 수직 파티셔닝
수직 확장은 단기적으로는 기존 DB 인스턴스의 부하를 줄여주고
장기적으로는 테이블들을 수평 확장할 수 있는 방법을 제공할 수 있는 좋은 방법이었습니다.
5. 수직 파티셔닝 ok! 그런데 테이블을 어떻게 나눌거에요?
수직 파티셔닝을 하기 위해서는 테이블들을 적절히 나눠야 합니다.
피그마 인프라팀은 Impact와 Isolation이라는 지표를 만들어서 테이블을 선정했다고 합니다.
- Impact
- 테이블을 나눴을 때, DB 인스턴스의 부하가 줄어드는 정도
- 일반적으로 클수록 나누는 것을 고려함
- Isolation
- 다른 테이블과의 결합도
- 일반적으로 작을수록 나누는 것을 고려함
테이블의 Impact 지표를 측정하기 위해 DB로 요청하는 쿼리들의 AAS를 측정했다고 합니다.
- pg_stat_activity 명령어를 10ms마다 실행해서 각 쿼리들의 cpu 사용량을 측정한 뒤, 테이블 이름으로 취합했다고 하네요!
하지만 Isolation 지표를 측정하는 것은 꽤나 어려웠다고 합니다.
피그마는 Ruby와 ActiveRecord을 사용하고 있기 때문에 테이블들과의 결합도를 정적 코드 분석으로 알아내기 어려웠습니다.
ActiveRecord를 Ruby의 ORM 라이브러리로 이해했습니다.
혹시 더 궁금하신 분들은 https://guides.rubyonrails.org/active_record_basics.html#what-is-active-record-questionmark 를 참고해주세요!
그래서 피그마 인프라팀은 동적 분석을 하기 위해서
ActiveRecord에 훅을 붙여서 어떤 쿼리가 사용되는지 Snowflake라는 데이터 웨어하우스 서비스로 전송했습니다.
수집된 쿼리들을 분석해서 동일한 테이블들을 조회하고 워크로드가 큰 녀석들을 대상으로 파티셔닝을 진행하기로 결정했다고 합니다.
6. 이제 진짜로 데이터를 옮겨야 하는데 주의할 것이 없나?
데이터를 이관하는 것은 단순한 작업이 아닙니다.
잠깐 서비스를 중단하고 데이터를 옮기는 것은 쉽지만 피그마는 다운타임이 없는 서비스!
피그마 인프라팀은 서비스를 정상 운영하면서 데이터를 옮기기 위해 다음 3가지 목표를 세웠다고 합니다.
- 가용성에 1분 미만 영향 줘야함
- 자동화 가능해야 함
- 중간에 문제가 발생한다면 진행된 파티셔닝 작업을 Undo 할 수 있어야 함
아쉽게도 이 목표들을 만족하는 상용 솔루션이 없어서 피그마 인프라팀이 자체 제작했다고 하네요.
7. 피그마 인프라팀이 만든 솔루션
피그마 인프라팀이 만든 솔루션을 추상적으로 설명하면 다음 6단계의 과정이라고 합니다.
- 모든 클라이언트 프로그램들이 수직 파티셔닝을 지원할 때까지 대기합니다.
- 기존 데이터를 새로운 DB에 복사함. 복제 지연 시간이 거의 없어질 때까지 대기합니다.
- 기존 DB로 사용하는 기능을 일시 정지시킵니다.
- DB들이 동기화 되는 것을 기다립니다.
- 쿼리 요청을 새로운 DB로 라우팅합니다.
- 3에서 일시 정지시킨 기능을 재개합니다.
사실 피그마 인프라팀은 1번을 가장 걱정했다고 합니다.
클라이언트 프로그램도 다양하고, 서비스의 백엔드도 너무 복잡하다보니 누락된 것이 있을까 걱정을 많이 했다고 해요.
이를 해소하기 위해서 피그마 인프라팀은 PgBouncer 레이어를 하나 추가하고
PgBouncer만 DB 인스턴스에 접근 가능하도록 설정했다고 합니다.
클라이언트 프로그램의 수직 파티셔닝 지원 여부를 PgBouncer 레이어 지원 여부로 확인할 수 있게끔 말이죠!
8. 진짜 데이터 옮기기 - logical replication
Postgres에서 데이터를 복사하는 방법은 streaming replication과 logical replication 2가지 방법이 있는데
피그마 인프라팀은 다음 3가지 장점 때문에 logical replication을 선택했다고 합니다.
- 테이블의 일부분도 가능한 복사
- 메이저 버전이 달라도 가능한 데이터 복사
- 역복사(Undo)도 가능
그렇게 데이터를 복사하는데 예상치 못한 속도 문제가 발생했다고 합니다. 너무 느린 것이었죠!
살펴보니 데이터를 복사하면서 행 하나가 바뀔 때마다 인덱스가 갱신되는 것이 원인이었다고 합니다.
데이터 복사가 끝나고 인덱스를 갱신하도록 조치하는 것으로 문제를 해결했다고 하네요 ㅎ
9. 마지막 쿼리 라우팅!
데이터 복사가 끝났으니 복사된 데이터베이스를 사용하도록 클라이언트들의 쿼리를 라우팅 해야겠죠!
하지만 수천 개의 연결을 맺고 있는 클라이언트들의 쿼리를 라우팅 하는 것은 어렵습니다...
피그마 인프라팀은 이 문제를 해결하기 위해서 다음과 같은 과정을 거쳤다고 합니다.
- 잠깐 동안 클라이언트의 새 연결을 막음
- 그 사이에 클라이언트가 기존 DB에 맺은 연결들을 새로운 DB에 연결(아직 실행 중인 쿼리들은 취소시킴)
- 마지막으로 기존 DB와 새로운 DB가 일치하는지 확인하고 일치하면 새로운 DB를 primary DB로 승격시킴
이렇게 피그마 인프라팀의 DB 병목 개선 작업을 공부해봤습니다.
오래 전에 봤던 글인데 당시에는 자세히 읽지 않았나봅니다. 이번에 다시 보니 새로운 내용들이 많네요 ㅋㅋㅋ
시간이 지나서 한번 더 보면 새롭게 배우는 내용이 많겠죠?
'리뷰' 카테고리의 다른 글
[2023-12] 스크럼 가이드 리뷰 (0) | 2023.12.07 |
---|---|
도메인 주도 개발 시작하기 - 2. 아키텍처 개요 (0) | 2022.11.25 |
도메인 주도 개발 시작하기 - 1. 도메인 모델 시작하기 (2) | 2022.11.15 |
[개발자의 서재] "실용주의 프로그래머" 4. 적당히 괜찮은 소프트웨어, 10. 예광탄 (0) | 2022.09.15 |
[개발자의 서재] "실용주의 프로그래머" 3. 돌멩이 수프와 삶은 개구리 (0) | 2022.09.12 |