> Java > Java베이스 > Java 높은 동시성 시스템 설계 - 캐시

Java 높은 동시성 시스템 설계 - 캐시

coldplay.xixi
풀어 주다: 2020-10-10 17:24:49
앞으로
2176명이 탐색했습니다.

오늘

java basics 칼럼에서는 Java 고동시성 시스템 설계의 캐싱 장을 소개합니다.

Java 높은 동시성 시스템 설계 - 캐시

일반적인 하드웨어 구성 요소의 대기 시간은 다음과 같습니다. Java 높은 동시성 시스템 설계 - 캐시

이 데이터를 보면 메모리 주소를 수행하는 데 약 100ns, 디스크 조회를 수행하는 데 약 10ms가 걸리는 것을 알 수 있습니다. 캐시 저장 매체로 메모리를 사용하면 디스크를 주 저장 매체로 사용하는 데이터베이스에 비해 성능이 몇 배나 향상되는 것을 볼 수 있습니다. 따라서 메모리는 데이터를 캐싱하는 가장 일반적인 매체입니다.

1. 캐시 케이스

1. TLB

Linux 메모리 관리는 MMU(Memory Management Unit)라는 하드웨어를 사용하여 가상 주소에서 물리적 주소로의 변환을 구현하지만, 모든 변환이 이렇게 이루어져야 합니다. 의심할 바 없이 성능 손실을 초래할 수 있으므로 TLB(Translation Lookaside Buffer)라는 구성 요소를 사용하여 최근 변환된 가상 주소와 실제 주소 간의 매핑을 캐시합니다. TLB는 캐싱 구성 요소입니다.

2. Douyin

플랫폼의 짧은 동영상은 실제로 내장된 네트워크 플레이어를 사용하여 완성됩니다. 네트워크 플레이어는 데이터 스트림을 수신하고, 데이터를 다운로드하고, 오디오와 비디오 스트림을 분리하고, 디코딩 및 기타 프로세스를 수행한 후 재생을 위해 주변 장치로 출력합니다. 일부 캐싱 구성 요소는 일반적으로 비디오가 열리지 않을 때 비디오 데이터의 일부를 캐시하도록 플레이어에서 설계됩니다. 예를 들어 Douyin을 열면 서버는 첫 번째 비디오를 재생할 때 한 번에 세 가지 비디오 정보를 반환할 수 있습니다. 플레이어 두 번째 및 세 번째 동영상의 데이터 중 일부를 캐시하여 두 번째 동영상을 시청할 때 사용자에게 "초 단위로 시작"하는 느낌을 줄 수 있습니다.

3. HTTP 프로토콜 캐시

사진과 같은 정적 리소스를 처음 요청하면 사진 정보를 반환하는 것 외에도 서버의 응답 헤더에 "Etag" 필드가 있습니다. 브라우저는 이미지 정보와 이 필드의 값을 캐시합니다. 다음에 이미지가 요청되면 브라우저에서 시작된 요청 헤더에 "If-None-Match" 필드가 있고 캐시된 "Etag" 값이 여기에 기록되어 서버로 전송됩니다. 서버는 이미지 정보가 변경되었는지 확인합니다. 변경되지 않은 경우 304 상태 코드가 브라우저에 반환되고 브라우저는 캐시된 이미지 정보를 계속 사용합니다. 이러한 캐시 협상 방법을 통해 네트워크를 통해 전송되는 데이터 크기를 줄일 수 있어 페이지 표시 성능이 향상됩니다. Java 높은 동시성 시스템 설계 - 캐시

2. 캐시 분류

1. 정적 캐시

정적 캐시는 일반적으로 Velocity 템플릿이나 정적 HTML 파일을 생성하여 정적 캐시를 구현합니다. 백엔드 애플리케이션 서버에 대한 압박

2. 분산 캐시

분산 캐시의 대표적인 예로는 우리에게 친숙한 Memcached와 Redis가 있습니다. 그들은 강력한 성능을 가지고 있으며 일부 분산 솔루션을 통해 클러스터를 형성함으로써 단일 시스템의 한계를 뛰어넘을 수 있습니다. 따라서 전체 아키텍처에서 분산 캐시는 매우 중요한 역할을 합니다

3. 로컬 캐시

