8.1 포인트별 튜닝 레시피
8.1.1 요청 횟수와 전송량을 줄이는 방법
HTTP 요청은 텍스트 기반의 프로토콜이며, 통신을 하기 위해서는 일련의 절차가 필요하다. 서버와 클라이언트 측 모두 통신을 할 때마다 프로토콜을 해석하는 파서(Parser)가 매번 동작하며, 요청 횟수가 늘어나면 그만큼 오버헤드가 증가한다. 따라서, HTTP의 오버헤드를 줄이기 위해서는 요청 횟수를 줄이거나 전체적인 데이터 전송량을 줄이도록 한다. 요청 횟수나 데이터 전송량을 줄이기 위해 파일 결합, CSS Sprite, CSS나 JavaScript의 minify를 할 때에는 'Grunt'와 같은 툴을 사용하면 좋다.
요청 횟수를 줄이는 방법 | 구체적인 실행방법 |
파일 결합에 의한 이미지 수 감소 | 페이지 내에서 이용하는 CSS나 Java Script의 파일을 결합해 하나로 집약함으로써 1페이지에서의 요청 수를 줄인다. |
CSS Script에 의한 이미지 수 감소 | 이미지를 하나로 집약하여 1페이지에서의 요청 수를 줄인다. |
배경 등의 표현을 CSS로 구현 | 이미지 수를 줄임으로써 1페이지내에서의 요청 수를 줄인다. 데이터 전송량도 줄일 수 있다. |
HTTP KeepAlive 유효화 | HTTP KeepAlive를 유효화하여 다수의 요청을 한 번의 통신으로 처리함으로써 통신 횟수를 줄일 수 있다. |
데이터 전송량을 줄이는 방법 | 구체적인 실행방법 |
CSS나 JavaScript를 minify한다. | 들여쓰기나 행 바꿈을 없애는 등 CSS나 JavaScript의 파일 내용을 줄인다. |
이미지의 압축률을 높인다. | 이미지의 압축률을 높여 파일 용량을 작게한다. |
이미지의 크기를 작게한다. | 이미지의 크기가 표시될 크기보다 큰 경우, 이미지의 크기를 표시될 크기에 맞추어 작게 한다. |
데이터를 압축하여 전송한다. | 전송 시에 데이터를 gzip 압축하여 전송한다. |
정적파일을 브라우저에서 캐시한다. | HTTP 헤더를 설정하여 정적 파일을 브라우저에서 캐시함으로써, 갱신의 확인만으로 요청의 처리를 끝낸다. |
CDN(Contents Delivery Network)을 사용한다. | CDN에서 데이터를 캐시함으로써 자체 서버의 데이터 전송량을 줄인다. |
HTTP KeepAlive를 이용하게 되면 하나의 TCP/IP접속을TCP/IP 접속을 유지한 채로 다수의 HTTP 요청을 처리할 수 있게 된다. HTTP KeepAlive를 사용하지 않는 경우에는 각각의 요청에 대해 TCP/IP 접속을 하나씩 할당한다. HTTP KeepAlive의 장점은 매번 접속할 필요가 없기 때문에 서버와 클라이언트 측 모두 처리량이 줄어들어 사이트 표시가 빨라질 수 있지만, 서버 측은 다음 요청이 올 수 있어 일정 시간을 대기하게 되기 때문에 그만큼 접속을 유지하여 병렬 수가 많아지게 된다. HTTP KeepAlive가 없는 경우에는 한 페이지를 표시하기 위해 필요한 접속 수가 많기 때문에 상위 네트워크 기기에서 동시 병렬 세션이 많아지게 된다. 방화벽이나 로드밸런서의 병렬 세션의 수가 문제가 되는 경우 HTTP KeepAlive를 활성화하는 것으로도 문제를 해결할 수 있으니 시스템에서 적절히 사용하도록 한다.
8.1.2 데이터 압축 전송 구현 예
데이터 압축 전송을 이용하면 데이터 전송량은 몇 분의 1 ~ 몇십 분의 1로 감소한다. 반면, 압축을 위해서는 CPU를 사용하므로 서버측의 CPU 부하는 높아진다. Apache의 경우 'mod_deflate' 모듈로 이를 구현하고, 이때 바이너리 파일은 압축을 해도 효과가 적으므로 테 5ㄱ스트 파일에 대해 지정하도록 한다. 최근에는 압축 전송을 지원하는 클라이언트가 많아 nginx의 경우도 미리 압축해 둔 파일을 송신함으로써 압축 부하를 줄일 수 있다.
[Apache로 구현하는 방법]
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE\ [1-6] !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|exe|zip|gz|ico|swf|mp.|wav)$ no-gzip dont-vary
Header append Vary User-Agent env=!dont-vary
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/json
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/xhtml
AddOutputFilterByType DEFLATE text/xhtml+xml
AddOutputFilterByType DEFLATE text/aton+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xml+rss
AddOutputFilterByType DEFLATE application/xhtml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/atom+xml
AddOutputFilterByType DEFLATE application/x-httpd-php
[NginX로 구현하는 방법]
gzip on;
gzip_disable "Mozilla/4";
gzip_dsable "msie6";
gzip_types text/plain
text/html
text/javascript
text/css
text/json
text/xhtml
text/xhtml+xml
text/atom+xml
application/javascript
application/x-javascript
application/json
application/xml
application/xml+css
application/xhtml
application/xhtml+xml
application/atom+xml
application/x-httpd-php;
gzip_vary on;
혹시나 압축 전송에 대응하지 않는 클라이언트라면 아래와 같이 압축을 풀어 송신한다.
location ~ ^/(css|js)/ {
gunzip on;
gzip_static always;
}
8.1.3 OS의 CPU 사용률 낮추기
Iowait을 낮추려면 어떤 프로세스가 I/O wait에서의 CPU사용률을 높이고 있는 원인인지를 파악하여 처리한다. 이때, I/O 체크 툴인 'iotop'을 사용하거나 ps 명령으로 status D 프로세스를 확인한다. 프로세스를 확인하였다면 불필요한 처리나 중시할 수 있는 처리가 있다면 먼저 중지시키도록 한다. 의도하지 않은 일괄 처리가 수행되고 있지는 않은지, 실행 시작 시간이 밀려있지는 않은지를 검토한다. 또한 로그 출력 수준을 낮추어 I/O 사용량을 감소시키고, 만약을 위해 취득하고 있는 데이터의 취득을 중단시킨다. SWAP을 사용하고 있는 프로세스가 있다면 그 프로세스의 메모리 이용량을 제한하거나 메모리를 늘리도록 한다. 또한 파일로의 출력을 버퍼링 하여 출력을 효율화하도록 한다. OS에서도 특히 많은 양의 디스크 쓰기를 수행하는 syslog를 버퍼링 하여 출력할 수도 있다.
Softirq는 통신량이 많은 로드밸런서 등에서 상한에 도달하는 경우가 많은데, top이나 dstat에서 특정 CPU 코어의 siq가 90%가 넘는 경우에는 문제가 된다. 근본적으로 통신량(데이터량)을 줄이는 수밖에 없지만, CentOS6 이상의 버전에서는 RFS(Feveive Flow Steering), RPS(Reveive Packet Steering)이라는 기능을 통해 다수의 코어를 이용하여 1코어의 상한 제약을 피할 수 있다.
8.1.4 OS의 메모리 용량 늘리기
OS의 메모리를 증가시키기 위해서는 스펙을 올리는 방법 뿐이지만, 스펙을 올리기 어려운 경우에는 유사하게 메모리를 증가시키기 위해 Swap(일시적으로 메모리에서 데이터를 하드디스크 등의 보조기억장치 영역에 쓰거나 읽는 것)을 활용할 수 있다. Swap은 서버가 가동 중인 상태에서도 추가 및 해제가 가능하며, 여러 개의 디스크로 구성하여 각각의 디스크에 우선순위를 부여할 수 있다. 또한 1대의 서버에 HDD와 SSD가 장착되어 있는 경우에는 SSD를 유사 메모리로 활용할 수 있다. 파일을 Swap 디바이스로도 인식하도록 할 수 있으며, SSD의 여유 용량을 Swap으로 이용하는 방법도 있다.
8.1.5 OS의 디스크 I/O 성능 높이기
OS의 디스크 성능을 높이는 방법은 기본적으로 저수준에서 대응하는 것으로, 물리적인 서버의 경우 RAID를 사용함으로써 디스크 1대당 성능을 초과하는 I/O 성능을 구현할 수 있다. 성능면에서는 RAID 카드(컨트롤러)를 이용한 하드웨어 RAID가 좋으며, 성능을 목적으로 RAID 카드를 선정하는 경우에는 반드시 메모리와 배터리를 내장하고 있는 것을 선택하는 것이 좋다. 메모리 용량은 최소한 512MB, 가능하면 1GB 이상인 것을 고른다. 메모리를 내장함으로써 디스크에 데이터를 기록하는 대신 내장 메모리에 기록하는 것만으로도 완료가 된다. 이 동장을 WriteBack이라고 한다.
디스크 자체의 성능을 높이려면 HDD를 사용하지 않고 SSD나 PCI express 인터페이스의 반도체 스토리지를 도입하는 방법이 있다. 가격이 비싸지만 성능문제를 해결하기 위해 서버를 여러 대 준비하는 것보다는 저렴한 경우가 있기도 하니 검토하도록 한다. 클라우드 서비스의 경우는 대부분 서비스 플랜에 미리 디스크나 서버의 디스크 I/O가 결정이 되어있다. 따라서 상위의 플랜을 사용하여 성능 향상을 도모하는 것이 기본이지만, AWS의 'Amazon Elastic Block Store(EBS)'처럼 디스크 별로 성능이 결정되는 서비스의 경우에는 디스크를 여러 개 준비하여 OS에서 RAID를 구성함으로써 디스크 각각의 성능을 능가할 수 있게 된다.
8.1.6 OS의 네트워크 성능 높이기
네트워크 성능을 높이기 위해서는 서버에서의 네트워크 접속, 인터넷 접속, OS에서의 튜닝 관점 3가지의 관점이 있다. 서버에서의 네트워크 접속 관점으로는 계약한 통신 대역을 100Mbps에서 1 Gbps로 올리는 것과 같은 속도 향상 등으로 이해하면 쉽다. 높은 속도를 지원하고자 할 때는 서버, 케이블, 스위치(허브) 등 모두가 해당 대역대를 지원해야 충분한 성능이 나오기 때문에 이용하고 있는 기기의 전반적인 성능을 확인한다. 또, 서버의 접속은 용량이 높다고 하더라도 상위(인터넷 접속 측)에서 대역을 제한하고 있는 경우도 있으니 참고한다.
OS의 커널 파라미터를 튜닝함으로써 네트워크 성능을 올릴 수도 있으며, 이 내용은 /etc/sysctl.conf에서 설정하게 된다. 네트워크 튜닝은 크게 제한을 완화하여 용량을 늘리는 것 또는 리소스의 재사용을 신속하게 함으로써 회전율을 높이는 것 2가지의 목적을 가진다. 두 가지를 동시에 대응하게 되면 결과적으로는 네트워크 성능이 향상된다.
항목 | 내용 | 설정 예 | 효과 |
net.netfilter.nf_conntrack_max | Netfilter(iptables)에서의 최대 동시 접속 수 | 65536 | 제한 완화 |
net.ipv4.ip_local_port_range | 접속할 경우에 이용하는 포트번호 | 16384 65536 |
제한 완화 |
net.ipv4.tcp_orphan_retries | 종료된 TCP 연결에서 재전송 타임아웃 발생 시의 재시도 횟수 | 2 | 고속 회전 |
net.ipv4.tcp_tw_reuse | TIME_WAIT 상태의 소켓을 재사용 | 1 | 고속 회전 |
net.ipv4.tcp_max_tw_buckets | 한 번에 보유할 수 있는 TIME_WAIT 상태의 소켓 수 | 65536 | 제한 완화 |
net.core.somaxconn | 소켓을 Listen 하는 Back Log의 상한 값 | 2048 | 제한 완화 |
net.core.netdev_max_backlog | 큐잉할 수 잇는 입력 패킷의 최대 수 | 2048 | 제한 완화 |
net.ipv4.tcp_max_syn_backlog | SYN 수신된 접속의 최대 수 | 2048 | 제한 완화 |
8.1.7 OS의 네트워크 사용량 낮추기
OS에는 스스로 네트워크 사용량을 낮추는 기능이 없다. 백업 등을 진행 할 대 데이터 전송의 네트워크 이용량을 낮추고 싶은 경우에는 rsync를 사용할 때 -z 옵션을 주어 압축 전송을 하는 것과 같이 전송 툴에 포함된 압축 기능을 이용하는 것이 좋다. CPU User항목의 CPU가 높고 httpd 프로세스가 많이 잡고 있는 경우, mod_php를 사용하고 있는지 확인한다. 모듈로 인해 CPU 이용률이 높은 경우 Apache가 아닌 모듈 자체를 튜닝해야 할 필요가 있다.
8.1.8 Apache의 CPU 사용률 낮추기
Apache는 프로세스 병렬도 및 라이프사이클 조정이 가능하다. 자식 프로세스형으로 동작하는 prefork MPM과 스레드 형으로 동작하는 worker MPM 중 prefork의 경우 Apache 2.2에서 Default값으로 사용되는 MPM으로 아래와같이 설정이 가능하다.
[prefork MPM으로 설정할 수 있는 항목]
항목 | 의미 |
ServerLimit | 최대 동시 접속 수의 상한값 |
MaxClients | 최대 동시 접속 수 |
StartServers | 시작할 때 생성하는 자식 프로세스의 수 |
MinSpareServers | Idle 상태의 자식 프로세스의 최소값 Idle 상태의 자식 프로세스가 이 값보다 작은 경우, 최대 초속 1process의 속도로 자식 프로세스를 시작한다. |
MaxSpareServers | Idle 상태의 자식 프로세스의 최대값 Idle 상태의 자식 프로세스가 이 값보다 많은 경우, 자식 프로세스를 종료하고 idle 상태의 자식 프로세스를 줄인다. MinSpareServers 값 이하로 설정한 경우는 자동적으로 MinSpareServers+1로 설정된다. |
MaxRequestPerChild | 이 횟수만큼 요청을 처리하면 프로세스를 종료한다. KeepAlive가 유효한 경우는 처음 1회만 카운트한다. |
Apache는 시작할때 StartServers만큼의 자식 프로세스를 생성하고 그 후에는 MinSpareServers 값에 따라 최대 MaxClients까지 자식 프로세스를 생성한다. 그리고 MaxSpareServers와 MaxRequestPerChild에 따라 자식 프로세스를 중지한다. ServerLimit은 MaxClients의 상한 값이기 때문에 MaxClients와 함께 높여가면 된다. 자식 프로세서의 생성(fork)은 CPU 입장에서 적지 않은 부하가 걸리는 처리이므로 가능하다면 피하는 것이 좋다. 특히 부하가 큰 시간대에는 더더욱 피하는 것이 좋다. 리소스가 잘 관리되고 적절하게 용량이 조정된 서버에서의 설정은 ServerLimit=MaxClients=StartServers=MinSpareServers=MaxSpareServers,MaxRequestPerChild=0 (프로세스를 종료하지 않음)과 같다.
MaxRequestPerChild의 목적은 메모리 누수를 위한 것이기 때문에 다른 방법으로 관리하여야 한다. Apache에 메모리 누수가 없더라도 모듈이나 모듈에서 읽어들이는 애플리케이션에 메모리 누수가 있다면 부득이하게 MaxRequestPerChild에 의존하게 되는 경우가 있다. 단, 그 경우에도 MaxRequestPerChild를 작게 설정하면 자식 프로세스들의 수명이 짧아져 자식 프로세스의 생성이 빈번하게 실행되므로 적절한 값을 설정하여야 한다. MPM을 worker로 변경하게 되면 자식 프로세스 모델에서 스레드 모델로 변경되므로, 자식 프로세스 생성이나 컨텍스트 스위칭이 쉬워지지만. PHP는 prefork만을 사용할 수 있기 때문에 MPM을 변경하고자 한다면 NginX 사용을 검토하는 것도 좋은 방법이다.
Apache의 병렬도를 높이다보면 Apache의 에러 로그에 'Too many open files'라는 에러가 출력되는 경우가 있는데, 이것은 Apache의 병렬 수가 높아져 프로세스마다 보유하는 파일 디스크립터의 수가 OS에서 설정한 제한에 걸렸다는 것을 의미한다. OS 전체의 상한 값은 '/etc/sysctl.conf'에서 fx.file-max로 설정하며, 사용자별 상한 값은 ulimit으로 설정하므로, 해당 에러가 나면 값을 확인하도록 한다.
8.1.9 Apache의 메모리 사용률 낮추기
Apache의 메모리 사용량을 낮추기 위해서는 앞에서 설명한 MaxClients를 조정하여 최대 병렬수를 조정한다. Apache나 모듈 또는 PHP 프로그램에 메모리 누수나 또는 그와 비슷한 동작이 있는 경우 MaxRequestPerChild를 작게 설정함으로써 메모리 누수의 영향을 줄일수 있지만, 이때 CPU 성능에도 영향이 있으므로 적용 시 검토를 진행하여야 한다. 다른 방법으로는 사용하지 않는 모듈을 로딩하지 않도록 하여 사용량을 낮출 수 있지만, Linux의 경우 Copy on Wirte라는 구조에 의해 부모 자식 프로세스가 메모리를 공유하여 절약을 하기 때문에 효과가 크지는 않은 방법이다.
8.1.10 Apache의 디스크 I/O 사용량 낮추기
Apache의 디스크 I/O를 낮추려면 OS의 캐시를 이용하여 로딩되는 양을 줄이는 방법이 있다. 메모리 사용량 중 Memcached가 부족하지 않도록 전체 메모리의 사용량을 조절한다. 출력량을 줄이게 되면 디스크 I/O가 줄어듦으로 이미지와 같은 정적인 파일은 출력하지 않도록 하면 사용량 절감 효과가 커진다. 또한 로그의 출력에서 BufferedLogs를 유효화 하면 로그를 버퍼링 할 수 있지만, 해당 기능은 아직은 실험적인 기능으로 동작이 예측가능한 구간에서만 사용하도록 한다.
8.1.11 Apache의 네트워크 성능 높이기와 사용률 낮추기
Apache 자체에서 네트워크 성능을 높이는 기능은 없다. 하지만 기능을 적절히 섞어 사용하면 불필요한 낭비를 줄이고 최대한 보틀넥이 되지 않도록 조정이 가능하다. ① KeepAlive를 이용해 재연결 횟수를 줄인다. ② 데이터를 압축 전송하여 통신량을 줄인다. ③ MPM을 적절하게 설정하여 자식 프로세스가 부족하지 않도록 한다. 이 3가지를 적절히 설정하여 Apache를 튜닝하도록 한다.
8.1.12 애플리케이션 서버의 CPU 사용률 낮추기
사용하는 프로그래밍 언어와 상관없이 애플리케이션 서버에 프레임워크를 이용하고 있는 경우에는 프레임워크가 development 모드 (또는 Debug모드)로 되어있어서 대량의 로그 출력 등에 부하가 많이 걸리고 동작이 느려질 수 있다. 실제 서비스를 위한 서버에서는 반드시 production 모드로 변경하여 빠르게 동작하고 불필요한 로그출력은 하지 않도록 변경한다. 애플리케이션 서버의 CPU 사용률은 처리량으로 결정되는 것이기 때문에 처리 알고리즘을 효율화하고 계산량을 줄임으로써 CPU 사용률을 낮출 수 있다.
PHP, Ruby, Java 및 Go와 같이 스스로 메모리를 malloc/free(할당/해제) 하지 않는 프로그래밍 언어는 Garbage collector가 그 작업을 대신한다. 따라서, 이 GC의 동작을 조정함으로써 실행속도가 변하는 경우가 많다. 예시로, PHP에서는 php.ini 파일에 zend.enable_gc=0이라고 설정하면 GC를 무효화할 수 있다. GC가 유효화 되면 메모리 사용량은 일정하게 유지된다. 이것은 GC가 불필요한 객체를 제거하여 메모리 사용량을 억제하기 때문이다.
8.2 SQL 튜닝에서의 고속화 (SKIP)
8.3 시스템 구성의 변경 시 보틀넥 대책의 기초
시스템 구성변경 패턴에는 처리 능력을 향상시키기 위한 목적의 기능 분할, 스케일 업, 스케일 아웃이 있다. 기능 분할은 기능(역할) 별로 이용하는 서버를 분류함으로써 각 서버를 각각의 역할에 집중시키고, 기능별 처리 능력을 향상시킨다. 구체적으로는 한 대로 [WEB]과 [DB]의 기능을 모두 담당하는 서버가 있는 경우에 WEB과 DB 서버로 각각 나누는 것을 말한다. 스케일 아웃을 하기 전에 기능 분할과 스케일 업을 적절하게 조합하는 것이 중요하다. 스케일 업은 서버의 처리 성능 자체를 향상 시키는 것으로, 각 부분 별 스케일 업의 적용 예는 아래와 같다.
각 부분 | 스케일 업 적용의 예 |
CPU 성능 | 클럭 수를 높임, CPU의 수를 늘림, 코어 수를 늘림, 최신 CPU로 변경 |
메모리 | 용량을 늘림, 클럭 수를 높임 |
네트워크 | 속도를 높임, 네트워크 배치를 변경 |
디스크 | 용량을 늘림, 속도를 높임, 고속 장치로 변경 |
스케일 업은 어느 정도의 스펙까지는 비용대비 효과가 높으므로 예산의 범위 내에서 가능한 한 스케일 업을 하도록 한다. 물리적인 서버를 사용하는 경우에는 디스크와 관련된 변경은 어려울 때가 많으므로 CPU를 바꾸거나 메모리를 늘리는 것이 보다 현실적인 선택일 경우가 많다. 클라우드 환경인 경우 CPU 성능이나 메모리 용량 그리고 네트워크 속도, 디스크 용량이나 디스크 I/O 성능도 변경할 수 있는 환경이 많으므로 잘 활용하도록 한다. 스케일 업에 비용을 투자하면 근본적인 대책을 확인하는 데까지 시간을 버는 효과도 얻을 수 있다. 스케일 업을 할 때는 서버의 정지를 수반하는 경우에 정지해도 괜찮은 타이밍이나 정지해 있는 시간을 잘 활용하여 작업하는 것이 좋다. 또한, 스케일 업 후에 튜닝하는 것을 잊지 않도록 하여 메모리 용량은 늘렸으나 미들웨어 설정을 변경하지 않아 메모리를 활용하지 않는 경우가 없도록 한다.
스케일 아웃은 서버를 여러 대 준비함으로써 처리를 분산시키고 시스템 전체의 처리 능력을 향상시키는 것이다. 즉, 여러 대의 서버를 이용하여 CPU 성능, 메모리, 네트워크, 디스크 처리 등을 분산시킨다. 스케일 아웃을 잘 적용하면 기능 분할이나 스케일 업만으로는 할 수 없는 성능을 낼 수 있게 된다. 특히 클라우드 환경에서는 원활한 확장이 가능하기 때문에 매우 편리하게 사용할 수 있다. 하지만 스케일 아웃의 경우 서버의 종류에 따라 주의할 점이 있다.
WEB을 스케일 아웃할 경우, 사용자 한 병의 연속된 액세스가 다수의 서버로 분산 될 수 있으므로 주의하여야 한다. 관련하여, 세션정보를 공유하거나, 다수의 요청을 초과하는 임시 파일을 작성하지 않거나, 서버 간에 정보를 공유하도록 설정하여야 한다. 세션정보를 공유하도록 설정하면 분산 목적지 서버가 바뀔 때마다 로그아웃 되거나 입력 내용이 지워지는 등의 문제를 피할 수 있다. 또한 임시 파일을 작성하지 않거나 서버 간에 공유를 하면 업로드 처리를 할 수 없는 경우가 생기는 문제를 피할 수 있다. 이와 같은 사항들을 고려하지 않기 위해서는 로드밸런서에 한 번 액세스 한 서버에 일정 기간 동안은 지속적으로 액세스 하도록 구현할 수 도있다. 동일한 접속 소스로부터의 액세스는 일정 기간 같은 서버에 분산시키고 cookie에 분산 목적지 서버의 정보를 저장하여 그 정보를 바탕으로 분산하는 식으로 구현을 한다.
DB를 스케일 아웃할 경우, 하나의 Master DB에 대해 다수(최저 2대)의 Slave DB를 준비하는 것이 정석이다. MySQL이나 PostgreSQL의 경우 RDBMS가 가진 리플리케이션 기능을 이용한다. 여기에서는 MySQL을 예로 설명한다. DB를 스케일 아웃하여 여러 대로 구성하는 경우에는 ① Master DB에만 쓴다(write) ② Slave DB로의 데이터 반영에는 지연이 발생한다. 두 가지를 주의한다.
8.4 [DB] 스케일 아웃 구현의 예 (SKIP)
8.5 기능 분할 구현의 예
서버를 분할하는 패턴으로는 ① 웹 서버와 DB 서버를 나눈다 ② 웹 서버와 AP 서버를 나눈다 ③ 웹 서버와 Proxy 서버를 나눈다 3가지가 있다. WEB은 애플리케이션에서 CPU를 사용하고, 콘텐츠 로딩을 위해 메모리와 디스크 I/O를 사용하고 DB는 Where, Join, Order By 등의 기능에서 CPU를, 데이터 저장에 메모리와 디스크 I/O를 사용하기 때문에 WEB과 DB를 분할하면 리소스 경합을 해소할 수 있다는 장점이 있다.
[WEB-DB서버 구성변경(분리) 작업] 1) 애플리케이션에 정의되어 있는 DB 접속 대상을 변경 - 원래 소켓으로 접속하고 있는 경우, TCP/IP 접속으로 변경 - 접속 대상이 localhost 등인 경우, DB 서버의 IP주소로 변경 2) MySQL(DB)에서 사용자 인증 설정을 변경 - MySQL에서 사용자를 생성하고 권한을 설정할 때 접속 대상을 지정하는 경우, 새로 접속 권한을 부여 |
다음으로 웹 서버와 애플리케이션 AP 서버를 나누는 것이 전형적이며, 이미지나 CSS, JavaScript 등의 정적인 콘텐츠 제공은 웹 서버에 맡기고, 비즈니스 로직을 처리하는 전용 서버로 AP 서버를 구축한다. AP 서버나 DB 서버의 CPU 처리량은 어쩔 수 없이 많아지기 때문에 앞에서 그 이외의 처리를 떠맡아 AP 서버와 DB 서버가 비즈니스 로직에 집중할 수 있도록 한다. 이러한 구성으로 진행하면 AP 서버는 병렬 수가 줄어 처리에 집중할 수 있다. 웹 서버에서는 KeepAlive와 MPM을 튜닝하도록 한다.
'Book Study > 웹 엔지니어가 알아야 할 인프라의 기본' 카테고리의 다른 글
Chapter 7. 웹 서비스 튜닝 1 : 보틀넥을 찾는 방법 (0) | 2021.04.17 |
---|---|
Chapter 6. 웹 서비스 운용 2 : 상태 모니터링 (0) | 2021.04.11 |
Chapter 5. 웹 서비스 운용 1 : 시스템 감시의 기본 (0) | 2021.04.04 |
Chapter 4. 인프라 준비의 기초 지식 (0) | 2021.03.30 |
Chapter 3. 웹 서비스 서버 구성의 모범 사례 (0) | 2021.03.25 |