고부하 사이트에서 PHP를 사용하기위한 전술


242

당신이 이것에 대답하기 전에 나는 서버로드를 높이기에 충분한 인기있는 것을 개발하지 않았습니다. PHP와 몇 가지 최적화 기술을 알고 있지만 지구상에서 방금 착륙 한 외계인으로 나를 처리하십시오.


제대로 작동하면 꽤 많은 사용자를 확보 할 수 있는 PHP 도구를 개발 중입니다. 그러나 프로그램을 완전히 개발할 수는 있지만 엄청난 트래픽을 처리 할 수있는 무언가를 만드는 데는 실마리가 거의 없습니다. 여기에 몇 가지 질문이 있습니다 (이 질문을 리소스 스레드로 자유롭게 전환하십시오).

데이터베이스

현재 PHP5에서 MySQLi 기능을 사용할 계획입니다. 그러나 사용자 및 컨텐츠와 관련하여 데이터베이스를 어떻게 설정해야합니까? 실제로 여러 데이터베이스 가 필요 합니까? 현재 모든 것이 하나의 데이터베이스로 뒤죽박죽되었습니다. 사용자 데이터를 하나의 실제 콘텐츠로 다른 것으로, 마지막으로 핵심 사이트 콘텐츠 (템플릿 마스터 등)를 다른 데이터베이스로 확산시키는 것을 고려하고 있었지만. 이것에 대한 나의 추론은 다른 데이터베이스에 쿼리를 보내면 하나의 데이터베이스 = 3로드 소스로 데이터베이스에 대한로드를 완화한다는 것입니다. 모두 동일한 서버에있는 경우에도 여전히 효과적입니까?

캐싱

페이지를 작성하고 변수를 교체하는 데 사용되는 템플릿 시스템이 있습니다. 마스터 템플릿은 데이터베이스에 저장되며 템플릿을 호출 할 때마다 캐시 된 사본 (html 문서)이 호출됩니다. 현재이 템플릿에는 두 가지 유형의 변수 인 정적 변수와 동적 변수가 있습니다. 정적 변수는 일반적으로 페이지 이름, 사이트 이름, 자주 변경되지 않는 것입니다. 동적 변수는 각 페이지로드에서 변경되는 것입니다.

이것에 대한 내 질문 :

다른 기사에 대한 의견이 있다고 가정 해보십시오. 더 나은 해결책은 페이지를로드 할 때마다 간단한 주석 템플릿을 저장하고 (DB 호출에서) 주석을 렌더링하거나 주석 페이지의 캐시 된 사본을 HTML 페이지로 저장하는 것입니다-주석이 추가 / 편집 / 삭제 될 때마다 페이지가 다시 캐시됩니다.

드디어

PHP에서 고부하 사이트를 운영하기위한 팁 / 포인터가 있습니까? 사용 가능한 언어 인 것이 확실합니다-Facebook 및 Yahoo! 우선 순위를 높이십시오.하지만주의해야 할 경험이 있습니까?


9
3.5 년이 지난 후에도 작업 한 내용을 기억할 수 없습니다. 너무 멋지다고 생각하고 싶습니다. :)
Ross

8
조기 최적화에 대한 교훈을 드리겠습니다 :)
Rimu Atkinson

답변:


89

두 사이트가 비슷하지 않습니다. 문제 지점이 어디 있는지 확인 하려면 jmeter 및 벤치 마크와 같은 도구가 필요 합니다. 추측하고 개선하는 데 많은 시간을 할애 할 수 있지만 변경 사항을 측정하고 비교할 때까지 실제 결과는 표시되지 않습니다.

예를 들어, 수년 동안 MySQL 쿼리 캐시는 모든 성능 문제에 대한 솔루션이었습니다. 사이트 속도가 느리면 MySQL 전문가가 쿼리 캐시를 켤 것을 제안합니다. 쓰기로드가 높으면 실제로 캐시가 손상되고있는 것으로 나타났습니다. 테스트하지 않고 전원을 켜면 알 수 없습니다.

그리고 스케일링이 완료된 것을 잊지 마십시오. 10req / s를 처리하는 사이트는 1000req / s를 지원하도록 변경해야합니다. 10,000req / s를 지원할만큼 운이 좋으면 아키텍처도 완전히 다르게 보일 것입니다.

데이터베이스

  • MySQLi를 사용하지 마십시오 - PDO가 '현대'OO 데이터베이스 액세스 레이어입니다. 가장 중요한 기능은 쿼리에서 자리 표시 자입니다. 서버 측 준비 및 기타 최적화 기능을 사용하는 것이 현명합니다.
  • 이 시점에서 데이터베이스를 분리하고 싶지 않을 것입니다. 하나의 데이터베이스가 잘리지 않는 경우 앱에 따라 몇 가지 기술을 확장 할 수 있습니다. 쓰기보다 읽기가 많은 경우 일반적으로 추가 서버로 복제하는 것이 좋습니다. 샤딩은 여러 머신에서 데이터를 분할하는 기술입니다.