Guava Cache 또는 Ehcache 등은 애플리케이션과 동일한 프로세스에 배포될 필요가 없다는 장점이 있습니다. 네트워크 전반에 걸쳐 스케줄링되며 속도가 매우 빠르므로 단시간에 핫 쿼리를 차단하는 데 사용할 수 있습니다.

3. 캐시 읽기 및 쓰기 전략

1. 캐시 제외 전략

데이터를 업데이트할 때 캐시에 있는 데이터를 삭제합니다. 캐시, 데이터베이스에서 데이터를 읽어 캐시로 업데이트합니다. Java 높은 동시성 시스템 설계 - 캐시

이 전략은 우리가 캐싱에 사용하는 가장 일반적인 전략인 Cache Aside 전략(바이패스 캐시 전략이라고도 함)입니다. 이 전략 데이터는 데이터베이스의 데이터를 기반으로 하며 캐시의 데이터는 요청 시 로드됩니다. .

Cache Aside 전략은 일상적인 개발에서 가장 일반적으로 사용되는 캐싱 전략이지만, 이를 사용할 때 상황에 따라 변경하는 방법도 배워야 합니다. 이는 정적이지 않습니다. Cache Aside의 가장 큰 문제점은 쓰기가 빈번할 때 캐시에 있는 데이터가 자주 지워지므로 캐시 적중률에 어느 정도 영향을 미친다는 것입니다. 귀하의 비즈니스에 캐시 적중률에 대한 엄격한 요구 사항이 있는 경우 다음 두 가지 솔루션을 고려할 수 있습니다.

한 가지 방법은 데이터를 업데이트할 때 캐시를 업데이트하는 것이지만, 캐시를 업데이트하기 전에 분산 잠금을 추가하는 것입니다. 이렇게 하면 동시에 하나의 스레드만 캐시를 업데이트할 수 있고 동시성 문제가 발생하지 않기 때문입니다. 물론 이렇게 하면 쓰기 성능에 어느 정도 영향을 미치게 됩니다(권장).

또 다른 접근 방식은 데이터를 업데이트할 때 캐시를 업데이트하는 것이지만 캐시에 더 짧은 만료 시간을 추가하면 캐시 불일치가 발생하더라도 캐시된 데이터도 빠르게 만료되며 비즈니스에 미치는 영향은 허용 가능합니다.

2. Read/Write Through

이 전략의 핵심 원칙은 사용자가 캐시만 처리하고 캐시는 데이터베이스와 통신하여 데이터를 쓰거나 읽는 것입니다. Java 높은 동시성 시스템 설계 - 캐시

Write Through

전략은 다음과 같습니다. 먼저 쓸 데이터가 캐시에 이미 존재하는지 쿼리하고, 이미 존재하는 경우 캐시에 있는 데이터를 업데이트하고 데이터베이스에 동기화합니다. 캐시 구성 요소입니다. 캐시에 데이터가 없으면 이 상황을 "쓰기 실패"라고 합니다. 일반적으로 두 가지 "Write Miss" 방법을 선택할 수 있습니다. 하나는 "Write Allocate(쓰기로 배포)"입니다. 이는 캐시에 해당 위치를 쓴 다음 캐시 구성 요소가 이를 다른 데이터베이스에 동기적으로 업데이트하는 것입니다. "No -write 할당(쓰기 시 할당 안 함)"이면 캐시에 쓰는 것이 아니라 데이터베이스에 직접 업데이트하는 방법입니다. Write Through 전략에서 데이터베이스에 대한 쓰기는 동기식이며, 이는 데이터베이스에 대한 동기식 쓰기의 대기 시간이 캐시에 쓰는 것보다 훨씬 길기 때문에 성능에 더 큰 영향을 미칩니다. Write Back 전략을 통해 데이터베이스를 비동기식으로 업데이트합니다.

Read Through

전략은 다음과 같이 간단합니다. 먼저 캐시에 데이터가 있는지 쿼리하고, 존재하지 않으면 직접 반환합니다. 데이터베이스에서 동기적으로 데이터를 로드합니다.

3. Write Back

