>  기사  >  운영 및 유지보수  >  웹사이트 시스템 캐싱 메커니즘 구축 및 최적화

웹사이트 시스템 캐싱 메커니즘 구축 및 최적화

藏色散人
藏色散人앞으로
2019-04-13 17:24:313684검색

웹 시스템의 외부 네트워크 환경에 대해 이야기한 후 이제 웹 시스템 자체의 성능 문제에 초점을 맞추기 시작합니다.

웹 사이트 방문 수가 증가함에 따라 이러한 문제를 해결하는 것은 시스템을 확장하는 것만큼 간단하지 않지만 적절한 캐싱 메커니즘을 설정하고 사용하는 것이 기본입니다.

처음에는 웹 시스템 아키텍처가 다음과 같을 수 있습니다. 각 링크에는 시스템이 하나만 있을 수 있습니다.

웹사이트 시스템 캐싱 메커니즘 구축 및 최적화

1. MySQL 데이터베이스 내부 캐시는

MySQL의 캐싱 메커니즘을 사용합니다. 다음 내용은 가장 일반적인 InnoDB 스토리지 엔진에 중점을 둡니다.

1. 적절한 인덱스 생성

가장 간단한 방법은 인덱스를 생성하는 것입니다. 테이블 데이터가 상대적으로 클 경우 인덱스는 데이터를 빠르게 검색하는 역할을 하지만 비용도 발생합니다. 우선, 일정량의 디스크 공간을 차지하며, 그 중에서 가장 눈에 띄는 것은 결합된 인덱스이므로 주의해서 사용해야 합니다. 둘째, 인덱스 생성 후 데이터 삽입/업데이트/삭제 등의 작업은 원본 인덱스를 업데이트해야 하기 때문에 시간이 더 걸립니다. 물론 실제로 우리 시스템 전체는 선택 쿼리 작업에 의해 지배됩니다. 따라서 인덱스를 사용하면 시스템 성능이 크게 향상될 수 있습니다.

2. 데이터베이스 연결 스레드 풀 캐시

모든 데이터베이스 작업 요청이 연결을 생성하고 삭제해야 한다면 이는 의심할 여지 없이 데이터베이스에 엄청난 오버헤드가 됩니다. 이러한 유형의 오버헤드를 줄이기 위해 MySQL에서 thread_cache_size를 구성하여 재사용을 위해 예약된 스레드 수를 나타낼 수 있습니다. 스레드가 부족하면 다시 생성되고, 유휴 스레드가 너무 많으면 소멸됩니다.

실제로 pconnect(데이터베이스 긴 연결)를 사용하는 좀 더 급진적인 접근 방식이 있는데, 한 번 스레드가 생성되면 오랫동안 유지됩니다. 그러나 접속량이 상대적으로 많고 머신 수가 많은 경우에는 연결이 설정되고 재활용되지 않아 결국 max_connections(최대 연결 수)에 도달하므로 "데이터베이스 연결 수가 소진되었습니다"로 이어질 가능성이 높습니다. 연결). 따라서 긴 연결을 사용하려면 일반적으로 CGI 시스템에 의해 "맹목적으로" 생성된 연결 수를 제어하기 위해 CGI와 MySQL 사이에 "연결 풀" 서비스를 구현해야 합니다.

3. Innodb 캐시 설정(innodb_buffer_pool_size)

innodb_buffer_pool_size 머신이 MySQL 전용이라면 일반적으로 머신의 물리적 메모리의 80%를 권장합니다. 테이블 데이터를 가져오는 시나리오에서는 디스크 IO를 줄일 수 있습니다. 일반적으로 이 값을 크게 설정할수록 캐시 적중률이 높아집니다.

4. 하위 라이브러리/테이블/파티션.