캐싱

  • 데이터베이스에 캐시하고 싶지 않을 것입니다. 데이터베이스는 일반적으로 병목 현상이므로 IO를 더 추가하는 것은 일반적으로 나쁜 일입니다. APC 및 Zend와 유사한 기능을 수행하는 몇 가지 PHP 캐시가 있습니다 .
  • 캐싱을 켜고 끈 상태에서 시스템을 측정하십시오. 캐시가 페이지를 똑바로 제공하는 것보다 무겁습니다.
  • db에서 주석 및 기사 데이터를 작성하는 데 시간이 오래 걸리면 memcache 를 시스템에 통합 하십시오. 쿼리 결과를 캐시하여 memcached 인스턴스에 저장할 수 있습니다. memcache에서 데이터를 검색하는 것이 데이터베이스에서 데이터를 조합하는 것보다 빠르다는 점을 기억해야합니다.
  • 기사가 동적이 아니거나 생성 된 후 간단한 동적 변경이있는 경우 디스크에 html 또는 php를 작성하는 것이 좋습니다. 디스크에서 기사를 찾는 index.php 페이지가있을 수 있으며, 있다면 기사를 클라이언트로 스트리밍합니다. 그렇지 않은 경우 기사를 생성하고 디스크에 쓴 다음 클라이언트로 보냅니다. 디스크에서 파일을 삭제하면 페이지가 다시 작성됩니다. 기사에 주석이 추가 된 경우 캐시 된 사본을 삭제하면 주석이 다시 생성됩니다.

10
디스크에 @ 쓰기. index.php를 버리고 Apache가 자동으로 작업하도록 할 수 있으므로 경로가 존재하지 않는 경우 index.php 만 호출됩니다. 이를 위해 mode_rewrite를 사용합니다.
troelskn

5
-1, PDO는 MySQLi 또는 MySQL 확장보다 훨씬 느립니다.
Alix Axel

4
PDO는 mysqli보다 훨씬 느리고 중첩 된 쿼리에서 제대로 작동하지 않았습니다. Mysqli는 PDO와 마찬가지로 서버 측 준비 및 바인딩 된 매개 변수도 지원합니다.
Daren Schwenke

5
나는 이것이 대답으로 받아 들여 졌다는 것을 믿을 수 없다. 그다지 좋지 않습니다.
symcbean

1
about : caching-이미지, CSS, htm 및 js가 이미지의 쿠키를 끄는 데 도움이됩니다!
Talvi Watia 2016 년

61

저는 1 억 5 천만 명의 사용자가있는 사이트의 수석 개발자입니다. 우리는 초기에 계획하고 신중하게 확장했기 때문에 확장 문제가 거의 없었습니다. 다음은 내 경험에서 제안 할 수있는 몇 가지 전략입니다.

SCHEMA 먼저 스키마를 비정규 화하십시오. 즉, 여러 관계형 테이블을 갖는 대신 하나의 큰 테이블을 선택해야합니다. 일반적으로 조인은 여러 준비 및 데이터 정렬을 수행하면 디스크 I / O가 손상되므로 귀중한 DB 리소스가 낭비됩니다. 가능하면 피하십시오.

여기서 중복되는 데이터는 중복 데이터를 저장 / 풀링한다는 것입니다. 그러나 데이터 및 케이지 내부 대역폭이 매우 저렴하고 (더 큰 디스크) 다중 준비 I / O가 훨씬 비싸기 때문에 (서버가 더 많기 때문에) 이는 수용 가능합니다. .

인덱싱 쿼리가 적어도 하나의 인덱스를 사용하는지 확인합니다. 그러나 자주 쓰거나 업데이트하면 색인 비용이 발생합니다. 이를 피하기위한 몇 가지 실험적인 트릭이 있습니다.

인덱싱되지 않은 열을 인덱싱 된 열과 병렬로 추가하여 추가 할 수 있습니다. 그런 다음 인덱싱되지 않은 열을 인덱싱 된 열에 일괄 적으로 쓰는 오프라인 프로세스를 가질 수 있습니다. 이런 식으로 mySQL이 인덱스를 다시 계산해야 할 때 더 잘 제어 할 수 있습니다.

전염병과 같은 계산 쿼리를 피하십시오. 쿼리를 계산해야하는 경우 쓰기시 한 번 수행하십시오.

CACHING 나는 매우 memcached를하는 것이 좋습니다. PHP 스택 (Facebook)에서 가장 큰 플레이어에 의해 입증되었으며 매우 유연합니다. 이를 수행하는 두 가지 방법이 있습니다. 하나는 DB 계층에서 캐싱하고 다른 하나는 비즈니스 로직 계층에서 캐싱입니다.

DB 계층 옵션을 사용하려면 DB에서 검색 한 쿼리 결과를 캐싱해야합니다. md5 ()를 사용하여 SQL 쿼리를 해시하고 데이터베이스로 이동하기 전에이를 조회 키로 사용할 수 있습니다. 이것의 단점은 구현하기가 쉽다는 것입니다. 단점 (구현에 따라 다름)은 캐시 만료와 관련하여 모든 캐싱을 동일하게 취급하기 때문에 유연성이 떨어집니다.

내가 작업하는 상점에서는 비즈니스 계층 캐싱을 사용합니다. 즉, 시스템의 각 콘크리트 클래스가 자체 캐싱 스키마 및 캐시 시간 초과를 제어합니다. 이것은 우리에게는 꽤 효과가 있었지만 DB에서 검색 한 항목은 캐시의 항목과 같지 않을 수 있으므로 캐시와 DB를 함께 업데이트해야합니다.

데이터 보호 복제는 지금까지만 가능합니다. 예상보다 빨리 쓰기 작업에 병목 현상이 발생합니다. 이를 보완하려면 가능한 빨리 데이터 샤딩을 지원해야합니다. 당신이하지 않으면 나중에 자신을 촬영하고 싶을 것입니다.

