여기에서는 캐시 서버의 설계 및 관련 세부 사항을 논의하기 위한 단서로 nginx 캐시 시스템을 사용합니다. 공간적 제약으로 인해 코드에 대해서는 다루지 않겠습니다. 여기에서 관련 내용을 함께 토론에 참여해 보세요.
캐시 서버가 백엔드에서 파일을 얻은 후 클라이언트로 직접 전송되거나(학명은 투명 전송), 후속 동일한 요청이 캐시 서버에 액세스하면 로컬 파일이 로컬로 캐시됩니다. 가능한 경우 사본을 직접 얻을 수 있습니다. 후속 요청에서 로컬로 캐시된 파일에 액세스하는 경우 이를 캐시 적중이라고 합니다. 로컬에 파일의 캐시 복사본이 없는 경우 캐시 서버는 구성에 따라 파일을 가져오거나 도메인 이름을 확인하기 위해 백엔드로 이동해야 합니다. 이를 캐시 미스, 즉 미스라고 합니다. 캐시 서버에 대한 더 많은 지식을 위해 nginx 캐시 시스템을 분석할 때 심도있게 논의하겠습니다.
nginx의 저장 시스템은 두 가지로 나뉘는데, 하나는 Proxy_store를 통해 오픈하며, 저장 방법은 URL에 있는 파일 경로에 따라 로컬에 저장하는 것입니다. 예를 들어 /file/2013/0001/en/test.html이면 nginx는 지정된 저장 디렉터리에 각 디렉터리와 파일을 순서대로 생성합니다. 다른 유형은 Proxy_cache를 통해 열립니다. 이렇게 저장된 파일은 URL 경로에 따라 구성되지 않고 몇 가지 특수한 방법(여기에서는 사용자 정의 방법이라고 함)을 사용하여 관리됩니다. 그렇다면 이 두 가지 방법 각각의 장점은 무엇입니까?
URL 경로로 파일을 저장하는 방법은 프로그램 처리가 비교적 간단하지만 성능이 좋지 않습니다. 우선, 일부 URL은 매우 깁니다. 로컬 파일 시스템에 그렇게 깊은 디렉토리를 생성해야 한다면 파일 열기 및 검색 속도가 매우 느려질 것입니다. (커널에서 경로 이름을 통해 inode를 검색하는 프로세스를 떠올려 보세요.) . 패턴을 처리하기 위해 사용자 정의 방법을 사용하는 경우 파일 및 경로와 분리될 수 없지만 URL 길이로 인해 복잡성이 증가하거나 성능이 저하되지는 않습니다. 어떤 의미에서 이것은 사용자 모드 파일 시스템이며 가장 일반적인 것은 Squid의 CFS입니다. nginx에서 사용하는 방법은 비교적 간단하며 주로 관리를 위해 URL의 md5 값에 의존하며 이에 대해서는 나중에 분석하겠습니다.
캐싱은 백엔드에서 콘텐츠를 가져온 다음 클라이언트로 보내는 것과 분리될 수 없습니다. 동시에 수신하고 전송해야 하는 특정 처리 방법을 누구나 쉽게 생각할 수 있습니다. 다른 방법은 읽기 및 보내기 등 너무 비효율적입니다. 여기서는 nginx가 동시에 수신하고 전송한다는 점을 언급하겠습니다. 사용되는 구조는 백엔드와 클라이언트 간의 통신을 위한 매체인 ngx_event_pipe_t입니다. 구조는 일반적인 구성 요소이므로 저장과 관련된 관련 기능을 처리하려면 일부 특수 태그가 필요하므로 캐시 가능한 멤버가 이 중요한 작업을 수행합니다.
p->cacheable = u->cacheable || u->store;
즉, 캐시 가능이 1이면 저장되어야 하고, 그렇지 않으면 저장되지 않습니다. 저장되었습니다. 그렇다면 u->cacheable과 u->store는 무엇을 의미할까요? 이는 각각 앞에서 언급한 두 가지 방법, 즉 Proxy_cache 및 Proxy_store를 나타냅니다.
(몇 가지 지식을 추가하자면, nginx가 백엔드 데이터를 가져올 때 해당 동작은 백엔드 서버에 대한 응답 버퍼링을 활성화하는 Proxy_buffering에 의해 제어됩니다. 버퍼링이 활성화되면 nginx는 프록시가 서버는 매우 빠르게 응답하고 이를 버퍼에 넣을 수 있습니다. 응답이 메모리에 맞지 않으면 응답이 하드 디스크에 기록됩니다. 백엔드에서 즉시 전송됩니다. )
이것들은 모두 한계가 있으며 아직 nginx 캐시 기능의 핵심을 다루지 않았습니다. 구현 관점에서 볼 때 nginx 업스트림 구조에는 캐시라는 멤버가 있으며 해당 유형은 ngx_shm_zone_t입니다. 캐시 기능을 활성화하면 캐시 멤버는 공유 메모리를 관리하는 데 사용되며(공유 메모리는 왜 사용되나요?) 다른 방식으로 저장하면 해당 멤버는 NULL이 됩니다. 또 설명해야 할 점은 캐시 시스템에서는 파일을 보통 스토어 객체, 즉 캐시 객체라고 부르기 때문에 캐싱하기 전에 반드시 스토어 객체를 생성해야 한다는 점이다. 중요한 질문은 그것을 만드는 시간을 어떻게 선택하느냐 하는 것입니다. 이에 대해 어떻게 생각하시나요? 먼저 파일을 캐시해야 하는지 확인해야 합니다. 당연히 GET 메서드로 요청한 파일은 일반적으로 캐시해야 하므로 요청 처리 초기 단계에서 GET 메서드를 보면 먼저 개체를 생성할 수 있습니다. 하지만 GET 방식으로 요청한 파일도 캐싱할 수 없는 경우가 많습니다. 객체를 너무 일찍 생성하면 시간과 공간을 낭비할 뿐만 아니라 결국 파괴됩니다. 그렇다면 GET 요청 저장에는 무엇이 영향을 미치나요? 이는 응답 헤더의 캐시 제어 필드입니다. 이 필드는 파일을 캐시할 수 있는지 여부를 프록시나 브라우저에 알려줍니다. 일반적으로 캐시 서버는 응답 헤더에 Cache-control 필드가 없으면 기본적으로 요청을 캐시합니다.
이러한 고려 사항을 바탕으로 우리가 개발한 캐시 서버는 응답 헤더를 구문 분석하고 충분한 캐싱 증거를 얻은 후에만 캐시 개체를 생성합니다. 불행하게도 nginx는 이것을 하지 않습니다.
nginx는 ngx_http_upstream_init_request 함수에서 캐시 객체 생성을 완료합니다. 이 함수는 http 처리의 어느 단계에 있습니까? 백엔드와 연결을 설정하기 전에. 개인적으로 이곳은 적합하지 않다고 생각합니다. . . 어떻게 생각하나요?
생성 과정과 관련하여 ngx_http_upstream_cache 함수를 읽을 수 있습니다. 여기서는 nginx와 비교하여 캐시를 분석하겠습니다. 우리의 요청은 캐시 개체와의 연결을 설정하기 위해 store라는 멤버를 사용합니다. 동일한 작업을 수행하기 위해 요청 구조에 캐시 멤버가 있는 nginx의 경우에도 마찬가지입니다. 차이점은 스토어 멤버에 해당하는 공간이 공유 메모리에 있는 반면 nginx는 r->pool에 적용된다는 것입니다(왜 이렇게 할까요?).
다음 단계에서 nginx는 여기서 일반적으로 사용되는 MD5 구성에 따라 캐시 개체의 키를 생성해야 합니다. 이 키는 시스템에서 캐시 개체의 고유 식별자 역할을 합니다. 많은 사람들이 md5 충돌에 대해 걱정할 수 있습니다. 나는 이 요구 사항이 특별히 까다롭지 않고 처리가 상대적으로 간단하다면 여기에서는 완전히 수용 가능하다고 생각합니다.
나중에 처리해야 할 것은 파일을 디스크에 어떻게 저장해야 하는가입니다.
이전에 사용한 예를 들어보겠습니다: /file/2013/0001/en/test.html. 해당 md5 값은 8ef9229f02c5672c747dc7a324d658d0입니다. 실제로 nginx는 이를 파일 이름으로 사용합니다. 이 정도면 충분합니까? 파일을 저장할 디렉토리를 찾았는데 그 안에 그러한 파일이 많이 있으면 어떻게 될까요? 우리는 대부분의 파일 시스템이 단일 디렉터리에 있는 파일 수에 제한이 있으므로 이러한 간단하고 조잡한 처리가 불가능하다는 것을 알고 있습니다. 무엇을 해야 할까요? nginx를 사용하면 구성을 통해 다중 레벨 디렉토리를 사용하여 이 문제를 해결할 수 있습니다. 간단히 말해서, nginx는 레벨 지시어를 사용하여 디렉터리 수준 수(콜론으로 구분)와 각 디렉터리 이름의 문자 수를 지정합니다. 이 예에서는level=1:2로 구성되어 있다고 가정합니다. 2레벨 디렉토리 이름은 1문자이고, 2레벨 디렉토리 이름은 2문자입니다. 그러나 nginx는 최대 3개 수준의 디렉터리(level=xxx:xxx:xxx)를 지원합니다.
그러면 디렉토리 이름을 구성하는 문자는 어디서 오는 걸까요? 저장 디렉토리가 /cache, level=1:2라고 가정하면 위 파일은 다음과 같이 저장됩니다:
/cache/0 / 8d/8ef9229f02c5672c747dc7a324d658d0
두 디렉터리 이름 0과 8d가 어떻게 나온 것인지 살펴보세요. 설명하다. 객체가 생성된 후에는 ngx_http_file_cache_exists에서 처리하는 객체 관리 구조를 캐시해야 합니다.
이 파일을 생성할 때 현재 디렉토리와 파일이 이미 존재한다면 어떻게 해야 할까요? 코드를 살펴보고 nginx가 이를 어떻게 처리하는지 확인할 수 있습니다.
이제 논의는 모두 끝났습니다. 이제 처리에 대해 논의하겠습니다. 백엔드 콘텐츠 도착.
자세한 내용은
http://www.pagefault.info/?p=123
http://www.pagefault.info/?p=375위 내용은 nginx 캐시 시스템의 설계 원리를 그 측면을 포함하여 소개하고 있으며, PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.