MySQL 데이터베이스 테이블은 일반적으로 수백만 개의 데이터 볼륨을 견딜 수 있습니다. 더 증가하면 다양한 성능이 크게 저하되므로 데이터 볼륨이 이 수준을 초과할 것으로 예상되는 경우 테이블/파티션을 수행하는 것이 좋습니다. 및 기타 작업. 가장 좋은 접근 방식은 처음부터 서비스를 하위 데이터베이스, 하위 테이블 스토리지 모델로 설계하여 중후반 단계에서 위험을 근본적으로 제거하는 것입니다. 그러나 목록 기반 쿼리와 같은 일부 편의성이 희생되고 동시에 유지 관리 복잡성이 증가합니다. 그러나 데이터의 양이 수천만 개 이상에 도달하면 모두 그만한 가치가 있음을 알게 될 것입니다.

2. 여러 MySQL 데이터베이스 서비스 설정

한 대의 MySQL 머신은 실제로 연결이 끊어지면 웹 서비스를 사용할 수 없기 때문에 위험도가 높은 단일 지점입니다. 게다가 웹 시스템에 대한 방문 횟수가 계속 증가함에 따라 어느 날 MySQL 서버 한 대가 이를 지원할 수 없다는 사실을 알게 되었고 더 많은 MySQL 머신을 사용해야 하기 시작했습니다. 여러 MySQL 머신이 도입되면 많은 새로운 문제가 발생합니다.

1. 슬레이브 데이터베이스를 백업으로 사용하여 MySQL 마스터-슬레이브를 설정합니다.

이 접근 방식은 순전히 마스터 데이터베이스가 실패할 경우 슬레이브 데이터베이스로 전환하는 문제를 해결하기 위한 것입니다. 그러나 슬레이브 라이브러리가 실제로 유휴 상태이기 때문에 이 접근 방식은 실제로 약간의 리소스 낭비입니다.

웹사이트 시스템 캐싱 메커니즘 구축 및 최적화

2. MySQL은 읽기와 쓰기, 기본 데이터베이스에 쓰기 및 슬레이브 데이터베이스에서 읽기를 분리합니다.

두 개의 데이터베이스는 읽기와 쓰기를 분리합니다. 메인 라이브러리는 쓰기 수업을 담당하고, 슬레이브 라이브러리는 읽기 작업을 담당합니다. 또한, 메인 데이터베이스에 장애가 발생하더라도 읽기 작업은 영향을 받지 않습니다. 동시에 모든 읽기 및 쓰기는 일시적으로 슬레이브 데이터베이스로 전환될 수 있습니다. (트래픽이 너무 클 수 있으므로 트래픽에 주의해야 합니다.) 슬레이브 데이터베이스는 다운됩니다.)

웹사이트 시스템 캐싱 메커니즘 구축 및 최적화

3. 스승과 스승은 서로를 위해 준비합니다.

두 개의 MySQL 서버는 서로의 슬레이브 데이터베이스이자 동시에 마스터 데이터베이스입니다. 이 솔루션은 트래픽 압박을 완화할 뿐만 아니라 "단일 장애 지점" 문제도 해결합니다. 특정 장치에 오류가 발생하면 다른 서비스 세트를 사용할 수 있습니다.

그러나 이 솔루션은 컴퓨터가 두 대인 시나리오에서만 사용할 수 있습니다. 사업이 여전히 빠르게 확장되고 있는 경우 사업을 분리하여 여러 개의 마스터-마스터 및 상호 백업 서비스를 구축하는 것을 선택할 수 있습니다.

웹사이트 시스템 캐싱 메커니즘 구축 및 최적화

3. 웹 서버와 데이터베이스 간 캐시 구축

사실 대규모 방문 문제를 해결하려면 데이터베이스 수준에만 집중할 수는 없습니다. "80/20 규칙"에 따르면 요청의 80%는 핫 데이터의 20%에만 집중됩니다. 따라서 웹 서버와 데이터베이스 사이에 캐싱 메커니즘을 구축해야 합니다. 이 메커니즘은 디스크를 캐시 또는 메모리 캐시로 사용할 수 있습니다. 이를 통해 대부분의 핫 데이터 쿼리가 데이터베이스 앞에서 차단됩니다.