구현하는 것은 매우 간단합니다. 기본적으로 데이터 저장소에서 키 권한을 분리하려고합니다. 기본 DB와 클러스터 ID 간의 매핑을 저장하려면 글로벌 DB를 사용하십시오. 이 매핑을 쿼리하여 클러스터를 얻은 다음 클러스터를 쿼리하여 데이터를 가져옵니다. 이 조회 작업에서 지옥을 캐시하여 무시할 수있는 작업으로 만들 수 있습니다.

이것의 단점은 여러 샤드의 데이터를 함께 수집하기가 어렵다는 것입니다. 그러나, 당신은 그것의 주위에 길을 엔지니어링 할 수 있습니다.

오프라인 처리 사용자가 백엔드를 기다리지 않아도되도록 기다리지 마십시오. 작업 큐를 작성하고 오프라인으로 처리 할 수있는 모든 처리를 사용자 요청과 별도로 수행하십시오.


9
+1 손을 내밀어, 이것이 정답입니다. 데이터베이스 구축에 관해 읽은 모든 내용이 조인을 수행 할 때의 성능 저하를 언급하지 않고 항상 "모든 데이터를 최대한 많이 정규화"한다고 말합니다. 나는 항상 직관적으로 조인 (특히 다중)이 많은 오버 헤드를 추가했지만 지금까지 명시 적으로 말하는 것을 듣지 못했다고 느꼈습니다. MySQL이 인덱스를 계산할 때 제어하는 ​​것에 대해 더 잘 이해하고 싶습니다. 매우 흥미로운 해킹처럼 들립니다.
Evan Plaice

데이터 샤딩은 너무 커지는 데이터베이스에 필수적입니다. Google (검색 엔진이 아닌 회사)은 샤딩 구성표 구현에 대해 흥미로운 내용을 많이 가지고 있습니다. 데이터베이스 쓰기 수를 제한하고 테이블 인덱스 재 계산 수를 제한 할 때 오프라인 처리도 엄청납니다. 많은 블로그 (그리고 스택 오버 플로우조차도)가 사용자 생성 주석 / 피드백 시스템 에이 기술을 사용하는 것을 보았습니다.
Evan Plaice

1
의견 주셔서 감사합니다. VAST 실행 시간이 데이터 I / O 또는 클라이언트-서버 I / O에 사용될 때 일부 계층이 중간 계층 코드를 프로파일 링한다고 주장하는 것은 놀라운 일입니다. 40ms가 소요되는 PHP 프로세스의 실행 시간을 20 % 절약하는 Ubber 복잡한 최적화는 1s 데이터베이스 쿼리의 단순한 5 % 절약에 비해 의미가 없습니다.
thesmart

42

PHP 및 MySQL의 지원을받는 수백만 / 히트 / 월을 얻는 소수의 사이트에서 일했습니다. 기본 사항은 다음과 같습니다.

  1. 캐시, 캐시, 캐시. 캐싱은 웹 서버 및 데이터베이스의 부하를 줄이는 가장 간단하고 효과적인 방법 중 하나입니다. 캐시 된 페이지 내용, 쿼리, 비싼 계산, I / O 바인딩 된 모든 것. Memcache는 간단하고 효과적입니다.
  2. 최대 한도에 도달하면 여러 서버를 사용하십시오. 여러 웹 서버와 여러 데이터베이스 서버 (복제 포함)를 가질 수 있습니다.
  3. 웹 서버에 대한 전체 요청 수를 줄입니다. 이 경우 Expirs 헤더를 사용하여 JS, CSS 및 이미지를 캐싱해야합니다. 정적 컨텐츠를 CDN으로 이동하여 사용자 경험을 향상시킬 수 있습니다.
  4. 측정 및 벤치 마크. 프로덕션 머신에서 Nagios를 실행하고 dev / qa 서버에서로드 테스트하십시오. 서버가 불을 붙일 때를 알아야이를 방지 할 수 있습니다.

확장 가능한 웹 사이트 구축을 읽는 것이 좋습니다 . Flickr 엔지니어 중 한 사람이 작성했으며 훌륭한 참고 자료입니다.

확장성에 대한 내 블로그 게시물을 확인하십시오. 여러 언어 및 플랫폼으로 확장하는 방법에 대한 프레젠테이션 링크가 많이 있습니다. http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1 여기에는 좋은 정보가 많이 있습니다. 나는 최근에이 주제에 대해 더 많은 연구를 해왔고 당신의 대답은 내가 읽은 모든 것과 일치합니다. 정적 컨텐츠를위한 Memcache, 캐싱, CDN, 요청 감소; 모든 좋은 물건. 또한 정적 컨텐트 파일 (CDN / 캐시 뒤에있는 경우) 서버 측에서 해시를 생성하여 업데이트 된 파일이 캐시에서 고유 한 서명을 갖도록합니다. 또한 정적 소스 파일 (css, javascript)을 즉석에서 결합하고 파일 이름 해시로 캐시하여 요청을 줄입니다. 또한 엄지 손가락을 동적으로 생성하고 캐시에 저장합니다.
Evan Plaice

Google은 모든 정적 콘텐츠에 대해 모든 파일 연결, 축소, 해시를 포함하도록 파일 이름 바꾸기 등을 처리 할 수있는 mod_pagespeed라는 아파치 모듈을 만들었습니다. 캐시 (및 CDN)에 대부분의 내용이 채워질 때까지 서버에 약간의 처리 오버 헤드 만 추가해야합니다. 또한 보안을 위해 백엔드를 처리하는 것보다 테이블과 동일한 데이터베이스에 공개적으로 액세스 가능한 (사용자) 테이블을 배치하는 것이 일반적으로 좋지 않습니다 (어떤 이유로 든 테이블 중 하나가 해킹 된 경우).
Evan Plaice 2019