이 전략의 핵심 아이디어는 데이터를 쓸 때만 캐시에 쓰고 캐시 블록을 "더티"로 표시하는 것입니다. 더티 블록의 데이터는 다시 사용될 때만 백엔드 스토리지에 기록됩니다. "Write Miss"의 경우 백엔드 스토리지에 쓰는 동안 캐시에 쓰는 것을 의미하는 "Write Allocate" 방법을 사용하므로 백엔드를 업데이트하지 않고 후속 쓰기 요청에서만 캐시를 업데이트하면 됩니다. 저장. 위의 write through 전략과의 차이점에 유의하세요. Java 높은 동시성 시스템 설계 - 캐시

캐시를 읽을 때 캐시 히트가 발견되면 캐시 데이터를 직접 반환해 드립니다. 캐시가 누락되면 사용 가능한 캐시 블록을 찾습니다. 캐시 블록이 "더티"이면 캐시 블록의 이전 데이터가 백엔드 스토리지에 기록되고 데이터가 백엔드 스토리지에서 로드됩니다. 블록이 더티가 아닌 경우 캐시 구성요소는 백엔드 스토리지의 데이터를 캐시에 로드합니다. 마지막으로 캐시를 더티가 아닌 것으로 설정하고 데이터를 반환합니다. Java 높은 동시성 시스템 설계 - 캐시

다시 쓰기 전략은 주로 디스크에 데이터를 쓰는 데 사용됩니다. 예: 운영 체제 수준의 페이지 캐시, 로그의 비동기 플러시, 메시지 큐의 메시지를 디스크에 비동기 쓰기 등 이 전략의 성능 이점은 의심할 여지가 없기 때문에 디스크에 직접 쓰기로 인해 발생하는 임의 쓰기 문제를 방지합니다. 결국 메모리 쓰기와 디스크 쓰기에 대한 임의 I/O의 대기 시간은 몇 배 정도 다릅니다.

4. 캐시 고가용성

캐시 적중률은 캐시에서 모니터링해야 하는 데이터 지표입니다. 캐시의 고가용성은 캐시 침투 가능성을 어느 정도 줄이고 시스템 안정성을 향상시킬 수 있습니다. . 캐싱을 위한 고가용성 솔루션에는 주로 클라이언트 측 솔루션, 중간 프록시 계층 솔루션, 서버 측 솔루션의 세 가지 범주가 포함됩니다.

1. 클라이언트 측 솔루션

클라이언트 측 솔루션에서 주의해야 할 사항은 다음과 같습니다. 캐시의 쓰기 및 읽기 측면: 데이터를 쓸 때 캐시에 쓴 데이터는 여러 노드에 분산되어야 합니다. 즉, 데이터 샤딩이 수행됩니다. 데이터를 읽을 때 내결함성을 위해 여러 캐시 세트를 사용하여 캐시 시스템의 가용성을 향상시킬 수 있습니다. 데이터 읽기와 관련하여 마스터-슬레이브 및 다중 복사라는 두 가지 전략을 사용할 수 있습니다. 두 가지 전략은 서로 다른 문제를 해결하기 위해 제안됩니다. 구체적인 구현 세부 사항에는 데이터 샤딩, 마스터-슬레이브, 다중 복사본

데이터 샤딩

이 포함됩니다.

일관적인 해시 알고리즘. 이 알고리즘에서는 전체 해시 값 공간을 가상 링으로 구성한 다음 캐시 노드의 IP 주소나 호스트 이름을 해시하여 이 링에 배치합니다. 특정 키에 액세스해야 하는 노드를 결정해야 할 때 먼저 키에 대해 동일한 해시 값을 수행하고 링에서의 위치를 ​​결정한 다음 시계 방향으로 링을 "걷습니다". 첫 번째 캐시 노드는 액세스할 노드입니다. Java 높은 동시성 시스템 설계 - 캐시

이때 노드 1과 노드 2 사이에 노드 5를 추가하면 원래 노드 2에 도달한 키 3이 이제 노드 5에 도달하는 반면 다른 키는 같은 방식으로 변경되지 않은 것을 볼 수 있습니다. 클러스터에서 노드 3을 제거하면 키 5에만 영향을 미칩니다. 따라서 노드를 추가하고 삭제할 때 소수의 키만 다른 노드로 "드리프트"되고 대부분의 키에 적중된 노드는 변경되지 않은 상태로 유지되므로 적중률이 크게 떨어지지 않습니다. [Tip] 컨시스턴트 해싱 시 발생하는 캐시 애벌런치 현상을 해결하려면 가상 노드를 활용하세요. 일관된 해시 샤딩과 해시 샤딩의 차이점은 캐시 적중률 문제입니다. 머신을 추가하거나 줄이면 해시 샤딩으로 인해 캐시가 무효화되고 캐시 적중률이 감소합니다.

