높은 동시성에서 Redis 성능 분석 정보

王林
풀어 주다: 2021-03-08 09:31:52
앞으로
1945명이 탐색했습니다.

높은 동시성에서 Redis 성능 분석 정보

머리말:

저는 최근에 프로젝트를 시작했고, 프로젝트의 건축 설계와 구현을 담당했습니다. 원래 회사에서는 외부인을 위한 API를 많이 만들었으나 외부인이 사용하게 되면 인터페이스 링크가 다른 사람에게 주어지게 되는데, 인터페이스 프로그램이 있는 머신에는 암호화나 동시성 제어가 되지 않습니다. IP는 존재하지만 이를 관리할 플랫폼은 없습니다. 그러므로 이러한 인터페이스의 가치(어떤 인터페이스가 다른 사람들이 더 많이 사용하고, 어떤 인터페이스가 덜 사용되는지)를 발견하기 어렵다는 것을 나는 분명히 알고 있습니다.

"모니터링"이 필요한 경우에만 Redis를 중간 계층으로 도입했습니다. 먼저 사용자 인터페이스의 등록 프로세스를 개선하고 사용자 정보와 주소를 통해 키를 해시했습니다. Redis에서는 이 (키-주소) 쌍을 사용합니다. 다음은 nginx입니다. 우리 프로젝트의 nginx 프로세스는 대략 다음과 같습니다.

1. 사용자가 등록한 후 키를 얻고 원래 URL과 완전히 다른 키가 포함된 URL을 통해 액세스합니다. 2. nginx 캡처 사용자의 특수 키에 대해 프로그램은 이 키를 기반으로 redis에서 대상 주소를 검색한 다음 nginx가 사용자를 대신하여 실제 주소에 액세스한 다음 반환합니다.

(이 프로세스의 이점은 많습니다)

(1). 프로그램은 보안을 강화하기 위해 사용자의 액세스에 개입할 수 있습니다

(2) ), 사용자 정보를 가져와 다시 Redis에 저장합니다. Redis에 저장된 로그를 타이머 프로그램을 통해 oracle에 유지한 다음 이를 추가로 분석하고 시각화합니다. 테스트 단계에서 리소스는 window 서버와 centos6.5 서버입니다. 테스트 단계에서는 배포 후 처음 1~2일 동안은 약 100,000개의 동시성이 발생했지만 그 이후에는 redis 연결이 발생했습니다. 실패했습니다. 프로세스 접근을 보면 다음과 같은 상황이 나타난다. (윈도우 서버 아래)

FiN_WAIT_2 TCP 링크가 많습니다.

(학습 영상 공유:

redis 영상 튜토리얼높은 동시성에서 Redis 성능 분석 정보)

Analytics

1. Redis는 단일 스레드를 사용하여 연결을 처리하는데, 이는 아래 두 번째 단계에서 언급된 상황을 확실히 경험하게 된다는 것을 의미합니다. 2. 분명히 이는 nginx와 redis 사이에 출시되지 않은 많은 리소스로 인해 발생합니다. TCP 상태 FIN_WAIT_2를 확인하고 설명하세요.

HTTP 애플리케이션에서 다음과 같은 문제로 인해 서버가 닫혀 있습니다. KEEPALIVE의 시간 초과는 적극적으로 닫힌 SERVER로 FIN_WAIT2 상태로 들어갑니다. 그러나 FIN_WAIT2 상태에는 TIME_WAIT 상태와 달리 시간 초과가 없으므로 CLIENT는 그렇지 않습니다. 닫히지 않으면 이 FIN_WAIT_2 상태는 시스템이 다시 시작될 때까지 유지되며 점점 더 많은 FIN_WAIT_2 상태로 인해 커널이 충돌하게 됩니다.

알겠습니다. 대학에서 공부를 잘 못했어요. http 연결 상태 변경은 다음과 같습니다

클라이언트 상태 마이그레이션

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT ->CLOSEDb .

서버 상태 마이그레이션

CLOSED->LISTEN->SYN 수신됨->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

지속적인 연결이 있는 불법 클라이언트