1. 페이지 정적화

사용자가 웹사이트의 특정 페이지를 방문하면 해당 페이지의 대부분의 내용이 오랫동안 변경되지 않을 수 있습니다. 예를 들어, 뉴스 보도는 일단 게시되면 거의 수정되지 않습니다. 이 경우 CGI에 의해 생성된 정적 HTML 페이지는 웹 서버 디스크에 로컬로 캐시됩니다. 동적 CGI 쿼리 데이터베이스를 통해 얻은 첫 번째 시간을 제외하고 이후에는 로컬 디스크 파일이 사용자에게 직접 반환됩니다.

웹 시스템의 규모가 상대적으로 작았을 때는 이 접근 방식이 완벽해 보였습니다. 그러나 일단 웹 시스템의 규모가 커지면, 예를 들어 웹 서버가 100개가 되면요. 이런 식으로 이러한 디스크 파일의 복사본이 100개 있게 되는데, 이는 리소스를 낭비하고 유지 관리가 어렵습니다. 이때, 서버를 중앙집중화해서 저장할 수 있다고 생각하시는 분들도 계시는데요. ㅎㅎ, 어떻게 그렇게 하는지 다음의 캐싱 방식을 살펴보시면 어떨까요.

2. 단일 메모리 캐시

페이지 정적화의 예를 통해 웹 시스템에 "캐시"를 구축하는 것이 유지 관리가 어렵고 더 많은 문제를 야기한다는 것을 알 수 있습니다(실제로 PHP apc 확장을 통해 키/값을 통해 웹 서버의 로컬 메모리). 따라서 우리가 구축하기로 선택한 메모리 캐시 서비스도 독립적인 서비스여야 합니다.

메모리 캐시의 주요 선택은 redis/memcache입니다. 성능면에서는 둘 사이에 큰 차이가 없습니다. 기능이 풍부하다는 점에서는 Redis가 더 뛰어납니다.

3. 메모리 캐시 클러스터

단일 메모리 캐시를 구축하면 단일 실패 지점 문제에 직면하게 되므로 이를 클러스터로 전환해야 합니다. 간단한 방법은 슬레이브를 백업 머신으로 추가하는 것입니다. 그러나 실제로 요청이 많고 캐시 적중률이 높지 않고 더 많은 시스템 메모리가 필요한 경우 어떻게 해야 합니까? 따라서 클러스터로 구성하는 것이 좋습니다. 예를 들어 Redis 클러스터와 유사합니다.

Redis 클러스터의 Redis는 서로에 대한 여러 세트의 마스터와 슬레이브입니다. 동시에 각 노드는 요청을 수락할 수 있으므로 클러스터를 확장할 때 더 편리합니다. 클라이언트는 모든 노드에 요청을 보낼 수 있으며, 그것이 "책임" 있는 콘텐츠인 경우 해당 콘텐츠가 직접 반환됩니다. 그렇지 않은 경우 실제 담당 Redis 노드를 찾은 다음 클라이언트에 주소를 알리면 클라이언트가 다시 요청합니다.

이 모든 것은 캐싱 서비스를 사용하는 클라이언트에게 투명합니다.

메모리 캐시 서비스 전환 시 특정 위험이 있습니다. 클러스터 A에서 클러스터 B로 전환하는 과정에서 클러스터 B가 미리 "워밍업"되었는지 확인해야 합니다(클러스터 B 메모리의 핫 데이터는 가능한 한 클러스터 A의 핫 데이터와 동일해야 함). 그렇지 않으면 전환 순간에 대량의 콘텐츠 요청이 요청됩니다. 클러스터 B의 메모리 캐시에서는 찾을 수 없습니다. 트래픽은 백엔드 데이터베이스 서비스에 직접적인 영향을 미치므로 데이터베이스 다운타임이 발생할 수 있습니다.

