10 억 수준의 트래픽 급증 시스템을 만들기위한 자바 성능 최적화 : 4. 쿼리 성능 최적화 : 다중 머신 캐싱

4. 쿼리 성능 최적화 : 다중 머신 캐싱

1. 학습 목표 :

이전 섹션에서 서버의 수평 적 확장을 통해 요청을 처리하기 위해 여러 시스템에 애플리케이션을 배포하면 TPS가 크게 향상되었지만 이러한 여러 데이터베이스는 여전히 동일한 시스템의 데이터베이스를 사용합니다.
다음으로 몇 가지 쿼리 최적화 기술을 사용하여 제품 상세 페이지에 대한 쿼리 최적화 솔루션을 완성합니다.

  • 다단계 캐시의 정의 파악
  • 마스터 redis 캐시, 로컬 캐시
  • 핫 nginx 럭스 캐시 마스터

2. 캐시 디자인 원칙의 개요

  • 빠른 액세스 장비, 메모리를 사용하기위한 캐시
  • 네트워크 대기 시간을 줄이기 위해 캐시를 사용자에게 가장 가까운 위치로 푸시합니다.
  • 더티 캐시 정리 데이터베이스가 변경된 후 캐시의 오래된 데이터는 脏缓存정리 방법 및 정리 전략입니다.

** 다단계 캐시 **

  • redis 캐시
  • 핫 데이터, 로컬 메모리 캐시
  • nginx 프록시 캐시 캐시
  • nginx 루아 캐시

세, Redis 중앙 집중식 캐시 소개

설치, 원칙, 세션 관리 및 토큰 관리에 대해서는 위를 참조하십시오.
키-값 형식의 데이터베이스.
memorycatch는 완전한 메모리 데이터베이스입니다.
Redis는 데이터를 디스크로 플러시하여 일정량의 손실을 허용 할 수 있습니다. 일반적으로 휘발성 저장소로 간주됩니다.

왜 중앙 집중식 캐싱입니까?

애플리케이션 서버가 수평으로 확장 된 후 동일한 redis 서버에 연결됩니다.
image.png

1. 독립형 버전

장애 병목 현상, 용량 상한
image.png

2. 센티널 센티넬 모드

여기에 사진 설명 삽입

redis2는 redis1의 슬레이브 백업 redis이며 redis의 변경 사항은 백업을 위해 redis2에 동기화됩니다.
그러나 당사자 redis1이 중단되면 응용 프로그램 서버가 자동으로 redis2에서 서비스를 요청해야하지만 동시 환경이 너무 복잡하기 때문에 응용 프로그램 서버가 redis2가 다운 된 것으로 인식하기 어렵습니다. 따라서 센티넬 모드입니다.

처음 사용할 때 응용 프로그램 서버는 먼저 redis를 사용해야하는 센티넬을 요청하고, 센티넬이 응답하고 알리면 응용 프로그램 서버가 redis를 요청합니다.
센티넬 도구는 redis로 하트 비트 메커니즘을 설정합니다. 하트 비트의 연결이 끊어지는 모든 상황에서 센티넬은이를 redis1의 실패로 간주합니다. redis2를 마스터로, redis1을 슬레이브로 변경하는 명령을 보내고 애플리케이션 서버에 변경을 알립니다 (아래 그림 참조).

image.png

3. 클러스터 클러스터 모드

센티넬 모드의 단점도 분명하며, 동시에 하나의 redis만이 외부 세계에 서비스를 제공합니다.
클러스터 전에 조각화 및 읽기-쓰기 분리를 사용하십시오.
여기에 사진 설명 삽입

