Skip to content
isdnetworks
Go back

장비에 맞춰 실행 설정을 조정했다

같은 코드를 두 장비에 올렸는데 한쪽만 느려서 코드가 아니라 코드 밖에서 차이를 찾아야 했다.

Table of contents

Open Table of contents

증상 — 사양이 달랐다

서버 A서버 B 의 사양부터 비교했다.

서버 A   CPU 8코어  RAM 32G
서버 B   CPU 2코어  RAM 4G

서버 B 가 느렸는데 사양 차이만큼이 아니라 훨씬 느렸다.

메모리 상태를 봤다.

$ free -m
              total  used  free
Mem:           3936  3820    41
Swap:          2047  1204   843

스왑을 1.2GB나 쓰고 있어서 디스크를 타느라 느린 것이었다.

원인 — 설정이 같았다

두 장비의 php-fpm 설정 파일이 같았다.

pm = dynamic
pm.max_children = 50
pm.start_servers = 10

max_children서버 A 기준으로 잡혀 있었다.

max_children 50개가 4GB 메모리에 안 들어가니 나머지가 스왑으로 밀린다. 기본 설정은 그 장비의 사양을 모른 채 그대로 적용된다.

조치 — 장비에 맞춘 계산

서버 B 에 맞춰 계산해서 다시 잡았다.

프로세스 하나가 쓰는 메모리   약 60MB (실측)
시스템·DB 용으로 남길 것       1.5G
쓸 수 있는 것                  4G - 1.5G = 2.5G
최대 프로세스 수               2.5G / 60MB ≈ 40
여유를 두고                    30

max_children 을 30으로 낮췄다.

프로세스 하나가 쓰는 양은 짐작하지 않고 쟀다.

$ ps --no-headers -o rss -C php-fpm | awk '{s+=$1; n++} END {print s/n/1024 " MB"}'
58.2 MB

rss 평균이 58.2MB라 그 값으로 계산했다.

문서에 적힌 일반적인 rss 값은 우리 코드와 부하에서 맞지 않을 수 있다. rss 를 짐작으로 잡았으면 너무 줄이거나 여전히 모자랐을 것이다.

설정 — 스왑과 장비별 프로파일

커널의 스왑 성향도 함께 봤다.

$ sysctl vm.swappiness
vm.swappiness = 60

메모리에 여유가 있어도 스왑을 쓰려는 값이었다.

$ sysctl -w vm.swappiness=10

낮추되 아예 끄지는 않았는데 끄면 메모리가 모자랄 때 프로세스가 강제 종료된다.

설정 파일은 장비별로 나눴다.

config/php-fpm/high.conf   max_children = 50
config/php-fpm/low.conf    max_children = 30
mem=$(free -m | awk 'NR==2 {print $2}')
if [ "$mem" -gt 16000 ]; then profile=high; else profile=low; fi
cp "config/php-fpm/$profile.conf" /etc/php/7.2/fpm/pool.d/app.conf

메모리 크기를 보고 highlow 중 하나를 고르므로 장비가 늘어도 손으로 고를 필요가 없다.

주의 — 설정끼리의 정합

사양에 묶여 있는 설정이 더 있었다.

DB 버퍼 풀       메모리에 비례
워커 수          코어 수에 비례
연결 수 상한     프로세스 수에 비례

셋 다 서버 A 기준이었다.

innodb_buffer_pool_size = 8G     # B 에서는 1G
max_connections = 500            # B 에서는 100

프로세스가 30인데 max_connections 를 500 허용하면 의미가 없다.

설정끼리도 서로 맞아야 했다. max_children 만 고치면 연결이 남거나 모자라서 다른 자리에서 문제가 난다.

검증 — 전후 측정과 한계

바꾸고 나서 실제로 나아졌는지 쟀다.

전   평균 응답 1,840ms   스왑 사용 1.2G
후   평균 응답   320ms   스왑 사용 0

스왑 사용이 0이 된 것이 컸고 응답 시간과 둘 다 봤다.

한계도 부하를 걸어 확인했다.

$ ab -n 1000 -c 30 http://b/

동시 30까지는 견뎠고 50에서 대기가 생겨 그 숫자를 적어 뒀다.

상한에 닿았는지도 재게 했다.

# 프로세스가 상한에 닿았는지
$ curl -s http://localhost/status | grep "listen queue"
listen queue: 12

listen queue 에 대기가 쌓이면 프로세스가 모자란 것이다.

listen queue 에 계속 대기가 생기면 장비를 늘리거나 설정을 다시 봐야 한다. 그 판단을 숫자로 하게 됐다.

정리


Share this post on:

Previous Post
복제 구성을 장비와 같이 적었다
Next Post
전수 집계가 한 경로만 검증했다