4. 데이터베이스 "쓰기" 감소

위의 메커니즘은 모두 데이터베이스 "읽기" 작업의 감소를 달성하지만 쓰기 작업도 큰 부담입니다. 쓰기 작업을 줄일 수는 없지만 요청을 병합하면 부담을 줄일 수 있습니다. 이때 메모리 캐시 클러스터와 데이터베이스 클러스터 간에 수정 동기화 메커니즘을 구축해야 합니다.

먼저 외부 쿼리가 정상적으로 표시될 수 있도록 수정 요청을 캐시에 적용한 다음, 이러한 SQL 수정 사항을 대기열에 넣고 대기열이 가득 차거나 가끔씩 병합됩니다. 하나의 요청이 데이터베이스를 업데이트하기 위해 데이터베이스로 전송됩니다.

위에서 언급한 시스템 아키텍처를 변경하여 쓰기 성능을 향상시키는 것 외에도 MySQL 자체에서는 innodb_flush_log_at_trx_commit 매개변수를 구성하여 디스크에 대한 쓰기 전략을 조정할 수도 있습니다. 시스템 비용이 허락한다면 하드웨어 수준에서 문제를 해결하기 위해 이전 RAID(독립 디스크의 중복 배열, 디스크 어레이) 또는 최신 SSD(솔리드 스테이트 드라이브, 솔리드 스테이트 드라이브)를 선택할 수 있습니다.

5. NoSQL 스토리지

데이터베이스 읽기나 쓰기에 관계없이 트래픽이 더 증가하면 결국 "인력이 제한되는 경우" 시나리오에 도달하게 됩니다. 더 많은 기계를 추가하는 데 드는 비용은 상대적으로 높으며 실제로 문제를 해결하지 못할 수도 있습니다. 이때 일부 핵심 데이터에 대해서는 NoSQL 데이터베이스 사용을 고려할 수 있습니다. 대부분의 NoSQL 스토리지는 위에서 소개한 것처럼 Redis를 사용하는 것이 좋습니다. Redis 자체가 메모리 캐시이므로 디스크에 직접 데이터를 저장할 수도 있습니다.

이 경우 데이터베이스에서 자주 읽고 쓰는 데이터를 분리하여 새로 구축한 Redis 스토리지 클러스터에 배치합니다. 그러면 동시에 원본 MySQL 데이터베이스에 대한 부담이 더욱 줄어듭니다. 메모리 수준 캐시를 사용하면 읽기 및 쓰기 성능이 크게 향상됩니다.

국내 1위 인터넷 기업들은 아키텍처 측면에서 위 솔루션과 유사한 솔루션을 많이 사용하고 있지만, 사용하는 캐시 서비스가 반드시 Redis인 것은 아니며, 자체 비즈니스 특성에 따라 자체적으로 개발할 수도 있습니다. .NoSQL 서비스.

6. 빈 노드 쿼리 문제

위에서 언급한 모든 서비스를 구축하고 웹 시스템이 이미 매우 강력하다고 생각하면. 우리는 여전히 똑같은 말을 하지만, 여전히 새로운 문제가 올 것입니다. 빈 노드 쿼리는 데이터베이스에 전혀 존재하지 않는 데이터 요청을 나타냅니다. 예를 들어 내가 존재하지 않는 사람의 정보에 대해 질의를 요청하면 시스템은 단계별로 모든 수준의 캐시에서 검색을 하고, 최종적으로 데이터베이스 자체를 찾은 다음, 찾을 수 없다는 결론을 내려 돌려준다. 프런트엔드에. 모든 수준의 캐시가 유효하지 않기 때문에 이 요청은 많은 시스템 리소스를 소비하며, 빈 노드 쿼리가 많이 발생하면 시스템 서비스에 영향을 미칠 수 있습니다.

위 내용은 웹사이트 시스템 캐싱 메커니즘 구축 및 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 hcoder.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제