nginx 학습 의 epoll
6583 단어 Nginx
예 를 들 어 100 만 명의 사용자 가 한 프로 세 스 와 동시에 TCP 연결 을 유지 하고 매 순간 몇 십 개 또는 몇 백 개의 tcp 연결 만 활발 하 다 면 (즉, TCP 패 키 지 를 받 을 수 있다) 매 순간 프로 세 스 는 이 100 만 개의 연결 중 일부분 만 처리 해 야 합 니 다.
select 와 poll 은 이렇게 처리 합 니 다. 어느 순간 프로 세 스 가 모든 연결 을 수집 합 니 다. 사실 이 100 만 연결 중 대부분 시간 이 없습니다.따라서 이 벤트 를 수집 할 때마다 100 만 개의 연 결 된 소켓 을 운영 체제 에 전송 한다 면 (이것 은 우선 사용자 상태 메모리 에서 커 널 메모리 로 의 대량 복사) 운영 체제 커 널 에서 이 링크 에 처리 되 지 않 은 이 벤트 를 찾 는 것 은 큰 낭비 가 될 것 이다.
epoll 은 이렇게 합 니 다. epoll 은 select 와 poll 을 두 부분 으로 나 누 었 습 니 다.
1 、 epoll 호출creat 에서 epoll 대상 을 만 듭 니 다.
2, epoll 호출ctl 은 epoll 대상 에 100 만 개의 연결 소켓 을 추가 합 니 다.
3 、 epoll 호출wait 이벤트 가 발생 한 연결 을 수집 합 니 다. =포 인 트 는 여기 있 습 니 다. epoll 호출wait 는 발생 하 는 모든 이벤트 의 연결 을 수집 하고 이 벤트 를 하나의 링크 에 넣 습 니 다. 이 링크 에서 100 만 개의 연결 을 옮 겨 다 니 지 않 고 연 결 된 이 벤트 를 찾 아야 합 니 다!이렇게 실제 사건 을 수집 할 때 epollwait 효율 이 높 을 겁 니 다.
세 시스템 호출 함 수 는 모두 C 로 포장 되 어 있 으 며, P310 에서 함수 에 의 해 상세 하 게 설명 되 어 있 으 며, 다음은 간단하게 소개 합 니 다.
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
우선 epoll 호출create 에서 epoll 대상 을 만 듭 니 다.매개 변수 size 는 커 널 이 정확하게 처리 할 수 있 는 최대 문형 수 입 니 다. 이 최대 수 보다 많 을 때 커 널 은 효 과 를 보장 하지 않 습 니 다.
epoll_ctl 은 위 에 세 워 진 epoll 을 조작 할 수 있 습 니 다. 예 를 들 어 방금 만 든 socket 을 epoll 에 추가 하여 모니터링 하거나 epoll 이 모니터링 하고 있 는 어떤 socket 핸들 을 epoll 에서 옮 기 고 더 이상 모니터링 하지 않 는 등 입 니 다.
epoll_wait 호출 시 주어진 timeout 시간 내 에 모니터링 하 는 모든 핸들 에서 이벤트 가 발생 하면 사용자 상태 로 돌아 갑 니 다.
그렇다면 epoll 은 어떻게 이런 생각 을 이 루 었 을 까?
어떤 프로 세 스 가 epoll 을 호출 할 때creat 방법 을 사용 할 때 Liux 커 널 은 이벤트 poll 구조 체 를 만 듭 니 다. 이 구조 체 에는 두 구성원 의 사용 이 epoll 의 사용 방식 과 밀접 한 관 계 를 가지 고 있 습 니 다.
struct eventpoll {
// , epoll , epoll 。
struct rb_root rbr;
// rdllist epoll_wait 、 。
struct list_head rdllist;
}
epoll 왜 이렇게 효율 적 입 니까?
우리 가 epoll 을 호출 할 때ctl 에 백만 개의 핸들 을 넣 었 을 때 epollwait 는 여전히 빠르게 돌아 갈 수 있 으 며, 이벤트 가 발생 한 핸들 을 사용자 에 게 효과적으로 줄 수 있 습 니 다.이것 은 우리 가 epoll 를 호출 하고 있 기 때문이다.create 시 커 널 은 epoll 파일 시스템 에 file 노드 를 만 드 는 것 을 제외 하고 커 널 cache 에 빨 간 검 은 나 무 를 만들어 서 나중에 epoll 을 저장 합 니 다.ctl 에서 들 려 오 는 socket 외 에 list 링크 를 하나 더 만들어 준 비 된 이 벤트 를 저장 합 니 다. epollwait 호출 시 이 list 링크 에 데이터 가 있 는 지 관찰 하면 됩 니 다.데이터 가 있 으 면 되 돌아 오고 데이터 가 없 으 면 sleep 입 니 다. timeout 시간 이 되면 링크 에 데이터 가 없어 도 되 돌아 갑 니 다.그래서 epollwait 는 매우 효율 적 입 니 다.
그리고 통상 적 으로 우리 가 백만 계 의 핸들 을 감시 해 야 하 더 라 도 대부분 한 번 에 아주 적은 양의 준비 완료 핸들 만 되 돌려 주기 때문에 epollwait 는 커 널 상태 copy 의 소량의 구문 에서 사용자 상태 까지 만 필요 합 니 다. 어떻게 효율 적 이지 않 을 수 있 습 니까?!
그럼 이 준비 완료 list 링크 는 어떻게 유지 되 나 요?우리 가 epoll 을 실행 할 때ctl 에 서 는 epoll 파일 시스템 에 있 는 file 대상 에 대응 하 는 빨 간 검 은 트 리 에 socket 을 올 리 는 것 외 에 커 널 인 터 럽 트 처리 프로그램 에 리 셋 함 수 를 등록 하여 커 널 에 알려 줍 니 다. 이 핸들 이 중단 되면 준비 완료 list 링크 에 넣 으 라 고 합 니 다.그래서 하나의 socket 에 데이터 가 도착 하면 커 널 은 네트워크 카드 의 데 이 터 를 커 널 에 복사 한 후에 socket 을 준비 링크 에 삽입 합 니 다.
이렇게 해서 빨 간 검 은 나무 하나, 준비 되 어 있 는 문형 링크 하나, 소량의 커 널 cache 는 우리 에 게 크 고 보 내 는 socket 처리 문 제 를 해결 해 주 었 다.실행 epollcreate 시, 붉 은 검 은 나무 와 준비 링크 를 만 들 고 epoll 을 실행 합 니 다.ctl 시 socket 핸들 을 추가 하면 빨간색 과 검은색 트 리 에 존재 하 는 지 확인 하고 즉시 되 돌아 오 며 존재 하지 않 으 면 트 리 에 추가 한 다음 커 널 에 리 셋 함 수 를 등록 하여 인 터 럽 트 이벤트 가 발생 했 을 때 준비 되 어 있 는 링크 에 데 이 터 를 삽입 합 니 다.실행 epollwait 시 준 비 된 링크 의 데 이 터 를 즉시 되 돌려 주면 됩 니 다.
마지막 으로 epoll 만 의 두 가지 모델 인 LT 와 ET 를 살 펴 보 자.LT 와 ET 모드 를 막론하고 위 에서 말 한 절차 에 적용 된다.차이 점 은 LT 모드 에서 하나의 핸들 에 있 는 사건 이 한 번 에 처리 되 지 않 으 면 나중에 epoll 을 호출 합 니 다.wait 시 이 핸들 을 되 돌려 줍 니 다. ET 모드 는 첫 번 째 로 되 돌아 갑 니 다.
이 일 을 어떻게 했 지?socket 핸들 에 이벤트 가 있 을 때 커 널 은 이 핸들 을 위 에서 말 한 준비 완료 list 링크 에 삽입 합 니 다. 이때 우 리 는 epoll 을 호출 합 니 다.wait, 준 비 된 socket 을 사용자 상태 메모리 에 복사 한 다음 준 비 된 list 링크 를 비 웁 니 다. 마지막 으로 epollwait 가 한 가지 일 을 했 습 니 다. 이 socket 을 검사 하 는 것 입 니 다. ET 모드 (LT 모드 의 핸들 입 니 다) 가 아니라면 이 socket 에 처리 되 지 않 은 이벤트 가 있 을 때 이 핸들 을 방금 비 운 준비 링크 로 돌려 놓 았 습 니 다.그래서 ET 의 문형 이 아 닙 니 다. 그 위 에 사건 이 있다 면 epollwait 는 매번 돌아온다.ET 모드 의 핸들 은 새로 중단 되 지 않 는 한 socket 의 이벤트 가 처리 되 지 않 았 더 라 도 epoll 에서 두 번 다시 중단 되 지 않 습 니 다.wait 에서 돌 아 왔 습 니 다.
epoll 의 장점:
1. 프로 세 스 가 많은 소켓 설명 자 를 여 는 것 을 지원 합 니 다 (FD)
select 가장 참 을 수 없 는 것 은 프로 세 스 가 열 린 FD 에 일정한 제한 이 있 습 니 다. FDSETSIZE 설정, 기본 값 은 2048 입 니 다.지원 해 야 할 수만 개의 연결 수 를 가 진 IM 서버 로 서 는 너무 적다.이 럴 때 첫째, 이 매크로 를 수정 한 다음 에 커 널 을 다시 컴 파일 할 수 있 지만 자 료 는 네트워크 효율 이 떨 어 질 것 이 라 고 지적 했다. 둘째, 다 중 프로 세 스 의 해결 방안 (전통 적 인 것) 을 선택 할 수 있다. Apache 프로젝트) 그러나 Liux 에서 프로 세 스 를 만 드 는 대가 가 비교적 적 지만 무시 할 수 없 는 것 입 니 다. 게다가 프로 세 스 간 데이터 동기 화 는 온라인 동기 화 보다 훨씬 효율 적 이기 때문에 완벽 한 방안 도 아 닙 니 다.... 에 불과 하 다 epoll 은 이 제한 이 없습니다. 지원 하 는 FD 상한 선 은 파일 을 열 수 있 는 최대 수 입 니 다. 이 숫자 는 보통 2048 보다 훨씬 큽 니 다. 예 를 들 어 1GB 메모리 의 기계 에 서 는 약 10 만 정도 입 니 다. 구체 적 인 수 는 cat / proc / sys / fs / file - max 에서 볼 수 있 습 니 다. 일반적으로 이 수 는 시스템 메모리 와 관계 가 매우 큽 니 다.
2. IO 효율 은 FD 수량 증가 에 따라 선형 으로 떨어진다.
전통 적 인 select / poll 의 또 다른 치 명 적 인 약점 은 당신 이 매우 큰 socket 집합 을 가지 고 있다 는 것 이다. 그러나 네트워크 지연 으로 인해 어느 시간 에 도 일부분 의 socket 만 '활발 하 다' 는 것 이다. 그러나 select / poll 은 호출 할 때마다 모든 집합 을 선형 으로 스 캔 하여 효율 이 선형 으로 떨어진다.그러나 epoll 은 이 문제 가 존재 하지 않 습 니 다. '활발 한' socket 만 조작 합 니 다. 이것 은 커 널 실현 에서 epoll 은 모든 fd 위의 callback 함수 에 따라 이 루어 지기 때 문 입 니 다.그러면 '활발 한' socket 만 이 주동 적 으로 호출 할 수 있 습 니 다. 콜백 함수, 기타 idle 상태 socket 은 할 수 없습니다. 이 점 에서 epoll 은 '위조' AIO 를 실 현 했 습 니 다. 이때 추진력 은 os 커 널 에 있 기 때 문 입 니 다.조금 benchmark 에서 모든 socket 이 기본적으로 활발 하 다 면 - 예 를 들 어 고속 LAN 환경, epoll 은 select / poll 보다 효율 적 이지 않 고, 반대로 epoll 을 너무 많이 사용 하면ctl, 효율 에 비해 약간 떨 어 집 니 다.그러나 idle connections 를 사용 하여 WAN 환경 을 모 의 하면 epoll 의 효율 은 select / poll 보다 훨씬 높다.
3. mmap 를 사용 하여 커 널 과 사용자 공간의 메시지 전달 을 가속 화 합 니 다.
이 점 은 사실상 epoll 의 구체 적 인 실현 과 관련 이 있다.select 든 poll 이 든 epoll 이 든 모두 커 널 이 FD 메 시 지 를 사용자 공간 에 알려 야 합 니 다. 불필요 한 메모리 복사 본 을 피 하 는 것 이 중요 합 니 다. 이 점 에서 epoll 은 커 널 을 통 해 사용자 공간 mmap 와 같은 메모리 로 이 루어 집 니 다.나 처럼 2.5 커 널 에서 epoll 에 관심 을 갖 고 싶다 면 수공 을 잊 지 않 을 것 이다. mmap 이번 엔
4. 커 널 미세 조정
이 점 은 사실 epoll 의 장점 이 아니 라 전체 Liux 플랫폼 의 장점 입 니 다.Liux 플랫폼 을 의심 할 수 있 지만 Liux 플랫폼 이 커 널 을 미세 조정 하 는 능력 을 부여 하 는 것 을 피 할 수 없습니다.예 를 들 어 커 널 TCP / IP 프로 토 콜 스 택 은 메모리 탱크 관리 sk 를 사용 합 니 다.buff 구조, 그러면 실행 시기 에 이 메모리 pool (skb head pool) 의 크기 를 동적 으로 조정 할 수 있 습 니 다. echo XXX > / proc / sys / net / core / hotlist_length 완성.예 를 들 어 listen 함수 의 두 번 째 매개 변수 (TCP 가 악 수 를 3 번 하 는 패 킷 대기 열 길이) 도 플랫폼 메모리 크기 에 따라 동적 으로 조정 할 수 있 습 니 다.심지어 하나의 패 킷 의 수량 이 많 지만 모든 패 킷 자체 의 크기 가 작은 특수 시스템 에서 최신 NAPI 네트워크 카드 구동 구 조 를 시도 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
linux2에 nginx 설치설치 가능한 nginx를 확인하고, 해당 nginx를 설치한다. localhost 혹은 해당 ip로 접속을 하면 nginx 화면을 볼 수 있다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.