기존 20기가 메모리에서 이번에 32기가로 증설하였습니다.

데스크탑 CPU, G4560이 들어가는 노트북이라 최대 메모리한도가 32기가 입니다.

일단 메모리는 풀셋팅이 되었고, 나중에 i7급 cpu가 가격이 떨어지면 그때 cpu업그레이드를 할 생각입니다.

 

메모리를 올린 김에, 그동안 기진곰님과 회원분들의 유익한 대화를 엿듣고 배운 내용을 가지고 서버 셋팅을 해봤습니다.

 

먼저, 그간 인터넷에 알려진 내용인 메모리 셋팅법을 찾아봤습니다.

 

#ps -ylC php-fpm --sort:rss

로 프로세스가 사용하는 메모리를 찾았습니다.

이미지 2.png

약 60~70메가가 소모됩니다. 뭐가 많네요. ㅎㅎ

 

#ps --no-headers -o "rss,cmd" -C php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"Mb") }'

로 더 자세히 찾아봅니다.

이미지 3.png

각 프로세스당 평균 약 62메가가 나옵니다.

 

저는 mysql에 16기가를 셋팅했습니다.

그런데 free -h로 보니깐 7기가 남짓 사용하고 있습니다.

 

이미지 5.png

여유분이 23기가가 남아있네요.

 

저는 그냥 16기가로 php-fpm에 할당하려고 합니다.

 

일반적인 인터넷에서 알려진 방식은 아래와 같습니다.

 

평균 62M를 사용하는 processor를 기준으로 pm.max_children은 16000MB / 63MB = 254 로 계산이 됩니다.

즉 총 254개의 php-fpm processor를 띄울 수 있게 되겠네요.

 

그럼 다음과 같이 설정을 할 수 있겠습니다.

 

pm.max_children = 254 //동시 사용할수 있는 최대 프로세스 수

pm.start_servers = 75  //처음 시작할 때 

pm.min_spare_servers = 50 //최소 사용값

pm.max_sapre_servers = 125 //최대  사용값 (이 수가 넘어가면 프로세스 삭제)

 

최대 여유 메모리로 php-fpm을 사용할 수 있는 공식이 나왔습니다.

 

하지만, 최대로 사용할 수 있다고 해서 이걸 다 쓰면 서버가 항상 북적거리가 될 겁니다.

php-fpm의 순간적인 메모리 사용량이 급격히 늘어날 수도 있기 때문에, 최대 프로세스 값을 줄여서 각 프로세스가 메모리를 여유있게 사용할 수 있어야 더 안전하겠죠.

 

즉, 현재 각 프로세스당 63메가를 책정한 값을 좀더 여유있게 최대 600메가 정도로 여유폭을 준다라고 생각을 해보겠습니다.

 

16000MB / 600MB = 26이 나왔네요.

 

pm.max_children = 26 //동시 사용할수 있는 최대 프로세스 수, 600메가 메모리 사용하는 유저가 동시에 26명이 클릭할 때까지는 문제가 없을 것으로 예상.

pm.start_servers = 8  //처음 시작할 때 max_children 30%선

pm.min_spare_servers = 5 //최소 사용값 max_children 20%선

pm.max_sapre_servers = 13 //최대  사용값 max_children 의 50% (이 수가 넘어가면 프로세스 삭제)

 

중요포인트 : php-fpm 프로세서를 많이 띄우려고 하지 말고, 빨리 처리하도록 하는 것이 중요. 그러기 위해서 각 프로세서의 메모리 사용 여유폭을 넉넉히 책정해야함.

 