그러나 redis5가 추가되면 다양하고 복잡한 데이터 마이그레이션이 필요합니다. 확장 성은 여전히 ​​좋지 않습니다.
따라서 클러스터 모드가 나타났습니다 :
redis 2 읽기 및 2 쓰기. 그리고 자동으로 마스터와 슬레이브를 선택합니다. 그리고 모든 redis는 모든 관계를 알고 있습니다. 그리고이 관계형 라우팅 테이블을 응용 프로그램 서버로 보내면 응용 프로그램 서버가 자체 메모리에 조각화 정보를 유지합니다.
redis3가 실패하면 상태가 Parker 메커니즘을 통해 자동으로 재배포되고 해시 조각이 자동으로 재조정됩니다.
그러나 애플리케이션 서버에는 여전히 잘못된 조각 라우팅 목록이 있습니다. 애플리케이션 서버가 오류 목록에 따라 redis2가 요청한 일부 데이터를 찾으면 redis2는 서버가 요청한 키가 조정 후 관리 범주에 속하지 않음을 발견하고 서버가 다시 끌어 올 수 있도록 서버에 reask 요청을 반환합니다. 최신 조각 라우팅 테이블.
여기에 사진 설명 삽입
image.png
이 세 가지 모델이 jedis실현 되었습니다 .

넷째, Redis 중앙 집중식 캐시 제품 세부 정보 페이지

컨트롤러 계층에서 자세한 정보가 캐시되고 다운 스트림 서비스 호출이 수행되지 않습니다. 데이터베이스에 대한 의존도를 줄입니다.
image.png

그러나 redis 자체에 의해 직렬화 된 후 왜곡 된 코드
여기에 사진 설명 삽입

읽기 쉽도록 기본 키 값 직렬화 방법이 변경되었습니다.
image.png

다섯, 로컬 핫스팟 캐시

즉, JVM 서버의 로컬

  • 핫 데이터
  • 더티 읽기는 매우 민감하지 않습니다. 데이터베이스가 변경되면 많은 더티 캐시 데이터가 알지 못하는 사이에 읽 힙니다.

MQ를 통해 업데이트 할 수 있지만 이득이 손실보다 큽니다.

  • 기억은 통제 가능하고 소중합니다.

즉각적인 액세스로만 캐시의 유효 시간이 매우 짧습니다.

동시 읽기 및 쓰기를 지원해야합니다. 간단한 해시 맵은 만족할 수 없습니다. LRU와 같은 전략으로도 제거 할 수 있으며 KEY는 시간에 따라 자동으로 무효화됩니다.

이루다:

구아바 캐시

  • 크기 및 시간 제한 만 제어 가능
  • 구성 가능한 lru 전략
  • 스레드 안전

image.png

@Service
public class CacheServiceImpl implements CacheService {
    
    

    private Cache<String,Object> commonCache = null;

    @PostConstruct
    public void init(){
    
    
        commonCache = CacheBuilder.newBuilder()
                //设置缓存容器的初始容量为10
                .initialCapacity(10)
                //设置缓存中最大可以存储100个KEY,超过100个之后会按照LRU的策略移除缓存项
                .maximumSize(100)
                //设置写缓存后多少秒过期
                .expireAfterWrite(60, TimeUnit.SECONDS).build();
    }

    @Override
    public void setCommonCache(String key, Object value) {
    
    
            commonCache.put(key,value);
    }

    @Override
    public Object getFromCommonCache(String key) {
    
    
        return commonCache.getIfPresent(key);
    }
}

1000TPS를 늘리십시오.

六 、 Nginx 프록시 캐치

  • 프록시 캐치는 nginx 역방향 프록시가 사전 활성화 된 경우에만 사용할 수 있습니다.
  • 캐시 작업을 완료하려면 파일 시스템의 인덱스 수준에있는 파일을 사용합니다.
  • 메모리를 사용하여 파일 주소를 캐시합니다.

그러나 메모리가 아닌 로컬 디스크 시스템에 캐시를 저장하기 때문에 QPS가 크게 개선되지 않았으며 jvm 로컬 캐시의 성능보다 훨씬 낮습니다. 평균 지연이 더 깁니다.

일곱, Nginx Lua 원리

  • 루아 코 루틴 메커니즘

스레드 우주 정거장에서 사용자 시뮬레이션에 따라 스레드에 의존

  • Nginx 코 루틴 메커니즘

비동기 프로그래밍 모델을 고려할 필요가 없습니다.

  • nginx lua 플러그인 포인트
  • OpenResty

1. 코 루틴 메커니즘

  • 스레드 메모리 모델에 따라 낮은 스위칭 오버 헤드
  • 막힌 경우 실행 권한이 제 시간에 반환되고 코드가 동기화됩니다.
  • 잠글 필요 없음

image.png