Master-slave

Redis 자체는 마스터-슬레이브 배포 방식을 지원하지만 Memcached는 이를 지원하지 않습니다. Memcached의 마스터-슬레이브 메커니즘이 클라이언트에 어떻게 구현되어 있나요? 각 마스터 그룹에 대해 슬레이브 세트를 구성합니다. 데이터를 업데이트할 때 마스터와 슬레이브가 동시에 업데이트됩니다. 읽을 때는 먼저 슬레이브에서 데이터를 읽습니다. 데이터를 읽을 수 없으면 마스터를 통해 읽은 후 슬레이브 데이터를 핫 상태로 유지하기 위해 데이터를 슬레이브에 다시 시드합니다. 마스터-슬레이브 메커니즘의 가장 큰 장점은 특정 슬레이브가 다운될 때 마스터가 백업이 되어 데이터베이스에 침투하는 요청이 많지 않아 캐시 시스템의 고가용성이 향상된다는 점입니다.

여러 복사본

마스터-슬레이브 방법은 대부분의 시나리오에서 문제를 해결할 수 있습니다. 그러나 극단적인 트래픽 시나리오에서는 일반적으로 슬레이브 그룹이 모든 트래픽을 완전히 감당할 수 없으며 슬레이브 네트워크 카드 대역폭으로 인해 병목 현상이 발생할 수 있습니다. . 이 문제를 해결하기 위해 마스터/슬레이브 앞에 복사 레이어를 추가하는 것을 고려합니다. 전체 아키텍처는 다음과 같습니다. Java 높은 동시성 시스템 설계 - 캐시

이 솔루션에서는 클라이언트가 쿼리 요청을 시작하면 요청이 먼저 여러 복사본 그룹에서 선택됩니다. 복사본 그룹은 쿼리를 시작합니다. 쿼리가 실패하면 계속해서 마스터/슬레이브를 쿼리하고 쿼리 결과는 복사본 그룹에 더티 데이터가 존재하지 않도록 모든 복사본 그룹에 다시 시드됩니다. 비용 고려 사항에 따라 각 복사본 그룹의 용량은 마스터 및 슬레이브의 용량보다 작으므로 더 자주 사용되는 데이터만 저장합니다. 이 아키텍처에서는 마스터와 슬레이브의 요청 볼륨이 크게 줄어듭니다. 저장하는 데이터의 열을 보장하기 위해 실제로는 마스터와 슬레이브를 복사 그룹으로 사용합니다.

2. 중간 프록시 레이어

Facebook의 Mcrouter, Twitter의 Twemproxy, Wandoujia의 Codis 등 업계에는 중간 프록시 레이어 솔루션도 많이 있습니다. 그들의 원칙은 기본적으로 그림으로 요약될 수 있습니다: Java 높은 동시성 시스템 설계 - 캐시

3. 서버 측 솔루션

Redis는 마스터-슬레이브 Redis 배포 중 고가용성 문제를 해결하기 위해 버전 2.4에서 Redis Sentinel 모드를 제안했습니다. 노드 장애 후 슬레이브 노드는 전체 클러스터의 가용성을 보장하기 위해 자동으로 마스터 노드로 승격됩니다. 전체 아키텍처는 아래 그림과 같습니다. Java 높은 동시성 시스템 설계 - 캐시

redis Sentinel도 클러스터에 배포됩니다. Sentinel 노드의 오류로 인해 발생하는 자동 오류 복구 문제를 방지합니다. 각 Sentinel 노드는 상태 비저장입니다. 마스터의 주소는 Sentinel에서 구성되며, Sentinel은 항상 마스터의 상태를 모니터링하며, 설정된 시간 내에 마스터가 응답하지 않는 것으로 확인되면 마스터가 사망한 것으로 간주됩니다. 슬레이브 노드 중 하나를 선택하여 마스터 노드로 승격하고 다른 모든 슬레이브 노드를 새 마스터의 슬레이브 노드로 처리합니다. Sentinel 클러스터 내에서 중재하는 동안 구성된 값에 따라 결정됩니다. 여러 Sentinel 노드가 마스터가 다운되었다고 생각하면 마스터-슬레이브 전환 작업을 수행할 수 있습니다. 즉, 클러스터는 합의에 도달해야 합니다. 캐시 노드의 상태.