39

재 : PDO / MySQLi / MySQLND

@ 게리

목표가 다르기 때문에 "MySQLi를 사용하지 마십시오"라고 말할 수는 없습니다. PDO는 추상화 계층과 거의 비슷하지만 실제로는 아니지만 여러 데이터베이스 제품을 쉽게 사용할 수 있도록 설계되었지만 MySQLi는 MySQL 연결에만 적용됩니다. PDO가 MySQLi와 비교하는 맥락에서 PDO가 최신 액세스 계층이라고 말하는 것은 잘못된 일입니다.

MySQLi와 PDO 사이의 선택은 간단합니다. 여러 데이터베이스 제품을 지원해야하는 경우 PDO를 사용하십시오. MySQL 만 사용하는 경우 PDO와 MySQLi 중에서 선택할 수 있습니다.

그렇다면 왜 PDO 대신 MySQLi를 선택하겠습니까? 아래를 참조하십시오 ...

@ 로스

최신 MySQL 핵심 언어 레벨 라이브러리 인 MySQLnd에 대해서는 정확하지만 MySQLi를 대체하지는 않습니다. PDO와 마찬가지로 MySQLi는 PHP 코드를 통해 MySQL과 상호 작용하는 방식으로 남아 있습니다. 이 두 가지 모두 libmysql을 PHP 코드의 C 클라이언트로 사용합니다. 문제는 libmysql이 핵심 PHP 엔진 외부에 있으며 mysqlnd가있는 곳입니다. 즉, 효율성을 극대화하기 위해 핵심 PHP 내부를 사용하는 네이티브 드라이버, 특히 메모리 사용과 관련이 있습니다.

MySQLnd는 MySQL 자체에서 개발하고 있으며 최근에는 RC 테스트중인 PHP 5.3 브랜치에 착륙하여 올해 후반에 출시 될 예정입니다. 그러면 Pnd가 아닌 MySQLi에서 MySQLnd를 사용할 수 있습니다. 이것은 많은 영역에서 MySQLi 의 성능 향상 을 가져다 줄 것이며 PDO의 기능과 같은 추상화가 필요하지 않은 경우 MySQL 상호 작용을위한 최상의 선택이 될 것입니다.

즉, MySQLnd 는 이제 PDO 용 PHP 5.3에서 사용할 수 있으므로 ND에서 PDO로 성능 향상의 이점을 얻을 수 있지만 PDO는 여전히 일반적인 데이터베이스 계층이므로 다음과 같은 이점을 얻을 수 없을 것입니다. MySQLi가 할 수있는 것처럼 ND의 향상된 기능 .

유용한 벤치 마크는 2006 년부터 있지만 여기에서 확인할 수 있습니다 . 이 옵션 과 같은 사항도 알고 있어야 합니다.

MySQLi와 PDO 사이를 결정할 때 고려해야 할 사항이 많이 있습니다. 현실적으로 당신이 엄청나게 많은 요청 수에 도달 할 때까지는 중요하지 않으며,이 경우 사물을 추상화하고 MySQL 드라이버를 제공하는 것보다 MySQL 용으로 특별히 설계된 확장을 사용하는 것이 더 합리적입니다 .

각각의 장점과 단점이 있기 때문에 가장 간단한 문제는 아닙니다. 내가 제공 한 링크를 읽고 자신의 결정을 내린 다음 테스트하고 알아 내야합니다. 나는 과거 프로젝트에서 PDO를 사용했으며 좋은 확장이지만 순수한 성능을 위해 선택하는 것은 새로운 MySQLND 옵션이 컴파일 된 MySQLi입니다 (PHP 5.3이 출시 될 때).


6
PDO에서 mysqli로 전환했으며 일반 쿼리가 정확히 2 배 더 빨리 실행되기 시작했습니다.
serg

5
@serg : PDO에서 mysqli로 간단히 전환하면 속도가 향상 될 것이라는 점을 심각하게 의심하기 때문에이를 확인하기 위해 몇 가지 테스트를 게시해야합니다.
Stann

23

일반

  • 실제 하중을보기 전에 최적화하지 마십시오. 당신은 맞을지 모르지만, 그렇지 않으면 시간을 낭비한 것입니다.
  • 사용 JMeter를 , Xdebug는 또는 벤치 마크에 다른 도구 사이트.
  • 로드가 문제가되기 시작하면 객체 또는 데이터 캐싱이 관련 될 가능성이 있으므로 일반적으로 캐싱 옵션 (memcached, MySQL 캐싱 옵션)을 읽으십시오.

암호

  • 병목 현상의 위치와 코드 또는 데이터베이스에 있는지 여부를 알 수 있도록 코드를 프로파일 링하십시오.

데이터베이스

  • 다른 데이터베이스로의 이식성이 중요하지 않은 경우 MYSQLi를 사용하고 , 그렇지 않으면 PDO
  • 벤치 마크에서 데이터베이스에 문제가있는 것으로 나타나면 캐싱을 시작하기 전에 쿼리를 확인하십시오. EXPLAIN 을 사용 하여 쿼리 속도가 저하되는 위치를 확인하십시오.
  • 쿼리가 최적화되고 데이터베이스가 어떤 식 으로든 캐시 된 후 여러 데이터베이스를 사용할 수 있습니다. 데이터, 쿼리 및 읽기 / 쓰기 동작의 종류에 따라 여러 서버로 복제하거나 샤딩 (여러 데이터베이스 / 서버로 데이터를 분할)이 적절할 수 있습니다.