몇 가지가 있습니다. 클라이언트 지속적인 연결(akakeepalives)을 처리하는 데 문제가 있습니다. 연결이 유휴 상태가 되고 서버가 연결을 닫으면(KeepAliveTimeout 지시문에 따라) 클라이언트는 FIN 및 ACK를 서버로 다시 보내지 않도록 프로그래밍됩니다. 이는 다음 중 하나가 발생할 때까지 연결이 FIN_WAIT_2 상태로 유지됨을 의미합니다.

클라이언트가 동일하거나 다른 사이트에 대한 새 연결을 열면 해당 소켓의 이전 연결이 완전히 닫힙니다.

사용자가 클라이언트 프로그램을 종료하면 일부(아마도 대부분?) 클라이언트에서 운영 체제가 연결을 완전히 닫게 됩니다.

FIN_WAIT_2 시간 초과, FIN_WAIT_2 상태 시간 초과가 설정된 서버에서.

운이 좋으면 결함이 있는 클라이언트가 연결을 완전히 닫고 서버 리소스를 확보할 수 있다는 의미입니다.

그러나 전화 접속 클라이언트가 클라이언트 프로그램을 닫기 전에 ISP와의 연결을 끊는 등 소켓이 완전히 닫히지 않는 경우가 있습니다.

또한 일부 클라이언트는 새 연결을 만들지 않고 며칠 동안 유휴 상태일 수 있으므로 더 이상 사용하지 않더라도 소켓을 며칠 동안 유효하게 유지합니다. 이는 브라우저나 운영 체제의 TCP 구현에 있는 버그입니다.

이유는 다음과 같습니다.

1. 연결이 항상 유휴 상태이고 SERVERCLOSE가 발생하는 경우 CLIENT 프로그래밍 결함으로 인해 FIN 및 ACK 패킷이 SERVER

2로 전송되지 않습니다. APACHE1.1에는 linger_close가 추가되었습니다. (( ) 함수는 이전 포스팅에서 소개한 함수인데, 이 함수가 이런 문제를 일으켰을 수도 있습니다(이유는 모르겠습니다)

 해결책:

1. FIN_WAIT_2 상태에 시간 초과 메커니즘을 추가합니다. 이 기능은 프로토콜에 반영되지 않지만 LINUX, SOLARIS, FREEBSD, HP-UNIX, IRIX 등과 같은 일부 OS

에서 구현되었습니다.

2. linger_close()로 컴파일하지 마세요

3. 대신 SO_LINGER를 사용하세요. 이는 일부 시스템에서 잘 처리될 수 있습니다

4. 커널 충돌을 방지하기 위해 네트워크 연결 상태를 저장하는 데 사용되는 메모리 mbuf를 늘립니다.

5. DISABLE KEEPALIVE

이 상황을 고려하여 여러 가지 논의를 거쳐 몇 가지 결론을 내렸습니다.

1 nginx와 redis의 연결 풀을 설정하고 keepalive 시간을 각각 10초와 5초로 설정했지만 결과는 다음과 같습니다. still Same

2. keepalive가 없다는 것, 즉 커넥션 풀이 없다는 것, 즉 사용할 때마다 close()를 하는 것을 보면 커넥션 풀을 사용하지 않는다는 것은 커넥션 풀을 열어야 한다는 뜻이다. 10초에 100,000번 닫히면 오버헤드가 너무 높음

3. Redis 클러스터, 원래 클러스터 시스템에 Redis 클러스터를 추가하면 문제가 해결될 수 있지만 실제로는 10초에 100,000번이 큰 문제가 아닐 수 있습니다. , 찾을 수 없습니다. Question

4. Redis의 유휴 시간 제한을 설정해도 결과는 동일합니다.

해결책:

사실 해결책은 아닙니다. 왜냐하면 redis의 메모리 메커니즘을 포기하고 nginx 자체의 메모리 기술을 사용하기 때문입니다. Redis의 온라인 최적화 대부분은 적용 가능하지 않으며 이 문제는 분석 및 해결이 필요합니다.

관련 권장 사항: redis 데이터베이스 튜토리얼

위 내용은 높은 동시성에서 Redis 성능 분석 정보의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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