[Tip] 캐시에 대한 쓰기 및 읽기 요청이 Sentinel 노드를 통과하지 않기 때문에 위 클라이언트에서 Sentinel 클러스터로의 연결선은 점선으로 표시됩니다.

5. 캐시 침투

1. Pareto

인터넷 시스템의 데이터 액세스 모델은 일반적으로 "80/20 원칙"을 따릅니다. 파레토 원리라고도 알려진 "80/20 원리"는 이탈리아 경제학자 파레토가 제안한 경제 이론입니다. 간단히 말해서, 일련의 사물에서 가장 중요한 부분은 일반적으로 20%만 차지하고 나머지 80%는 그다지 중요하지 않다는 것을 의미합니다. 이를 데이터 액세스 분야에 적용하면 핫 데이터의 20%에 자주 액세스하고 나머지 80%의 데이터에는 자주 액세스하지 않게 됩니다. 캐시 용량이 제한되어 있고 대부분의 액세스는 핫스팟 데이터의 20%만 요청하므로 이론적으로 취약한 백엔드 시스템을 효과적으로 보호하려면 제한된 캐시 공간에 핫스팟 데이터의 20%만 저장하면 됩니다. 핫이 아닌 데이터의 나머지 80%에 대한 캐싱을 포기할 수 있습니다. 따라서 이러한 소량의 캐시 침투는 불가피하지만 시스템에 해를 끼치지는 않습니다.

2. null 값 반환

데이터베이스에서 null 값을 쿼리하거나 예외가 발생하면 캐시에 null 값을 반환할 수 있습니다. 그러나 널값은 정확한 비즈니스 데이터가 아니며 캐시 공간을 차지하게 되므로, 널값이 빠르게 만료되어 짧은 시간 내에 소멸될 수 있도록 널값에 상대적으로 짧은 만료 시간을 추가하겠습니다. Null 값을 반환하면 많은 수의 침투 요청을 차단할 수 있지만, 캐시된 Null 값이 많으면 캐시 저장 공간도 낭비됩니다. 캐시된 캐시도 제거됩니다. 반대로 캐시 적중률이 감소합니다. 따라서 캐시 용량이 이 솔루션을 지원할 수 있는지 평가해 보시기 바랍니다. 이를 지원하기 위해 많은 수의 캐시 노드가 필요한 경우 null 값을 심는 것으로는 해결할 수 없습니다. 이 경우 블룸 필터 사용을 고려할 수 있습니다.

3. 블룸 필터

1970년에 Bloom은 요소가 집합에 있는지 확인하기 위해 Bloom 필터 알고리즘을 제안했습니다. 이 알고리즘은 바이너리 배열과 해시 알고리즘으로 구성됩니다. 기본 아이디어는 다음과 같습니다. 제공된 해시 알고리즘에 따라 집합의 각 값에 해당하는 해시 값을 계산한 다음 해시 값을 배열 길이로 모듈로하여 배열에 포함되어야 하는 인덱스 값을 얻습니다. 배열의 이 위치에 인덱스 값을 추가합니다. 값이 0에서 1로 변경되었습니다. 이 집합에 요소가 존재하는지 판단할 때 동일한 알고리즘에 따라 요소의 인덱스 값만 계산하면 됩니다. 이 위치의 값이 1이면 해당 요소가 집합에 포함된 것으로 간주됩니다. 세트에 포함되지 않은 것으로 간주됩니다. Java 높은 동시성 시스템 설계 - 캐시

블룸 필터를 사용하여 캐시 침투를 해결하는 방법은 무엇입니까?