원글 : https://godpeople.or.kr/4962364

  • profile

    서버가 놀고 있는 상태에서 측정한 RSS값은 아무 의미가 없습니다. PHP 엔진이 잡아먹는 최소한의 용량일 뿐, 뭔가를 실행하기 시작하면 늘어나기만 하지 절대 줄어들지는 않으니까요. 엘리베이터의 무게 제한이 1톤인데 성인이라면 최소 40kg은 나갈 테니 25명 탈 수 있겠네~라고 추정하는 것과 마찬가지입니다. 60kg 나가는 사람도 있고 80kg 나가는 사람도 있는데 말이죠 ㅠㅠ 대체 누가 RSS값을 갖고 php-fpm 프로세스 갯수를 계산하자는 신박한 발상을 처음 했는지 모르겠지만, 그런 가짜뉴스를 생산하거나 유포하는 블로그라면 서버 세팅에 대해 어떤 조언을 하더라도 믿을 수 없을 것 같습니다.

     

    1. 메모리 사용량이 실제로 어디까지 늘어날 것인지 예상하는 데 있어서 가장 중요한 설정은 memory_limit입니다. RSS 60M를 잡아먹고 있는 프로세스에서 용량 큰 사진을 리사이즈하거나 하면 60M + memory_limit만큼 메모리를 잡아먹습니다. 대개 memory_limit은 128M가 기본값이고, 그것보다 더 늘리는 경우는 있어도 줄이는 경우는 없지요.

     

    2. 그런데 RSS 60M짜리 프로세스가 30개 떠있다고 해서 60 × 30 = 1800M의 메모리를 잡아먹는 것이 아닙니다. PHP의 기본 메모리 사용량 중 대부분을 차지하는 각종 확장모듈 및 opcache 등은 모든 프로세스가 공유하고 있기 때문입니다. top에서 SHR라고 나오는 부분인데, 하나를 제외한 다른 모든 프로세스에서 SHR 부분은 제외하고 더해야 합니다. 그렇게 계산하고 나면 사실 얼마 남지 않습니다. memory_limit에 10~20M만 더해서 계산해도 될 정도입니다.

     

    위의 1과 2가 대충 상쇄되는 덕분에, RSS를 기준으로 평균을 계산해도 웬만하면 서버가 터지지는 않습니다. 소가 뒷걸음질치다가 쥐 잡은 격이지요. 그러나 그렇다고 그게 정답은 아닙니다.

     

    3. 동접수가 많은 사이트는 PHP 7.0 이후 opcache가 깨지는 치명적인 버그를 우회하기 위해 opcache 용량을 상당히 많이 주어야 합니다. 동접 1000명이 넘어가면 안전을 위해 기본 1G 이상 세팅해 드리고 있는데, 이것도 RSS 용량을 차지하기 때문에 php-fpm 프로세스 1개당 RSS가 1.5G에 육박하는 흠좀무한 상황이 연출되기도 합니다. 물론 이런 프로세스가 수십 개 돌아가더라도 1.5G × 수십 배의 메모리를 잡아먹지는 않습니다.

     

    4. CPU 사양이 높지 않은 서버라면 메모리 용량이 아니라 CPU 코어수와 예상 동접수를 기준으로 php-fpm 프로세스 갯수를 결정하는 것이 더 유리합니다. G4560이라면 2코어 4쓰레드인데, 메모리가 아무리 많더라도 php-fpm 프로세스 갯수는 쓰레드 숫자 × 4를 넘어가지 않는 것이 좋습니다. 메모리에 여유를 주기 위해서가 아니라 CPU가 너무 붐비기 때문입니다. 또한 일반적인 커뮤니티 기준으로 php-fpm 프로세스 하나당 동접 100명 정도를 처리할 수 있다고 보는데, 프로세스 갯수를 26으로 한다면 과연 이 CPU가 동접 2600명을 감당할 수 있을 것인지 물어봐야 합니다. 감당할 수 없는 동접수를 억지로 처리하라고 시키면 "싫어, 안해, 못해" 하고 뻗으니까요.

     

    위의 3과 4까지 감안하여 제가 흔히 권하는 기준이 [ (CPU 쓰레드수 × 4)(남는 메모리 GB × 5~6)적은 쪽 ] 입니다. 후자는 일반적인 memory_limit 기본값과 RSS값, opcache 등을 감안하여 프로세스 1개당 160~200M 정도를 사용한다고 추정하는 것이고요. 이렇게 계산하면 저사양 가상서버가 아닌 이상 대체로 메모리가 남는데, 남는 메모리는 memcached처럼 성능에 도움이 되는 곳에 사용하면 됩니다.

     

    결론적으로 26도 조금 많기는 하지만, 254보다는 확실히 낫습니다.^^

  • profile profile
    와... 어떻게 하면 기진곰님처럼 해박할 수 있을까요.
    그동안 서버 메모리 관련해서 가장 속시원한 글을 마주할 수 있어서 영광입니다.
    1~4번 항목을 모두 감안해서 다시 셋팅을 해봐야겠습니다.
    그동안 cpu와의 관계에 대해서는 잘 정리가 안되었는데, 큰 도움이 되었습니다. ^^

    궁금한게 있는데요.
    [ (CPU 쓰레드수 × 4) 와 (남는 메모리 GB × 5~6) 중 적은 쪽 ] 이라고 하셨는데, 후자의 경우 제 상황에서 23기가 X 5~6 이라는 계산이 어떻게 적용되는지 모르겠습니다. ㅠ
  • profile profile
    23기가에 5~6을 곱하면 너무 큰 숫자가 나오니까, 쓰레드 수 × 4에 가깝게 세팅하시면 됩니다. 게다가 DB에 16기가를 할당하셨다면 실제로 23기가가 남는 것도 아니지요. 언제라도 디비가 16기가 다 내놓으라고 하면 줘야 하니까요.
  • profile profile
    네. 이제 이해했습니다.
    정리하자면, 기존에 인터넷에 알려진 방식대로 할게 아니라, 전체적인 구조를 이해한 상태에서 기본적으로 [ (CPU 쓰레드수 × 4) 와 (남는 메모리 GB × 5~6) 중 적은 쪽 ] 공식을 대입하는 거군요.
    나머지는 캐쉬쪽으로 여유 메모리를 넘겨주면 되는 거구요.

    CPU 쓰레드 수가 적은 저의 경우에는 쓰레드에 맞춰서 셋팅을 하고, 쓰레드가 많은 CPU 사용시 메모리가 적은 경우에 후자를 이용할 셋팅 값이 적용될 여지가 생기겠네요.

    메모리도 결국 CPU에 성능과 쓰레드에 따라서 결정되는 걸로 정리가 되네요.
    와.. 이제 메모리쪽은 뭔가 개념이 잡힌 거 같습니다. ^^
    너무 감사합니다.
  • profile
    신기한 내용들이 많네요. 감사합니다.