3. 성능 지표
3
처리량: 얼마나 많은 일을 하고 있는가
= 이 서버 동시 접속 몇 명까지 받을 수 있나?
응답 시간: 하나의 일을 얼마나 빨리 처리하는가
= 이 서버 랙 있는지?
4. 게임 서비스
4
……게임 서버 (PvP) …
Game
Server
Game
Server
Matchmaking
Server
Matchmaking
Server
게임 서버 …
게임 서버 군
유저 세션 랭킹 캐시 …
Redis / memcached
유저 데이터 랭킹 통계 데이터
Databases
로드 밸런서
Nutcracker 캐시 / 디비 미들웨어
유저 인증
서비스
GooglePlay
결제
3rd 파티 플랫폼 서비스
BI / 통계
운영 API
운영 서비스
유저
랭킹
CDN
Matchmaking
Server
Matchmaking
Server매치메이킹
실시간 PVP 서버 군
5. 게임 서비스
5
전체 시스템이 여러 개의 다양한 요소로 구성
각 요소 중에 성능 문제가 있는 부분을 찾을 수 있을까?
14. 성능 모델 (1)
14
요청 하나를 여러 개의 이벤트로 쪼개서 측정한다
• 웹 API의 요청 - 응답 쌍 하나
vs.
1. 유저 로그인 요청을 받고 해당하는 DB 객체 가져오기
2. DB객체와 로그인 요청을 비교해서 바른 요청인지 확인
3. 인증 서비스에 유저 로그인 요청 보내기
4. 인증 서비스 결과를 클라이언트에 응답
15. 성능 모델 (2)
15
이벤트 하나
→ 클라이언트 메시지, 타이머 만료, DB 연산 완료, API 호출에 대한 응답
측정할 성능:
하나의 작업 (= 하나 혹은 여러 개의 이벤트) 가 얼마나 걸렸는가
각 이벤트 실행 시간을 작업 별로 모아서 합산
평균적/최소/최대로는 얼마나 빠른지 확인 (혹은 분포 확인)
16. 성능 측정 코드 넣기
16
모든 분리된 이벤트 단위에서 측정한다.
• 클라이언트 메시지 받고 처리 시작까지 걸린 시간 (큐 대기 시간)
• DB 혹은 redis 요청 전송 / 요청 완료 콜백에 걸린 시간
• 외부 API 요청 / 완료 콜백까지 걸린 시간
• 데이터를 가지고 복잡한 연산 (예를 들어 길찾기, AI tick, …) 에 걸린 시간
• DB 에서 가져온 row 수 혹은 ORM 객체 수
• 외부 API 호출 실패에 대한 재시도 횟수
21. 리눅스 성능 측정 도구들
21
Linux perf kernel 이벤트 카운터 (v2.6 이상)
Linux eBPF 프레임웍의 트레이싱 기능 (v3.18 이상; 가능하면 v4.9 이상)
그리고 이를 이용한 스크립트 / 성능 모니터링 툴
• BCC (https://github.com/iovisor/bcc): eBPF 프로그램 컴파일러 (python, lua)
• PLY (https://github.com/wkz/ply): eBPF 스크립트 툴
• eBPF trace (https://github.com/iovisor/bpftrace): D-Trace 유사 기능
22. eBPF + BCC
22
eBPF: 리눅스 커널 안에서 동작하는 (제한된) VM
BCC: eBPF 프로그램을 생성하고,
해당 프로그램과 통신하는 python / lua 스크립트
성능 측정이 커널 안에서 이뤄져서 빠르다 (컨텍스트 스위칭 부하 없음)
23. eBPF: 할 수 있는 일
23
eBPF: 리눅스 커널 안에서 동작하는 (제한된) VM;
OS 실행 중 아무때나 추가하거나 제거할 수 있다.
커널 안의 함수, 시스템 콜, 프로그램 내의 함수를 후킹
해당 함수 호출할 때 마다 특정 동작(=호출 내용 통계내기)을 하거나,
동작을 변경할 수 있다. (=패킷 필터링)
24. BCC: 할 수 있는 일
24
eBPF 프로그램을 (자동으로) 생성하고
해당 프로그램을 커널에 넣어 실행 한 후, 통신한다.
시스템/프로그램의 동작을 지속적으로 추적하거나 (트레이싱)
성능 지표 등을 통계낼 수 있다. (프로파일링)
25. 예: CPU 프로파일링
25
1초에 수십-수백번 정도 특정 프로세스나 스레드를 살펴본다
이때 각 CPU가 실행 중인 콜스택을 key로 map에 저장
Map에 있는 데이터를 FlameGraph 로 시각화
(https://github.com/brendangregg/FlameGraph )
27. 어떤 질문을 답할 수 있을까?
27
어떤 lock 을 제일 오래 기다리는가?
Disk 읽기 요청을 어떤 크기로 주로 보내는가?
CPU 수가 작업 수에 비해서 적은가?
어느 시스템 콜을 제일 많이 하는가?
어떤 Disk IO가 제일 느린가?
28. Kernel - 유저 스페이스 역할 분리
28
데이터를 측정 대상의 kernel 영역 안에 안전하게 갈무리하고 (eBPF)
분석 프로그램의 유저 스페이스에서 후처리 (BCC)
성능 측정 / 디버깅 코드가 문제를 일으키기 어렵다
(측정 대상과 측정하는 툴이 서로 다른 프로그램)
29. 장점
29
안전성 - OS나 측정 대상을 크래시하지 않는다 (eBPF 컴파일러가 보장)
시스템 / 프로그램 재시작 없이 측정 방식 변경
3rd 파티 라이브러리 / 프레임웍이 존재
30. 단점
30
최신 커널 필요 - 일정 이상의 kernel 버전이 필요하다 (CentOS 7 은 커널 추가 설치 필요)
측정 대상이 사용하는 라이브러리 / OS 지식이 필요
(측정할 함수나 결과로 나온 함수들을 추측해야)
컴파일러 최적화로 인해서 변경된 콜스택 분석이 어려운 경우가 있다
41. flaskr: 직접 측정
41
웹 요청에 대한 비동기 처리 없음 - DB 및 기타 처리는 직렬로 처리
하나의 HTTP 요청에 대한 처리 시간을 구분해서 기록
• 총 처리 시간
• DB 요청 - 응답 시간
• HTML 응답 생성 시간 (template -> HTML 렌더링 시간)
42. 측정 코드 삽입 (1)
42
HTTP Request 에 대한 middleware 추가
• 요청 처리 시작 / 종료 시각 기록 (총 요청 처리 시간 계산)
• DB 요청 시작 / 완료 시각 기록
• HTML 렌더링 시작 / 완료 시각 기록
만일, DB / HTML 렌더링 두 부분이 문제가 아니라면,
총 요청 시간 - DB 요청 시간 - HTML 렌더링 시간
값이 크게 나올 것이다. (예측)
43. 측정 코드 삽입 (2)
43
각 측정 값 (총, DB, 렌더링)에 대해서 처리 시간 분포를 측정 (log 분포 이용)
시간은 마이크로 초 (us) 수준에서 측정
49. flaskr: eBPF + BCC를 써서 측정
49
BCC 에서는 예제 및 기본 기능 제공을 위해서 몇 가지 도구를 제공한다.
해당 도구를 사용해서 성능 측정 / 병목 분석을 진행한다.
50. 측정 진행 방식
50
1. 가설을 세운다
2. 가설을 확인할 적당한 도구로 측정한다 (혹은 도구를 만든다)
3. 측정 후 가설이 맞는지 확인한다
예를 들어 CPU가 병목이라고 가정한다면,
profile 을 실행해서 CPU 병목을 찾아보고,
CPU 병목이 있다면 많이 실행되는 곳을 최적화한다
51. 가설 #1: CPU 병목이 있는가?
51
CPU 를 많이 쓰는 코드를 어떻게 찾을까?
BCC profile 명령 이용
앞서 언급한 샘플링 방식의 프로파일링 도구
예: 30초간, 매초 199번 샘플링
sudo profile -p $(pgrep -nx flaskr) -f -F 199 30
55. 가설 #2: 어딘가에서 대기하는 문제?
55
Lock 이나 메모리 같은 다른 무언가에서 대기하면 오래 걸린다
코드의 대기 시간을 측정해보자: BCC offcputime
스레드가 락을 기다리거나 / 블럭킹 시스템 콜을 해서
CPU를 반납하는 순간의 콜 스택 분포를 구한다
sudo offcputime -p $(pgrep -nx flaskr) -f 30
58. 누가 poll() 대기를 깨우는가?
58
poll() 호출한 코드가 무엇을 기다렸는지 반대방향에서 보기
깨우는 쪽에서 뭘 했는지 확인한다
offwaketime 툴 이용
다른 스레드를 실행 가능하게 해줬을 때의 콜 스택 분포를 본다
sudo offwaketime -p $(pgrep -nx flaskr) 30
69. 어떻게 접근할까?
69
서버 코드에 측정하는 기능을 추가
모델에 대해서 한 번에 측정/확인
모델 범위를 벗어나는 경우 문제
외부에서 관찰
도구가 제공하는 범위 내에서 측정
한 번에 모두 볼 수 없으나 반복/수정
70. 더 해보고 싶은 것: 클라이언트
70
• 직접 측정: Unity 나 Unreal Engine 의 자체 프로파일러
• 도구 사용: Android adeb (https://github.com/joelagnel/adeb)
adb root 사용 가능한 arm64 / android N 이상의 기기 지원
(사실상 커스텀 빌드 커널 필요)
71. 더 해보고 싶은 것: Windows 서버
71
• 직접 측정: Linux 의 경우와 차이가 크지 않다
• 도구 사용
• Event Tracing for Windows / Xperf
(https://randomascii.wordpress.com/2012/05/11/the-lost-xperf-
documentationcpu-scheduling/ )
• Windows Performance Analyzer (WPA)
(https://docs.microsoft.com/ko-kr/windows-hardware/test/wpt/
graphs#flame_graphs)