캐싱

  • 코드, 객체 및 데이터 캐싱에 대한 많은 작성이 이루어졌습니다. APC , Zend Optimizer , memcached , QuickCache 에 관한 기사를 찾아보십시오 , JPCache 찾아보십시오 . 실제로 필요한 작업을 수행하기 전에이 작업을 수행하면 최적화되지 않은 상태에서 시작하는 것에 대해 덜 걱정할 것입니다.
  • APC와 Zend Optimizer는 opcode 캐시이며 코드 재분석 및 재 컴파일을 피하여 PHP 코드 속도를 높입니다. 일반적으로 설치가 간단하고 조기에 가치가 있습니다.
  • Memcached는 일반 캐시로, 쿼리, PHP 함수 또는 객체 또는 전체 페이지를 캐시하는 데 사용할 수 있습니다. 캐시 된 객체의 생성, 업데이트 및 삭제를 처리 할 중앙 지점이없는 경우 관련 프로세스가 될 수있는 코드를 사용하려면 코드를 특별히 작성해야합니다.
  • QuickCache 및 JPCache는 파일 캐시이며, 그렇지 않으면 Memcached와 유사합니다. 기본 개념은 간단하지만 코드가 필요하며 중앙에서 생성, 업데이트 및 삭제 지점이 있으면 더 쉽습니다.

여러 가지 잡다한

  • 부하가 큰 대체 웹 서버를 고려하십시오. lighthttpnginx 와 같은 서버는 Apache의 성능과 유연성을 희생 할 수있는 경우 (또는 종종 필요하지 않은 경우), Apache 보다 훨씬 적은 메모리에서 많은 양의 트래픽을 처리 할 수 있습니다.
  • 요즘 하드웨어는 놀라 울 정도로 저렴하다는 점을 명심하십시오. "몬스터 서버를 구입"하는 것보다 큰 코드 블록을 최적화하는 데 드는 비용이 들지 않도록하십시오.
  • 이 질문에 "MySQL"및 "scaling"태그를 추가하십시오

9

APC 는 절대적으로 필요합니다. 그것은 훌륭한 캐싱 시스템을 만들뿐만 아니라 자동 캐시 된 PHP 파일의 이점은 신의 선물입니다. 다중 데이터베이스 아이디어에 관해서는 동일한 서버에서 다른 데이터베이스를 사용하는 데 많은 도움이 될 것이라고 생각하지 않습니다. 쿼리 시간 동안 약간의 속도 향상을 가져올 수 있지만, 세 가지 코드를 모두 배포하고 유지하면서 코드를 동기화하고 유지하는 것이 가치가 있다고 생각합니다.

또한 프로그램에서 병목 현상을 찾기 위해 Xdebug 를 실행하는 것이 좋습니다 . 그것은 나를 위해 최적화를 산들 바람으로 만들었습니다.


9

먼저 Knuth가 말한 것처럼 "조기 최적화는 모든 악의 근원"입니다. 지금 당장 이러한 문제를 처리 할 필요가 없다면, 올바르게 작동하지 않는 것을 제공하는 데 집중하십시오. 최적화가 기다릴 수 없다면 말입니다.

데이터베이스 쿼리를 프로파일 링하고 느리게 진행되는 작업과 발생하는 작업을 파악한 후 그로부터 최적화 전략을 수립하십시오.

Memcached 는 모든 유형의 컨텐츠를 효율적으로 캐싱하기 위해 많은 고부하 사이트가 사용하는 것으로 Memcached 를 조사 할 것이며 이에 대한 PHP 객체 인터페이스는 매우 좋습니다.

서버간에 데이터베이스를 분할하고 일종의로드 밸런싱 기술을 사용하는 경우 (예 : 필요한 데이터로 중복 데이터베이스 1 개와 # 개 사이의 임의의 숫자 생성-이 숫자를 사용하여 연결할 데이터베이스 서버 결정)는 훌륭한 방법입니다. 능률.

이것들은 과거에 상당히 높은로드 사이트에 대해 잘 작동했습니다. 희망이 당신이 시작하는 데 도움이되기를 바랍니다 :-)


1
RequiredFullQuote는 "우리는 작은 효율성에 대해 잊지 시간의 97 %에 대해 말해야한다 : 조기 최적화는 모든 악의 뿌리입니다"
알리 스터 Bulman

RequiredReallyFullQuote : "프로그래머는 프로그램의 중요하지 않은 부분의 속도에 대해 생각하거나 걱정하는 데 많은 시간을 낭비하며, 이러한 효율성에 대한 시도는 실제로 디버깅 및 유지 관리를 고려할 때 강력한 부정적인 영향을 미칩니다. 우리는 작은 효율성을 잊어야합니다. 시간의 약 97 %를 말합니다. 조기 최적화는 모든 악의 근원입니다. 그러나 우리는 그 중요한 3 %의 기회를 포기해서는 안됩니다. "
cHao

6

Xdebug와 같은 것으로 프로파일을 프로파일 링하는 것 (tj9991 권장)이 반드시 필요합니다. 맹목적으로 최적화하는 것만으로도 이해가되지 않습니다. Xdebug를 사용하면 코드에서 실제 병목 현상을 찾아 최적화 시간을 현명하게 사용하고 실제로 속도 저하를 일으키는 코드 덩어리를 수정할 수 있습니다.

Apache를 사용하는 경우 테스트에 도움이되는 다른 유틸리티는 Siege 입니다. 서버와 응용 프로그램이 실제로 속도를 조절하여 고부하에 어떻게 반응하는지 예상하는 데 도움이됩니다.

