문제

저는 약 12,000명의 사용자(쓰기량이 많음), 1Gb RAM을 갖춘 단일 VPS에서 최대 100명의 동시 사용자로 구성된 커뮤니티 웹사이트를 소유하고 있습니다.부하는 3을 넘는 경우가 거의 없으며 응답도 상당히 좋습니다.

현재는 DB 쿼리 결과를 단순 파일 캐시에 저장해 DB의 부하를 완화하고 있지만, 여전히 웹사이트의 동시 접속자가 220명이 넘으면 속도가 느려질 수 있다(부하 테스트).

병목 현상이 무엇인지 어떻게 알 수 있나요?

캐시가 잘 작동하므로 DB는 괜찮다고 가정하지만 디스크 IO로 인해 문제가 발생할 수 있습니다.각 페이지로드에는 DB 또는 파일 캐시에서 가져온 약 10개의 포함과 10-20개의 쿼리와 많은 PHP 처리가 포함됩니다.

파일 캐시 대신 Memcache를 사용해 보았지만 놀랍게도 로드 테스트에서는 파일 캐시를 더 좋아하는 것 같았습니다.

대체 PHP 캐시를 사용할 계획이지만 해당 캐시가 어떻게 무효화되는지 여전히 이해하지 못합니다.모든 요청을 처리하는 단일 index.php가 있습니다.캐시는 각 개별 요청에 대한 결과를 저장합니까?내 포함(또는 캐시의 쿼리 결과) 중 하나가 변경되면 캐시가 자동으로 지워지나요?

병목 현상을 찾기 위한 다른 제안 사항이 있습니까(xdebug 시도)?

감사합니다, 햄릿

도움이 되었습니까?

해결책

대체 PHP 캐시를 사용할 계획이지만 여전히 해당 캐시가 무효화되는 방법을 이해하지 못합니다.모든 요청을 처리하는 Singe Index.php가 있습니다.캐시가 각 개별 요청에 대한 결과를 저장합니까?내 포함 (또는 쿼리가 캐시에서 결과) 변경되면 캐시를 자동으로 지우나요?

APC는 출력을 캐시하지 않습니다.컴파일된 바이트코드를 캐시합니다.

기본적으로 일반적인 PHP 요청은 다음과 같습니다.

  1. PHP 파일은 바이트코드로 구문 분석되고 컴파일됩니다.
  2. PHP 인터프리터는 바이트코드를 실행합니다.

APC는 첫 번째 단계의 결과를 캐시하므로 동일한 코드를 반복해서 재분석/재컴파일하지 않습니다.기본적으로는 여전히 stat()캐시된 복사본이 컴파일된 이후 파일이 수정되었는지 확인하기 위해 요청할 때마다 PHP 파일을 확인합니다. 따라서 코드를 변경하면 캐시된 복사본이 자동으로 무효화됩니다.

임의의 사용자 데이터를 저장하기 위해 memcached를 사용하는 것처럼 APC를 사용할 수도 있습니다.하지만 다음 사항을 명심하세요.

  1. Memcached 서버는 여러 서버에 데이터를 제공할 수 있습니다.APC에 캐시된 데이터는 실제로 로컬에서만 사용할 수 있습니다.각 개별 서버의 APC에 해당 데이터의 복사본 4개를 보유하는 것보다 하나의 memcached 상자에서 4개의 서버로 엄청난 양의 데이터를 제공하는 것이 더 좋습니다.
  2. 내 경험에 따르면 Memcached는 단일 캐시 키에 대한 많은 수의 동시 쓰기를 처리하는 데 더 좋습니다.
  3. APC는 캐시가 가득 차는 상황에 잘 대처하지 못하는 것 같습니다.조각화가 증가하고 성능이 저하됩니다.

또한 다음 사항에 주의하세요.일종의 잠금 메커니즘을 설정하지 않으면 동시 쓰기로 인해 파일 기반 캐시가 손상될 가능성이 높습니다.잠금을 구현한 경우 자체적으로 병목 현상이 발생할 수 있습니다.IMO, 동시성은 까다롭습니다. memcached/APC/데이터베이스가 처리하도록 하세요.

다른 팁