사용자 정보가 저장되는 테이블을 예로 들어 설명하겠습니다. 먼저 길이가 20억인 배열과 같은 큰 배열을 초기화한 다음 해시 알고리즘을 선택한 다음 모든 기존 사용자 ID의 해시 값을 계산하고 이를 이 큰 배열에 매핑하여 위치 값을 매핑합니다. 1로 설정되고 다른 값은 0으로 설정됩니다. 데이터베이스에 쓰는 것 외에도 새로 등록된 사용자는 동일한 알고리즘에 따라 Bloom 필터 배열의 해당 위치 값을 업데이트해야 합니다. 그러다가 특정 사용자의 정보를 조회해야 할 때 Bloom 필터에 해당 ID가 존재하는지 먼저 조회하고, 존재하지 않는 경우 데이터베이스와 캐시를 계속 조회하지 않고 직접 null 값을 반환하므로, 이를 크게 줄일 수 있습니다. 예외. 쿼리로 인한 캐시 침투. Java 높은 동시성 시스템 설계 - 캐시

블룸 필터 장점:

(1) 고성능. 쓰기 작업이든 읽기 작업이든 시간 복잡도는 O(1)이며 이는 공간을 절약하기 위한 상수 값

(2)입니다. 예를 들어, 20억 개의 배열에는 2000000000/8/1024/1024 = 238M의 공간이 필요합니다. 배열이 저장에 사용되는 경우 각 사용자 ID가 4바이트의 공간을 차지한다고 가정하면 20억 명의 사용자를 저장하려면 2000000000 * 4 / 1024가 필요합니다. / 1024 = 7600M 공간으로 Bloom 필터의 32배입니다.

블룸 필터의 단점:

(1) 집합에 요소가 포함되어 있는지 판단할 때 특정 오류 확률이 있습니다. 예를 들어 집합에 포함되지 않은 요소를 집합에 포함된 것으로 판단합니다. .

원인: 해시 알고리즘 자체에 결함이 있습니다.

해결책: 여러 해시 알고리즘을 사용하여 요소에 대한 여러 해시 값을 계산합니다. 모든 해시 값에 해당하는 배열의 값이 1인 경우에만 해당 요소가 집합에 포함된 것으로 간주됩니다.

(2)는 요소 삭제를 지원하지 않습니다. Bloom 필터가 요소 삭제를 지원하지 않는 결함도 해시 충돌과 관련이 있습니다. 예를 들어 두 요소 A와 B가 모두 컬렉션의 요소이고 동일한 해시 값을 갖는 경우 배열의 동일한 위치에 매핑됩니다. 이때 A를 삭제하고 배열에서 해당 위치의 값도 1에서 0으로 변경됩니다. 그러다가 B를 판단하여 그 값이 0임을 알게 되면 B도 0이 아닌 요소라고 판단하게 됩니다. 세트에서 우리는 잘못된 결론을 얻게 될 것입니다.

해결책: 배열에 0과 1의 값만 갖는 대신 개수를 저장합니다. 예를 들어 A와 B가 동시에 배열의 인덱스에 도달하면 이 위치의 값은 2입니다. A가 삭제되면 값이 2에서 1로 변경됩니다. 이 솔루션의 어레이는 더 이상 비트가 아닌 값을 저장하므로 공간 소비가 늘어납니다.

4. 개 더미 효과

예를 들어, 매우 핫한 캐시 항목이 있을 때, 일단 실패하면 대량의 요청이 데이터베이스에 침투하게 되는데, 이는 데이터베이스에 즉각적이고 큰 압력을 가하게 됩니다. 시나리오 "개 더미 효과"(개 더미 효과). Dog Pile 효과를 해결하는 아이디어는 캐시 침투 후 동시성을 최소화하는 것입니다. 해결책은 비교적 간단합니다.

(1) 특정 핫 캐시 항목이 만료된 후 백그라운드 스레드를 시작하고 데이터베이스에 침투하도록 코드에서 제어합니다. 캐시가 로드되기 전에는 이 캐시에 액세스하려는 모든 요청이 침투하지 않고 직접 반환됩니다.

(2) Memcached 또는 Redis에서 분산 잠금을 설정하면 잠금 획득 요청만 데이터베이스에 침투할 수 있습니다.

6. CDN

1. 우리 시스템에 정적 리소스 가속의 이유

가 존재합니다. 정적 리소스 요청: 모바일 앱의 경우 이러한 정적 리소스는 주로 웹 사이트의 사진, 비디오 및 스트리밍 미디어 정보이며 JavaScript 파일, CSS 파일, 정적 HTML 파일 등이 포함됩니다. 엄청난 양의 읽기 요청이 있고 높은 액세스 속도가 필요하며 높은 대역폭을 차지합니다. 이때 느린 액세스 속도와 전체 대역폭에 문제가 있어 동적 요청을 대상으로 하는 방법을 고려해야 합니다. 자원을 읽는 속도가 빨라집니다.