PHP에 대한 모든 종류의 opcode 캐시 (APC 또는 다른 많은 것 중 하나)도 많은 도움이 될 것입니다.


6

한 달에 7-8 백만 페이지 뷰의 웹 사이트를 운영합니다. 별로 많지는 않지만 서버가 부하를 느꼈을 정도로 충분합니다. 우리가 선택한 솔루션은 간단했습니다 : 데이터베이스 수준의 Memcache. 이 솔루션은 데이터베이스로드가 주요 문제인 경우 잘 작동합니다.

Memcache를 사용하여 전체 개체와 가장 자주 사용 된 데이터베이스 결과를 캐시하기 시작했습니다. 그것은 효과가 있었지만 버그를 도입했습니다 (더 조심 스러우면 버그를 피했을 수도 있습니다).

그래서 우리는 접근 방식을 바꿨습니다. 우리는 데이터베이스 래퍼 (이전 데이터베이스와 똑같은 방법을 사용하여 전환하기 쉬움)를 구축 한 다음, 서브 클래 싱하여 memcached 데이터베이스 액세스 방법을 제공했습니다.

이제 쿼리가 캐시 된 (그리고 오래된) 결과를 사용할 수 있는지 여부를 결정하기 만하면됩니다. 사용자가 실행 한 대부분의 쿼리는 이제 Memcache에서 직접 가져옵니다. 업데이트 및 삽입은 예외이며 기본 웹 사이트에서는 로깅으로 인해 발생합니다. 이 간단한 측정으로 서버로드가 약 80 % 감소했습니다.


6

가치있는 것은 memcached와 같은 확장 / 헬퍼 패키지가 없어도 캐싱은 PHP에서 DIRT SIMPLE입니다.

다음을 사용하여 출력 버퍼를 생성하기 만하면됩니다. ob_start() .

글로벌 캐시 기능을 작성하십시오. 요구ob_start , 함수를 콜백으로 전달하십시오. 함수에서 페이지의 캐시 된 버전을 찾으십시오. 존재하는 경우 제공하고 종료하십시오.

존재하지 않으면 스크립트는 계속 처리합니다. 일치하는 ob_end ()에 도달하면 지정한 함수를 호출합니다. 이때 출력 버퍼의 내용을 가져 와서 파일에 놓아 파일을 저장 한 후 종료하면됩니다.

일부 만기 / 가비지 콜렉션에 추가하십시오.

그리고 많은 사람들이 당신이 중첩 ob_start()/ ob_end()전화를 할 수 있다는 것을 깨닫지 못합니다 . 따라서 이미 광고를 구문 분석하거나 구문 강조 표시 등을 수행하기 위해 출력 버퍼를 사용하고 있다면 다른 ob_start/ob_end호출을 중첩시킬 수 있습니다 .


흥미로운 아이디어처럼 보이기 때문에 +1입니다. 나는 그것이 성능 현명한 얼마나 잘 작동하는지 모르겠어요
Sylverdrag

흥미로운 아이디어이기 때문에 +1입니다. 이 콜백은 캐싱 클래스를 호출 할 수 있습니다!
Xeoncross 2009

5

PHP의 캐싱 확장에 대한 조언에 감사드립니다. 서로를 사용하는 이유를 설명해 주시겠습니까? IRC를 통해 memcached에 대해 큰 이야기를 들었지만 APC에 대해 들어 본 적이 없습니다. 귀하의 의견은 무엇입니까? 여러 캐싱 시스템을 사용하는 것이 상당히 효과적이라고 가정합니다.

실제로 많은 사람들이 APC와 memcached를 함께 사용합니다 ...


4

내가 잘못한 것 같습니다 . MySQLi는 여전히 개발 중입니다. 그러나 기사에 따르면 PDO_MySQL은 이제 MySQL 팀이 기여하고 있습니다. 기사에서 :

MySQL Enhanced Extension (mysqli)이 주력 제품입니다. Charsets, Prepared Statements 및 Stored Procedures를 포함하여 MySQL 서버의 모든 기능을 지원합니다. 드라이버는 하이브리드 API를 제공합니다. 선호도에 따라 절차 또는 객체 지향 프로그래밍 스타일을 사용할 수 있습니다. mysqli는 PHP 5 이상과 함께 제공됩니다. PHP 4의 수명은 2008-08-08입니다.

PDO (PHP Data Objects)는 데이터베이스 액세스 추상화 계층입니다. PDO를 사용하면 다양한 데이터베이스에 대해 동일한 API 호출을 사용할 수 있습니다. PDO는 어느 정도의 SQL 추상화를 제공하지 않습니다. PDO_MYSQL은 PDO 용 MySQL 드라이버입니다. PDO_MYSQL은 PHP 5와 함께 제공됩니다. PHP 5.3부터 MySQL 개발자들이 적극적으로 기여합니다. 통합 API의 PDO 이점은 MySQL 고유 기능 (예 : 여러 명령문)이 통합 API를 통해 완전히 지원되지 않는 가격에 제공됩니다.

ext / mysql과 같이 공개 된 PHP 용 MySQL 드라이버 사용을 중단하십시오. 2004 년에 PHP 5가 포함 된 MySQL Enhanced Extension (mysqli)이 도입 된 이후로 가장 오래된 드라이버를 계속 사용할 이유가 없습니다. ext / mysql은 Charsets, Prepared Statements 및 Stored Procedures를 지원하지 않습니다. MySQL 4.0의 기능 세트로 제한됩니다. MySQL 4.0에 대한 확장 지원은 2008-12-31에 종료됩니다. 이러한 오래된 소프트웨어의 기능 세트로 자신을 제한하지 마십시오! mysqli로 업그레이드하십시오. Converting_to_MySQLi도 참조하십시오. mysql은 우리의 관점에서 유지 관리 전용 모드입니다.

