▣ 1장: 튜닝의 기초 지식 1-1 현재 웹 서비스의 필수 요건인 ‘속도’ ___웹 서비스의 경쟁력과 직결되는 ‘속도’ ___SEO에도 영향을 주는 ‘속도’ 1-2 속도가 빠른 웹 서비스 ___비용 절감에도 영향을 미치는 ‘속도’ ___속도가 빠른 웹 서비스란? ___웹 서비스 속도 단위 ___웹 서비스의 구조 이해 1-3 웹 서비스 부하 ___웹 서비스의 부하가 높은 상태 ___속도와 용량 ___성능 튜닝 1-4 웹 서비스 용량 ___필요 충분한 용량 ___필요 충분한 용량을 예측하는 방법 1-5 성능 튜닝의 시작(1) ___추측하지 않고 계측 ___공정한 비교 ___하나씩 비교 1-6 성능 튜닝의 시작(2) ___병목 현상 해소 ___병목을 식별할 때는 바깥쪽에서 안쪽으로 ___병목 현상에 대처하는 3가지 방법 1-7 성능 튜닝의 시작(3) ___부하 테스트의 과정 개요 1-8 정리 ▣ 2장: 모니터링 2-1 모니터링이란 - 인프라에서의 테스트 2-2 모니터링 개념 2-3 모니터링 종류 ___외형 감시 ___내부 감시 2-4 수동 모니터링 2-5 모니터링 도구 2-6 모니터링 도구의 구조 ___에이전트 node_exporter ___node_exporter로 얻을 수 있는 메트릭 2-7 모니터링 실시 2-8 모니터링 시 주의점 ___올바른 측정 결과 확인 ___2개의 그래프를 비교할 때 다른 조건 맞추기 ___부하가 높은 상태 모니터링 ___모니터링 해상도 2-9 로그 모니터링 2-10 정리 ▣ 3장: 부하 테스트의 기초 3-1 private-isu ___private-isu 사양 및 운영 환경 ___직접 private-isu를 동작 ___Amazon EC2에서 private-isu 시작 ___Docker에서 private-isu 시작 ___private-isu 실행 3-2 부하 테스트 준비 ___부하 테스트 환경 준비 ___nginx의 액세스 로그 집계 ___액세스 로그를 JSON 형식으로 출력 ___JSON 형식의 액세스 로그 집계 ___alp를 설치하는 방법 ___alp를 사용한 로그 해석 방법 3-3 벤치마커로 부하 테스트 실시 ___ab 명령 설치 ___ab 명령 사용법 ___ab의 결과와 alp의 결과 비교 ___액세스 로그 로테이션 3-4 성능 튜닝 시작 ___부하 테스트 실시 - 첫 번째 결과 확인 ___부하 테스트 중 부하 모니터링 ___MySQL 병목을 발견할 준비 ___슬로우 쿼리 로그 구문 해석 ___튜닝 결과를 확인하는 부하 테스트 ___새로운 병목 찾기 3-5 벤치마커의 병렬성 ___서버의 처리 능력을 전부 사용할 수 있는지 확인 ___왜 CPU를 사용하지않는가? ___여러 CPU를 효과적으로 사용하기 위한 설정 ___서버 병렬성을 높여 부하 테스트 실시 3-6 정리 ▣ 4장: 시나리오 부하 테스트 4-1 부하 테스트 도구 k6 ___k6 설치 4-2 k6로 간단한 부하 테스트 4-3 k6로 시나리오 작성 ___시나리오에서 공통으로 사용하는 함수를 정의 ___웹 서비스 초기화 처리 시나리오 작성 ___sleep() 함수: 일정시간 대기 ___사용자가 로그인해 댓글을 작성하는 시나리오 작성 ___check() 함수: 응답 내용 확인 ___parseHTML() 함수: HTML 내의 요소를 취득 ___파일 업로드가 포함된 양식 제출 ___시나리오에서 사용할 외부 데이터 준비 4-4 여러 시나리오를 결합한 통합 시나리오 실시 ___통합 시나리오 실행 결과 예 4-5 부하 테스트에서 얻은 액세스 로그 해석 4-6 정리 ▣ 5장: 데이터베이스 튜닝 5-1 데이터베이스의 종류 및 선택 ___일관성을 강조하는 RDBMS ___응용 프로그램 요구에 맞춘 NoSQL ___일관성과 분산을 모두 충족하는 NewSQL ___데이터베이스 선택 5-2 데이터베이스 부하 측정 ___OS에서 부하를 모니터링 ___MySQL 프로세스 목록 ___pt-query-digest로 슬로우 쿼리 로그 분석 ___query-digester를 사용한 프로파일링 자동화 ___pt-query-digest 결과 확인 5-3 인덱스로 데이터베이스를 고속화 ___데이터베이스에서 결과를 빠르게 얻으려면 ___데이터베이스에서 인덱스의 역할 ___인덱스로 인해 검색이 빨라지는 이유 ___MySQL에서 인덱스 사용 ___복합 인덱스 및 정렬에 사용되는 인덱스 ___클러스터 인덱스 구성 및 클러스터 인덱스에서 인덱스 튜닝 ___너무 많은 인덱스 생성으로 인한 안티 패턴 ___MySQL이 지원하는 기타 인덱스 5-4 N+1이란? ___쿼리 수가 증가하면 응용 프로그램이 느려지는 이유 ___N+1을 찾고 해결하는 방법 ___데이터베이스 이외에도 있는 N+1 문제 5-5 데이터베이스와 자원을 효율적으로 사용 ___FORCE INDEX와 STRAIGHT_JOIN ___필요한 열만 취득해 효율화 ___프리페어드 스테이트먼트와 Go 언어에서의 연결 설정 ___데이터베이스와의 연결 지속성 및 최대 연결 수 5-6 정리 ▣ 6장: 리버스 프락시 사용 6-1 응용 프로그램 및 프로세스 스레드 6-2 리버스 프락시를 이용하는 장점 6-3 nginx란? 6-4 nginx 구조 6-5 nginx로 전송할 때 데이터 압축 6-6 nginx에 의한 요청 응답 버퍼링 6-7 nginx와 업스트림 서버의 연결 관리 6-8 nginx의 TLS 통신 속도 향상 6-9 정리 ▣ 7장: 캐시 활용 7-1 캐시 데이터 저장에 사용되는 미들웨어 7-2 캐시를 KVS에 저장할 때의 주의점 7-3 언제 캐시를 사용할까? ___TTL을 충분히 짧게 설정 7-4 구체적인 캐시 구현 방법 ___캐시에 데이터가 없으면 캐시를 생성해 생성 결과를 저장하는 방법 ___캐시가 없다면 기본값이나 이전의 캐시를 반___비동기적으로 캐시 갱신 처리를 실시 ___일괄 처리 등으로 정기적으로 캐시를 갱신 ___Private-isu에서 실제로 캐시 사용 7-5 캐시 모니터링 7-6 정리 ▣ 8장: 알아 두면 좋은 고속화 방법 8-1 외부 명령 실행이 아닌 라이브러리 사용 8-2 개발용 설정에서 불필요한 로그를 출력하지 않는다 8-3 HTTP 클라이언트 사용 기법 ___적절한 타임아웃 설정 ___동일한 호스트에 대량의 요청을 보내는 경우 호스트의 연결 수 제한 확인 8-4 정적 파일을 리버스 프락시에서 직접 전달 8-5 클라이언트 측에서 캐시를 활용하기 위해 HTTP 헤더를 사용 8-6 CDN상에 HTTP 응답을 캐시 ___CDN은 전 세계 어디서 액세스하더라도 빠른 서비스를 제공 ___Cache-Control을 사용해 CDN 또는 Proxy에 캐시 8-7 정리 ▣ 9장: OS 기초 지식과 튜닝 9-1 흐름 파악하기 9-2 리눅스 커널의 기초 지식 9-3 리눅스의 프로세스 관리 9-4 리눅스의 네트워크 ___네트워크 메트릭 ___리눅스 커널에서 패킷 처리 효율성 9-5 리눅스의 디스크 I/O ___스토리지 종류 ___스토리지 성능이란 - 처리량, 지연 시간, IOPS ___스토리지 성질 조사 ___디스크 마운트 옵션 ___I/O 스케줄러 9-6 CPU 사용률 ___us - User: 사용자 공간에서 CPU 사용률 ___sy - System: 커널 공간에서의 CPU 사용률 ___ni - Nice: nice 값(우선순위)이 변경된 프로세스의 CPU 사용률 ___id - Idle: 사용되지 않는 CPU ___wa - Wait: I/O 처리를 기다리는 프로세스의 CPU 사용률 ___hi - Hardware Interrupt: 하드웨어 인터럽트 프로세스의 사용률 ___si - Soft Interrupt: 소프트 인터럽트 프로세스의 사용률 ___st - Steal: 하이퍼바이저가 사용하는 CPU 사용률 9-7 리눅스에서의 효율적인 시스템 설정 ___ulimit 9-8 리눅스 커널 매개변수 ___net.core.somaxconn ___net.ipv4.ip_local_port_range 9-9 MTU(Maximum Transmission Unit) ___기타 커널 매개변수 9-10 정리 ▣ 부록A: private-isu 공략 실천 A-1 준비한 대회용 환경 A-2 벤치마커 실행 방법 A-3 각 장에서 소개한 방법 적용 ___초기 상태(약 640점) ___comments 테이블에 인덱스 추가(약 5,500점) ___unicorn worker 프로세스를 4로 설정(약 13,000점) ___정적 파일을 nginx로 전달(약 17,000점) ___업로드 이미지를 정적 파일화(약 22,000점) ___GET /을 분석 ___posts와 users를 JOIN해 필요한 행 수만 취득(약 90,000점) ___벤치마커가 사용하는 파일 디스크립터 상한을 증가 ___프리페어드 스테이트먼트를 개선(약 110,000점) ___comments 테이블에 인덱스 생성 (약 115,000점) ___posts에서 N+1 쿼리 결과 캐시(약 180,000점) ___적절한 인덱스를 사용할 수 없는 쿼리를 해결(약 200,000점 ) ___외부 명령 호출 중지(약 240,000점) ___MySQL 설정 변경 (약 250,000점) ___memcached에 대한 N + 1 제거 (약 300,000 점 ) ___Ruby의 YJIT를 활성화(약 320,000점) ___처음에 생성한 인덱스를 삭제(약 10,000점) A-4 정리 ▣ 부록B: 벤치마커 구현 B-1 ISUCON의 벤치마커는 무엇인가? ___부하 테스트 도구로서의 벤치마커 ___웹 서비스 구현에 대한 E2E 테스트로서의 벤치마커 ___점수와 에러를 제공하는 정보원으로서의 벤치마커 ___벤치마커에 요구되는 행동에 주의할 것 B-2 자주 사용되는 벤치마커 구현 패턴 ___context.Context ___time과 context에 의한 루프 패턴 ___sync 패키지 사용 ___sync/atomic 패키지 사용 ___Functional Option 패턴 B-3 private-isu를 대상으로 한 벤치 마커 구현 ___입출력 설계 ___데이터 갖기 ___초기화 처리 구현하기 ___로그인하는 처리 작성 ___이미지를 게시하는 처리 만들기 ___최상위 페이지 검증 ___점수 계산 ___실제로 실행하고 동작을 확인 B-4 정리