여유 메모리가 많이 남아 있는데 왜 Swap을 사용합니까?

여유 메모리가 많이 남아 있는데 왜 Swap을 사용합니까?

나는 좋은 메모리 리소스를 갖춘 꽤 좋은 웹(전용) 서버를 가지고 있습니다.

System information
Server load     2.19 (8 CPUs)   
Memory Used     29.53% (4,804,144 of 16,267,652)    
Swap Used   10.52% (220,612 of 2,097,136)   

보시다시피, 사용 가능한 여유 메모리가 많을 때 내 서버는 스왑을 사용하고 있습니다.

이것이 정상입니까, 아니면 구성이나 코딩에 문제가 있습니까?

주의:
내 MySQL 프로세스는 어떤 이유로 CPU 성능의 160% 이상을 사용하고 있습니다. 왜인지는 모르겠지만 동시접속자가 70명도 안되네요...

답변1

이것은 완전히 정상입니다.

시스템 시작 시 여러 서비스가 시작됩니다. 이러한 서비스는 자체적으로 초기화되고, 구성 파일을 읽고, 데이터 구조를 만드는 등의 작업을 수행합니다. 그들은 약간의 메모리를 사용합니다. 이러한 서비스 중 다수는 사용하지 않기 때문에 시스템이 작동하는 동안 다시 실행되지 않습니다. 그 중 일부는 몇 시간, 며칠 또는 몇 주 안에 실행될 수 있습니다. 하지만 이 모든 데이터는 물리적 메모리에 있습니다.

물론 시스템은 이 데이터를 버릴 수 없습니다. 문자 그대로 절대 접근할 수 없다는 것을 증명할 수는 없습니다. 예를 들어, 이러한 서비스 중 하나는 상자에 대한 원격 액세스를 제공하는 서비스일 수 있습니다. 일주일 동안 사용하지 않았을 수도 있지만 사용한다면 효과가 더 좋았을 것입니다.

그러나 시스템은 물리적 메모리를 디스크 캐시와 같은 용도로 사용하거나 성능을 향상시키는 다른 방식으로 사용하고 싶을 수도 있다는 것을 알고 있습니다. 그래서 기회주의적 교환을 수행합니다. 더 이상 할 일이 없을 때, 스왑 공간을 이용하여 아주 오랫동안 사용하지 않은 데이터를 디스크에 씁니다. 그러나 페이지는 여전히 실제 메모리에 유지됩니다. 따라서 교체하지 않고도 계속 액세스할 수 있습니다.

이제 시스템이 나중에 다른 용도로 물리적 메모리가 필요한 경우 해당 페이지를 이미 교환하기 위해 기록했기 때문에 간단히 해당 페이지를 버릴 수 있습니다. 이는 시스템에 두 가지 장점을 모두 제공합니다. 데이터는 여전히 메모리에 보관되므로 디스크에서 읽지 않고도 액세스할 수 있습니다. 그러나 시스템이 다른 목적으로 해당 메모리를 필요로 하는 경우 먼저 해당 메모리를 기록할 필요는 없습니다. 모든 곳에서 큰 승리를 거두었습니다.

답변2

과거 어느 시점에 머신에 있는 실제 RAM보다 더 많은 메모리가 필요했던 경우 이런 일이 발생할 수 있습니다. 이때 일부 데이터가 스왑 공간에 기록됩니다.

나중에 메모리가 해제되면 스왑의 데이터가 자동으로 RAM으로 다시 읽혀지지 않습니다. 이는 일부 프로세스에서 스왑의 데이터가 실제로 필요한 경우에만 발생합니다. 이것은 완전히 정상입니다.

mysql 프로세스의 경우 이는 모두 실행하는 쿼리 유형에 따라 다릅니다. 이론적으로 사용자 수에 관계없이 이러한 로드를 얻는 데는 매우 복잡한 쿼리 2개로도 충분할 수 있습니다. 느린 쿼리 로그를 활성화하면 로드 집약적인 쿼리에 대한 더 많은 통찰력을 얻을 수 있습니다.

답변3

또한 이 동작을 변경하여 sysctl -w vm.swappiness=10실제로 필요할 때까지 스왑 사용을 크게 줄일 수 있습니다.

MySQL의 경우 최소한 다음을 사용하여 기본 구성 테스트를 수행했습니까?튜닝-프라이머.sh스크립트?

답변4

이는 아마도 David가 설명했듯이 Linux 커널의 정상적인 동작일 수도 있습니다.MySQL "스왑 광기" 문제. 귀하의 경우(8 CPU, 총 16GB RAM, 5GB 사용) 이를 위해서는 컴퓨터가 4개의 노드(소켓)와 노드당 4GB RAM 및 4개의 MySQL InnoDB 버퍼 풀을 갖춘 NUMA 시스템이어야 합니다. GB.

간단히 말해서(자세한 내용은 위의 링크를 읽어야 함) 다음과 같은 일이 발생합니다.

  1. 시스템이 시작되면 프로세스는 일부 메모리를 사용하여 모든 NUMA 노드에 분산됩니다.
  2. MySQL이 시작되면 InnoDB 버퍼 풀에 4GB를 할당하여 NUMA 노드의 RAM을 채우고 다른 노드의 일부 RAM을 사용합니다.
  3. 그런 다음 할당된 RAM을 한 NUMA 노드에서 다른 노드로 이동할 수 없는 Linux 커널은 부족한 노드에서 페이지를 교체하는 것이 좋은 생각이라고 생각합니다(또는 페이지를 교체해야 하기 때문에 페이지를 교체해야 함).

이를 방지하려면 MySQL의 메모리 할당을 변경하여 모든 코어에 RAM을 할당하십시오(자세한 내용은 위 링크 참조).

관련 정보