나 에게이 기사는 MySQLi에 편향되어있는 것 같습니다. PDO에 편향되어 있다고 가정합니다. 저는 MySQLi보다 PDO를 정말 좋아합니다. 그것은 나에게 똑바르다. API는 내가 프로그래밍 한 다른 언어에 훨씬 가깝습니다. OO 데이터베이스 인터페이스가 더 잘 작동하는 것 같습니다.

PDO를 통해 사용할 수 없었던 특정 MySQL 기능을 보지 못했습니다. 내가 한 적이 있다면 놀랐을 것입니다.


3

PDO도 매우 느리고 API는 매우 복잡합니다. 이식성이 문제가되지 않으면 제정신의 마음으로 아무도 그것을 사용해서는 안됩니다. 그리고 모든 웹 애플리케이션의 99 %에서 그렇지 않습니다. 당신은 MySQL이나 PostrgreSQL, 또는 당신이 사용하는 모든 것을 고수합니다.

PHP 질문과 고려해야 할 사항에 관해서. 나는 조기 최적화가 모든 악의 근원이라고 생각합니다. ;) 응용 프로그램을 먼저 완료하고 프로그래밍과 관련하여 깨끗하게 유지하고 약간의 문서를 작성하고 단위 테스트를 작성하십시오. 위의 모든 시간이 올 때 코드를 리팩토링하는 데 문제가 없습니다. 그러나 먼저 당신은 사람들이 그것에 어떻게 반응하는지보기 위해 그것을 끝내고 싶어합니다.


2

물론 PDO는 좋은,하지만 거기에 있다 하고 일부 가 수정되었습니다 것 같다 있지만, MySQL과 mysqli 대 그것의 성능에 대한 논란.

이식성을 고려한다면 pdo를 사용해야하지만, 그렇지 않으면 mysqli가 좋은 방법입니다. OO 인터페이스, 준비된 명령문 및 pdo가 제공하는 대부분의 기능 (휴대 성을 제외하고)이 있습니다.

또한 성능이 실제로 필요한 경우 PHP 5.3 의 (기본 mysql) MysqLnd 드라이버를 준비하십시오. PHP 5.3은 성능이 향상되고 메모리 사용량이 향상되고 성능 조정에 대한 통계와 함께 PHP와 훨씬 더 긴밀하게 통합됩니다.

Memcache는 클러스터 된 서버 (및 YouTube와 같은로드)가 있으면 좋지만 APC도 먼저 시도해보십시오 .


2

많은 좋은 답변이 이미 제공되었지만 XCache 라는 대체 opcode 캐시를 알려 드리겠습니다. . 가벼운 기여자에 의해 만들어졌습니다.

또한 향후 데이터베이스 서버의로드 밸런싱이 필요할 경우 MySQL 프록시 가이를 달성하는 데 도움이 될 것입니다.

이러한 도구는 모두 기존 응용 프로그램에 매우 쉽게 연결되므로 너무 번거 로움없이 필요할 때이 최적화를 수행 할 수 있습니다.


2

첫 번째 질문은 당신이 얼마나 크게 기대 하느냐입니다. 인프라에 대한 투자 계획은 얼마입니까? 여기에서 질문 할 필요가 있다고 생각하기 때문에 제한된 예산으로 소규모로 시작할 것으로 예상됩니다.

사이트를 사용할 수없는 경우 성능이 관련이 없습니다. 그리고 가용성을 위해서는 수평 확장이 필요합니다. 현명하게 벗어날 수있는 최소값은 아파치, PHP 및 mysql을 실행하는 2 대의 서버입니다. 한 DBMS를 다른 DBMS의 슬레이브로 설정하십시오. 어떤 이유로 든 방금 읽은 데이터를 다시 읽을 필요가 없으면 (마스터 사용) 마스터에 대한 모든 쓰기와 로컬 데이터베이스에 대한 모든 읽기를 수행하십시오. 슬레이브를 자동으로 승격시키고 마스터를 차단할 수있는 기계가 있는지 확인하십시오. 웹 서버 주소에 라운드 로빈 DNS를 사용하여 슬레이브 노드에 더 많은 선호도를 제공하십시오.

이 단계에서 다른 데이터베이스 노드로 데이터를 분할하는 것은 매우 나쁜 생각입니다. 그러나 동일한 서버의 다른 데이터베이스로 데이터를 분할하는 것을 고려할 수 있습니다 (페이스 북을 추월 할 때 노드 간 분할을 용이하게 함).

사이트 성능을 측정하고 병목 현상을 식별 할 수있는 모니터링 및 데이터 분석 도구가 있는지 확인하십시오. 더 나은 SQL을 작성하거나 데이터베이스 스키마를 수정하면 대부분의 성능 문제를 해결할 수 있습니다.

데이터베이스에 템플릿 캐시를 유지하는 것은 멍청한 생각입니다. 데이터베이스는 구조화 된 데이터를위한 중앙 공통 리포지토리 여야합니다. 템플릿 캐시를 웹 서버의 로컬 파일 시스템에 보관하십시오. 더 빠르게 사용할 수 있으며 데이터베이스 액세스 속도가 느려지지 않습니다.

op 코드 캐시를 사용하십시오.

사이트와 로그를 연구하는 데 많은 시간을 할애하여 왜 느리게 진행되는지 이해하십시오.

가능한 한 많은 캐싱을 클라이언트에 푸시하십시오.