당신은 당신이 사용한 것을 언급합니다 xdebug - 무엇을 할 수 없었습니까? 일반적으로 병목 현상 추적을 시작하려면 요청을 프로파일 링 한 다음 결과 "캐시 그라인드"파일을보십시오. Kcachegrind 또는 윈클 린드.

캐시 시스템 사용에 관해서는 귀하와 같은 동적 스크립트가 일반적으로 다음과 같은 작업을 수행합니다.

  • 고유 입력에서 스크립트로 캐시 "키"를 구성하십시오.
  • 캐싱 시스템에 해당 키에 대한 데이터가 있는지 문의하십시오. 있다면, 당신은 가기 좋습니다!
  • 그렇지 않으면 모든 노력을 기울여 데이터를 생성하고 캐싱 시스템에 다음에 원하는 키 아래에 저장하도록 요청하십시오.

APC 캐시 PHP 코드의 구문 분석 버전을 캐싱하여 속도를 높이는 데 도움이 될 수 있습니다.

MySQL 자체 쿼리 캐시가 있습니다.

설정하여 활성화 할 수 있습니다 query_cache_size 더 이상 0.

쿼리 결과는 쿼리가 반복적으로 구두로 반복되고 비 결정적 함수, 세션 변수 및 기타 설명과 같은 특정 사항을 포함하지 않으면 캐시에서 가져옵니다. 여기:

쿼리의 캐시는 발행하여 무효화됩니다. DML 기본 쿼리에 대한 작업.

테스트 서버에서 APC를 켜고 구성했으며 성능이 약 400% 증가했습니다.

응답 시간이있는 동시 사용자 300 명 최대 1,4 초 :) 시작하기에 좋습니다.


업데이트:

라이브 서버 테스트 결과

원래의:

APC 없음 : 220 동시 사용자, 서버로드 20, 응답 시간 5000ms

APC 없음 : 250 명의 동시 사용자, 서버로드 20+, 사이트를 사용할 수 없습니다.

새로운:

APC 활성화 : 250 동시 사용자, 서버로드 2, 응답 시간은 600ms입니다.

APC 활성화 : 350 동시 사용자, 서버로드 10, 응답 시간은 1500ms입니다.

APC 활성화 : 500 동시 사용자, 서버로드 20, 응답은 5000ms + 사이트입니다. 사이트는 완전히 작동하지만 약간 느리지 만 정상적으로 사용할 수 있습니다.

제안 해주셔서 감사합니다. 이것은 매우 큰 개선입니다.

사이트가 쓰기로 인해 쿼리 캐시가 비활성화되어 전체 테이블에 대해 캐시가 지속적으로 무효화됩니다.

나는 당신의 데이터베이스가 IO 바운드 일 가능성이 높다고 말하고, 나는 "vps"가 무엇인지 정확히 알지 못하지만, 그것이 일종의 VM이라면, IO를 수행하는 것이 거의 제대로 보장되지 않습니다.

실제 하드웨어로 최대한 빨리 사용하십시오. 현명한 양의 RAM을 얻습니다 (1G는 작습니다. 16G는 더 합리적입니다).

그런 다음 DB를 조정하여 제대로 작동 할 수 있습니다. 데이터는 총 얼마나 큽니까? 데이터베이스 캐시 (Dodgy Query 캐시, 적절한 InnoDB 버퍼 풀 1이 아님)에 맞게 모든 것 (또는 대부분)을 가져올 수 있다면 그렇게하십시오.

InnoDB 엔진을 사용하고 있다고 가정합니다. 그렇다면 모든 데이터에 충분히 커질 수 있도록 버퍼 풀을 설정하십시오. RAM이 충분하지 않은 경우, 할 때까지 더 많이 구입하십시오 (아니요!).

그런 다음 DB 쿼리가 상당히 나쁘더라도 빠르도록해야합니다 (예).

까다로운 비트는 단일 컴퓨터가있는 경우 MySQL과 PHP 사이의 RAM 사용을 개척하는 방법입니다. 특히 Prefork와 많은 MaxClients를 사용하는 경우 웹 서버 (Apache라고 가정합니다). 그것의 데이터베이스.

직무에 대한 괜찮은 모니터링 (트렌드 포함)에 대한 괜찮은 모니터링을 받고 신중하게 변경하고 만들 때 정확히 기록하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top