2. Nginx 코 루틴

  • nginx의 각 작업자 프로세스는 epoll 또는 kqueue의 이벤트 모델 위에 코 루틴으로 캡슐화됩니다.

언제

  • 모든 요청은 코 루틴에 의해 처리됩니다.
  • ngx_lua가 lua를 실행하더라도 c에 비해 특정 오버 헤드가 있지만 여전히 높은 동시성을 보장 할 수 있습니다.

3. Nginx 코 루틴 메커니즘

  • nginx의 각 작업자 프로세스는 lua 가상 머신을 생성합니다. lua 파일을 실행하는 데 사용
  • 작업자 프로세스의 모든 코 루틴은 동일한 VM을 공유합니다.
  • 각 외부 요청은 루아 코 루틴에 의해 처리되며 데이터는 서로 격리됩니다.
  • lua 코드가 io와 같은 비동기 인터페이스를 호출하면 코 루틴이 일시 중단되고 컨텍스트 데이터는 변경되지 않습니다.
  • 작업 프로세스를 차단하지 않고 자동 저장
  • io 비동기 작업이 완료된 후 코 루틴 컨텍스트가 복원되고 코드가 계속 실행됩니다. 즉, 코드는 상대적으로 간단한 동기 프로그래밍입니다.

즉, HTTP 요청을 수신 한 후이를 처리하기 위해 Lua 코 루틴이 할당되지만, 역방향 프록시가 백엔드 서버가 데이터를 반환 할 때까지 기다려야하는 경우 (예 : 소켓 핸들을 epoll 청취 대기열에 넣고 스스로 매달려 있습니다. 다른 코 루틴을 계속 실행합니다. 백엔드 서버가 반환되면 epoll이 수신 대기 한 다음 코 루틴이 깨어나 후속 응답 작업을 처리합니다.
이러한 이유로 각 코 루틴 간의 데이터는 격리됩니다.
Nginx는 워커는 스레드이며 그 아래에는 많은 코 루틴이 있습니다. 직렬 처리는 전적으로 코 루틴을 기반으로합니다.
자바 서블릿이 http 요청을 처리하면 요청이되고이를 처리하기 위해 스레드가 할당됩니다.

4. Nginx 처리 단계

여기에 사진 설명 삽입

5. Nginx lua 마운트 지점

여기에 사진 설명 삽입

여기에 사진 설명 삽입

6.OpenResty

  • Nginx의 이벤트 기반 모델과 비 차단 IO의 도움으로 고성능 웹 애플리케이션을 구현할 수 있습니다.
  • nginx에서 웹 애플리케이션을보다 쉽게 ​​개발할 수 있도록 Mysql, redis, memcache 등과 같은 많은 구성 요소가 제공됩니다.

(1) 헬로 월드

image.png
즉, helloworld를 방문하면 / item / get? id = 6을 방문한 결과가 반환됩니다.

(2) 공유 dic

모든 작업자 프로세스에 표시되는 공유 메모리 사전

guaua catch와 유사한 메모리 사전, lru 제거 지원

그러나 메모리 제한이 있습니다.
그래서

(3) Openresty redis 지원

Nginx는 공유 dic보다 redis에서 읽는 것이 확실히 느립니다.
여기에 사진 설명 삽입

nginx에서 업데이트 메커니즘이 생략되어 다운 스트림 애플리케이션 서버가 업데이트 될 수 있으며 nginx는 읽기 전용이며 쓰기가 불가능합니다.
Nginx는 실시간으로 redis의 데이터를 인식하고 더티 읽기를 방지 할 수 있습니다.
여기에 사진 설명 삽입

따라서 nginx는 자체 메모리 캐시에만 핫 데이터를 저장할 수 있으며 핫 데이터가 아닌 데이터는 redis 슬레이브를 읽습니다.

8. 요약

업스트림에 가까울수록 캐시가 차지하는 시스템 리소스가 더 비싸고 해당 업데이트 메커니즘이 더 어려워지고 성능이 높아집니다.
따라서 통합 된 일반 캐싱 체계가 없으며 실제 비즈니스 시나리오에 따라 동적 요청에 대한 캐싱 체계, 더티 읽기 허용 정도, 핫 데이터 정도를 결정해야합니다.

추천

출처blog.csdn.net/xiaohaigary/article/details/108010966