2. CDN

정적 리소스 액세스의 핵심은 인근 액세스입니다. 즉, 베이징의 사용자는 베이징의 데이터에 액세스하고 항저우의 사용자는 항저우의 데이터에 액세스해야 최적의 성능을 얻을 수 있습니다. 우리는 정적 리소스에 대한 대부분의 액세스를 처리하기 위해 비즈니스 서버의 상위 계층에 특수 캐시 계층을 추가하는 것을 고려합니다. 이 특수 캐시 계층의 노드는 사용자가 가장 가까운 노드를 선택할 수 있도록 전국에 분산되어야 합니다. 입장. 캐시 적중률도 어느 정도 보장되어야 하며, 자원 저장 원본 사이트에 접근하기 위한 요청(원본 복귀 요청)도 최소화되어야 합니다. 이 캐싱 계층은 CDN입니다.

CDN(콘텐츠 전송 네트워크/콘텐츠 배포 네트워크, 콘텐츠 배포 네트워크). 간단히 말해서, CDN은 여러 지리적 위치에 있는 컴퓨터실에 있는 서버에 정적 리소스를 배포하므로 인근 데이터 액세스 문제를 잘 해결하고 정적 리소스 액세스 속도를 높일 수 있습니다.

3. CDN 시스템 구축

CDN 시스템 구축 시 고려해야 할 두 가지 사항:

(1) 사용자 요청을 CDN 노드에 매핑하는 방법

이것이 매우 간단하다고 생각할 수도 있습니다. 사용자 CDN 노드의 IP 주소를 입력한 후 이 IP 주소에 배포된 CDN 서비스를 요청하면 됩니다. 그러나 그렇지 않은 경우 해당 IP를 해당 도메인 이름으로 바꿔야 합니다. 그럼 어떻게 해야 할까요? 이를 위해서는 도메인 이름 매핑 문제를 해결하기 위해 DNS를 사용해야 합니다. DNS(Domain Name System)는 실제로 도메인 이름과 IP 주소 간의 대응을 저장하는 분산 데이터베이스입니다. 일반적으로 도메인 이름 확인 결과에는 두 가지 유형이 있습니다. 하나는 도메인 이름에 해당하는 IP 주소를 반환하는 "A 레코드"이고, 다른 하나는 다른 도메인 이름, 즉 도메인 이름을 반환하는 "CNAME 레코드"입니다. 현재 도메인 이름 확인 다른 도메인 이름 확인으로 이동합니다.

예: 예를 들어 회사의 1차 도메인 이름이 example.com인 경우 이미지 서비스의 도메인 이름을 "img.example.com"으로 정의한 다음 해상도의 CNAME을 구성할 수 있습니다. 예를 들어 CDN에서 제공하는 도메인 이름에 대해 ucloud는 "80f21f91.cdn.ucloud.com.cn"이라는 도메인 이름을 제공할 수 있습니다. 이러한 방식으로 귀하의 전자상거래 시스템에서 사용되는 이미지 주소는 "img.example.com/1.jpg"가 될 수 있습니다.

사용자가 이 주소를 요청하면 DNS 서버는 도메인 이름을 도메인 이름 80f21f91.cdn.ucloud.com.cn으로 확인한 다음 도메인 이름을 CDN의 노드 IP로 확인하여 리소스 데이터가 CDN에서 구할 수 있습니다.

도메인 이름 수준 확인 최적화

도메인 이름 확인 프로세스는 계층적이며 각 수준에는 확인을 담당하는 전용 도메인 이름 서버가 있으므로 도메인 이름 확인 프로세스에는 공용 네트워크에서 여러 DNS 쿼리가 필요할 수 있습니다. 성능면에서는 상대적으로 열악한 편입니다. 한 가지 해결책은 APP가 시작될 때 구문 분석해야 하는 도메인 이름을 미리 구문 분석한 다음 구문 분석된 결과를 로컬 LRU 캐시에 캐시하는 것입니다. 이런 식으로 이 도메인 이름을 사용하려면 캐시에서 필요한 IP 주소만 직접 가져오면 됩니다. 캐시에 없으면 전체 DNS 쿼리 프로세스를 거치게 됩니다. 동시에, DNS 확인 결과의 변경으로 인해 캐시의 데이터가 무효화되는 것을 방지하기 위해 타이머를 시작하여 캐시의 데이터를 정기적으로 업데이트할 수 있습니다.