mod_gzip을 사용하여 가능한 모든 것을 압축하십시오.

씨.


2

내 첫 번째 조언은 사이트를 디자인 할 때이 문제에 대해 생각하고 염두에 두어야하지만 배 밖으로 가지 않는 것입니다. 입니다. 종종 새로운 사이트의 성공을 예측하기가 어려우므로 시간을 일찍 끝내고 나중에 최적화하는 데 시간을 보내는 것이 좋습니다.

일반적으로 Simple은 빠릅니다 . 템플릿 속도가 느려집니다. 데이터베이스 속도가 느려집니다. 복잡한 라이브러리는 속도를 늦 춥니 다. 템플릿을 서로 겹쳐서 데이터베이스에서 가져 와서 복잡한 라이브러리에서 구문 분석-> 시간 지연이 서로 곱해집니다.

기본 사이트를 설치하고 실행 한 후에 는 테스트 를 통해 어디에서 노력을 기울여야하는지 보여줍니다. 타겟팅 할 위치를 찾기가 어렵습니다. 작업 속도를 높이기 위해 코드의 복잡성을 풀어야하기 때문에 코드를 유지 관리하기가 더 크고 어렵 기 때문에 필요한 경우에만 수행하기를 원합니다.

내 경험상 데이터베이스 연결을 설정하는 것은 상대적으로 비쌌습니다. 이를 피할 수 있다면 첫 페이지와 같이 트래픽이 가장 많은 페이지의 일반 방문자를 위해 데이터베이스에 연결하지 마십시오. 여러 데이터베이스 연결을 만드는 것은 별다른 이점이없는 광기입니다.


1

@ 게리

MySQLi를 사용하지 마십시오-PDO는 '현대'OO 데이터베이스 액세스 계층입니다. 가장 중요한 기능은 쿼리에서 자리 표시 자입니다. 서버 측 준비 및 기타 최적화 기능을 사용하는 것이 현명합니다.

나는 현재 PDO를 찾고 있는데 그것이 옳은 것처럼 보입니다. 그러나 MySQL이 PHP 용 MySQLd 확장을 개발하고 있음을 알고 있습니다-MySQL 또는 MySQLi 중 하나를 성공할 것이라고 생각합니다. 어떻게 생각하십니까?


@ 라이언 , 에릭 , tj9991

PHP의 캐싱 확장에 대한 조언에 감사드립니다. 서로를 사용하는 이유를 설명해 주시겠습니까? IRC를 통해 memcached에 대해 큰 이야기를 들었지만 APC에 대해 들어 본 적이 없습니다. 귀하의 의견은 무엇입니까? 여러 캐싱 시스템을 사용하는 것이 상당히 효과적이라고 가정합니다.

필자는 프로파일 링 테스터를 확실히 분류 할 것입니다-권장 사항에 대해 대단히 감사합니다.


1

곧 MySQL에서 전환하는 것을 보지 못하므로 PDO의 추상화 기능이 필요하지 않은 것 같습니다. 그 기사 DavidM에 감사드립니다. 그들은 많은 도움을주었습니다.


1

ASP.NET의 출력 캐싱과 비슷한 Apache 웹 서버의 출력 캐시 인 mod_cache를 살펴보십시오 .

예, 여전히 실험적이지만 언젠가는 최종적인 것으로 보입니다.


1

나는 아무도 이것을 이미 언급하지 않았다고 믿을 수 없다 : 모듈화와 추상화. 사이트가 많은 기계로 확장되어야한다고 생각한다면 가능한 한 많이 설계 해야합니다 ! 그것은 데이터베이스가 localhost에 있다고 가정하지 않는 것과 같은 어리석은 것을 의미합니다. 또한 PDO와 같은 데이터베이스 추상화 계층을 작성하는 것과 같이 처음에는 귀찮게 될 일을 의미하지만 필요한 작업 만 수행하기 때문에 훨씬 가볍습니다.

그리고 이는 프레임 워크 작업과 같은 것을 의미합니다. 예를 들어, 일부 객체가 다른 데이터베이스에 있고 코드가 알 필요가 없다고 가르치는 등 데이터 축소 레이어를 리팩토링하여 나중에 성능을 얻을 수 있도록 코드에 레이어가 필요합니다 .

마지막으로 불필요한 문자열 복사와 같이 메모리를 많이 사용하는 작업에주의하십시오. PHP의 메모리 사용을 줄이면 웹 서버에서 더 많은 성능을 얻을 수 있으며 이는로드 밸런싱 솔루션으로 갈 때 확장 될 수 있습니다.


1

많은 양의 데이터로 작업하고 있고 캐싱으로 인해 데이터가 잘리지 않으면 Sphinx를 살펴보십시오. 우리는 더 나은 텍스트 검색뿐만 아니라 더 큰 테이블을 다룰 때 MySQL의 데이터 검색 대체 기능으로 SphinxSearch를 사용하여 훌륭한 결과를 얻었습니다. SphinxSE (MySQL 플러그인)를 사용하는 경우 여러 번 캐싱하여 얻은 성능 향상을 능가했으며 응용 프로그램 구현은 거의 끝났습니다.


1

캐시에 관한 사항은 현장에 있습니다. 효율적인 애플리케이션을 구축하는 데있어 가장 복잡하고 가장 중요한 부분입니다. memcached는 훌륭하지만 응용 프로그램이 단일 서버에 있으면 APC는 약 5 배 빠릅니다.

MySQL 성능 블로그의 "Cache Performance Comparison"게시물에는 http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ 주제에 대한 흥미로운 벤치 마크가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.