대용량 트래픽/데이터에 대한 사고 과정 정리
어디까지나 내가 회사에서 경험한 것 바탕임
왠만한 기업이 아닌 이상
평상시 트래픽은 굉장히 낮을 것임
가장 중요한 것은
지금 이 순간에 얼만큼 굵게 들어오지는가 중요함
그 지표는 주로 TPS / QPS로 측정됨
이렇게 선착순이나 알림톡 / 마케팅으로
특정 이벤트 발생 시 유입이 몰려오고
그때 서버가 터지는 경우가 대부분임
1. 기본적으로 대기열로 막는다.
예를 들어, 정보처리기사 접수할 때
@@명이 대기 중입니다.
잠시만 기다려주세요.
현재 페이지를 벗어나면 대기순번이 초기화됩니다.
이부분은 DevOps팀 담당이라 자세하게 말은 못하겠음
2. 웹서버 단에서 스케일 아웃
로드밸런서 뒤로 어플리케이션 서버를 여러개 둬서 적절히 부하를 분산함
3. 무거운 작업을 하는 배치 작업/어드민 서버는 별도로 분리
대량 배치 작업이나, 엑셀 다운로드 같은 작업은 가끔 씩
CPU나 메모리 부하를 일으키고
이러한 서버가 장애가 나더라도 사용자 서버랑 분리하는게 좋음
4. DB서버 스케일 아웃
마스터DB 1대 - 슬레이브 DB N대 이러한 구조가 일반적일 것임
CUD 연산은 마스터 DB
단순 select 조회는 슬레이브 DB에서 조회하고
결제 재고 처럼 정합성이 중요한 조회는 마스터DB에서 수행
추가로, DB백업은 슬레이브 DB에서 수행되게 끔
5. 집계 연산은 캐싱처리
통계테이블도 좋지만, 조건이 다양하게 들어오면 모든 경우의 수를 관리하기 어려움이 있음
캐싱 TTL을 적절히 잡고, 실시간성이 아님을 안내할 필요가 있음
필요한 경우에 배치로 계속 백그라운드에서 캐시 갱신 필요
6. 쿼리 자체가 오래 걸리는 것은 쿼리 튜닝 / 인덱스 튜닝으로 해결
가능하면 쿼리를 바꿔서 해결하는게 최선이고
과도한 복합 인덱스 추가는 Buffer Pool이 효율을 떨어지고
실행 계획이 꼬여서 최대한 지양해야함
7. CUD 락은 최소한으로 꼭 필요한 경우에는 PK로 정확히 식별하여 갱신하기
흔하게 발생하는 락 지연이 인덱스 안타서 전체 Full Scan 레코드를 잠그는 경우
꼭 해야하는 경우엔 chunk를 쪼개서 반복 update
8. log처럼 부가적인 데이터는 RDB에 insert 적재를 지양
한번에 다량의 log가 수집되면 마스터DB에 부담이 크고
정합성이 덜 중요하여 MongoDB나 ElasticSearch에 파이프라인을 구축하여 적재하는 것을 권장함
혹은 그냥 appene 방식으로 파일쓰기 권장
9. insert는 bulk(너무 많으면 chunk 분리)로 update는 모아서 한번에 실행
CUD 연산은 전부 binlog에 기록되고 대량 발생시 Slave DB Relay 지연이 빈번함
10. contents like %% 검색은 검색엔진에서 조회하기
RDB(원본데이터) ----> kafka(CDC) -----> ElasticSearch(검색용 복제데이터)
모든 데이터를 ElasticSearch에 적재하긴 어려워서
쿼리로 부하가 큰 대규모 데이터만 적재하는 것을 권장
정합성이 중요한 데이터는 반드시 RDB에서 트랜잭션 권장
11. count sum join order by limit은 최대한 쿼리에 위임하기
물론 쿼리 구조가 비대해지는 것은 좋은 것은 아니나,
어플리케이션 단으로 먼저 가져와서 필터링/집계연산 처리하면
불필요한 데이터까지 메모리를 잡아먹게되고
대규모 네트워크 I/O가 발생 가능함
최대한 DB에 맡기고 최종 남긴 결과만 가져오는게 좋음
12. 비동기/지연 반영이 허용되는 경우엔 메시지큐에 위임
클라이언트에게 즉시 응답을 해주고 백그라운드에서 무거운 작업을 수행
다만, 문제가 생기면 추적이 어렵고 정합성 이슈 발생 가능성이 높음
13. 고가용성
어떤 경우든 서버는 장애가 나고 죽는 일이 생길 수 밖에 없음
그러한 서버로 응답이 오면 당연히 timeout 이 발생함
Primary 노드- Secondary 노드 구조에서
Secondary 노드가 죽으면 빠르게 클러스터 그룹에서 배제시키고
Primary 노드가 죽으면 배제되고 Secondary 노드가 승격
이미 잘 구축된 솔루션을 활용하면 됨
뭐 다 뻔한 얘기라고 생각할 수 있는데
이정도면 왠만한 한국 대기업은 다 커버될거임
14. 알림/이메일 서버 분리, 이미지동영상 등 CDN서버 활용
나도 이쪽은 잘 안해봤지만
웹서버는 저쪽에 요청만 보내고
그것을 전문으로 하는 서버에게 위임한다고 생각하면 됨
대용량 트래픽/데이터 처리의 본질은
단순히 순간 트래픽 처리량을 늘리는 개념을 넘어
모든 요청이 몰리는 최종 종착점 마스터 DB에 부담을 줄이는 일관된 방향성을 지님
정리하면
이벤트로 트래픽이 과다하게 유입되면
속도가 제일 느리고(디스크I/O)
한 곳으로 몰리는게(마스터DB 혼자서 트래픽을 다 몸빵함)
흔한 장애 사유라고 볼 수 있음
너 정말 핵심을 찔럿어
**지금까지 내용을 바탕으로 세미나/발표용 자료**를 만들어줄까? - dc App
딘퐁님 7번부터 이해하기 좀 빡센데, 어디가 부족할까요..? - dc App
글로만 적어서 예시가 없어서 gpt한테 예시나 설명해달라고 하면 이해되실듯 - dc App
감사합니당 - dc App
7번은 where에 인덱스없을 때 update문이 대표적입니디 - dc App
@곰팡 혹은 범위 전체를 update - dc App
4번은 저렇게 할 수 밖에 없음 rdbms 는 구조적으로 단일서버에서 데이터 관리하게 강제되어있어
그래서 중간에 레디스 넣는 이유가그거임 디비 안죽이고 레디스 죽이게
5번은 새벽에 돌게 해야하고 분석쿼리는 spark 같은거 써서 여러 서버 조지는거 rdb 는 단일서버만 조져서 분석 성능 처참함 6번은 dba 없으면 하면 안댐. 개발자들 sql 조또 몰라 7번은 실무에서 pk 설정하면 오류 빵빵터져서 설정 안함 8번은 로그에 엘라스틱서치 쓰면 안댐. 이거 ㅈㄴ 무거워서 좀만 쌓여도 비용ㅈㄴ 나감 11번은 윈도우함수 쓸줄알면 무적권 써야함 13번은 절대 생기면 안대는일임. 이 일 생기면 이론적으론 세컨다리 노드 승격 하면 될것같지만 서버 죽은동안 데이터 누락대서 걍 완전 재앙임
힙메모리랑 데이터 백업 수명 주기 서버 용량 및 개발자의 조회 쿼리 습관 등 추가하면 좋을거같삼
하 시발 메이플 뭔데
대기열 쓰면 좋긴 한데 실질적으로 총 트래픽을 늘리는 거라 좀 사파무공 같은 느낌 에버랜드 대기하는 감성으로 사람들 죽치고 앉아있음
사용자는 안좋아하긴해.. - dc App
인스타그램이 그랬잖아. 저스틴비버가 글한번싸면 Like때문에 서버 터진다고 그래서 Like 카운트를 따로 관리하는 방식으로 개선했따 하더라 아마 너가 쓴 글 내용중에 분명있을거임
통계테이블이라고 보면 되는데 일종의 캐싱이지 - dc App
이론적으로는 다 맞는 말인데 실제로 하려면 귀찮아서 제끼는애들도 있긴하네 - dc App
저렇게 안해도 잘만돌아감ㅋㅋ - dc App