(2) 사용자의 지리적 위치 정보를 기반으로 가까운 노드를 선택하는 방법.

GSLB(Global Server Load Balance)는 서로 다른 지역에 배포된 서버 간의 로드 밸런싱을 의미하며, 아래에서 많은 로컬 로드 밸런싱 구성 요소를 관리할 수 있습니다. 여기에는 두 가지 기능이 있습니다. 한편으로는 로드 밸런싱 서버입니다. 이름에서 알 수 있듯이 로드 밸런싱은 다른 한편으로는 아래에서 관리되는 서버의 로드가 더 균일하도록 트래픽을 균등하게 분산시키는 것을 의미합니다. 또한 통과하는 서버의 트래픽이 트래픽 소스와 비교적 가까운지 확인해야 합니다.

GSLB는 반환된 CDN 노드와 사용자가 가능한 한 동일한 지리적 영역에 있도록 다양한 전략을 사용할 수 있습니다. 예를 들어 사용자의 IP 주소는 지리적 위치에 따라 여러 영역으로 분할될 수 있습니다. CDN 노드는 하나의 영역에 매핑될 수 있습니다. 사용자가 있는 지역에 따라 적절한 노드가 반환되며, RTT를 측정하기 위해 데이터 패킷을 보내 반환할 노드를 결정할 수도 있습니다.

요약: DNS 기술은 CDN 구현에 사용되는 핵심 기술로, 사용자 요청을 CDN 노드에 매핑할 수 있으며 DNS 확인 프로세스의 응답 시간을 줄이기 위해 DNS 확인 결과를 로컬로 캐시해야 합니다. 사용자 그의 가까운 노드는 정적 리소스에 대한 액세스 속도를 높입니다.

Expansion

(1) Baidu 도메인 이름 확인 프로세스

처음에 도메인 이름 확인 요청은 먼저 로컬 호스트 파일을 확인하여 www.baidu.com에 해당하는 IP가 있는지 확인합니다. , 로컬 DNS에 도메인 이름 확인 결과 캐시가 있는지 여부를 요청합니다. 캐시가 있으면 신뢰할 수 없는 DNS에서 반환되었음을 나타내는 결과를 반환합니다. 그렇지 않으면 DNS의 반복 쿼리를 시작합니다. 먼저 최상위 DNS(.com)의 주소를 반환하는 루트 DNS를 요청한 다음 .com 최상위 DNS에 baidu.com의 도메인 이름 서버 주소를 요청합니다. baidu.com의 도메인 이름 서버에서 www.baidu.com IP 주소를 반환하는 동안 해당 IP 주소를 신뢰할 수 있는 DNS에서 온 것으로 표시하고 다음 번에 로컬 DNS 구문 분석 결과 캐시에 기록합니다. 동일한 도메인 이름을 구문 분석하면 반복적인 DNS 쿼리를 수행할 필요가 없습니다.

(2) CDN 지연

일반적으로 CDN 제조업체의 인터페이스를 통해 특정 CDN 노드에 정적 리소스를 쓴 다음 CDN의 내부 동기화 메커니즘이 해당 리소스를 각 CDN 노드에 분산하고 동기화합니다. CDN 내부 네트워크가 최적화된 경우 이 동기화 프로세스에 지연이 발생합니다. 선택한 CDN 노드에서 데이터를 얻을 수 없으면 원본 사이트에서 데이터를 가져와야 하고, 사용자 네트워크에서 원본 사이트로 네트워크가 필요합니다. 여러 백본 네트워크에 걸쳐 있을 수 있으며, 이는 성능 손실을 초래할 뿐만 아니라 원본 사이트의 대역폭을 소비하여 더 높은 R&D 비용을 초래합니다. 따라서 CDN을 사용할 때에는 CDN의 적중률과 원본 사이트의 대역폭에 주의를 기울여야 합니다.

관련 학습 권장 사항: java 기본

위 내용은 Java 높은 동시성 시스템 설계 - 캐시의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.im
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