Linux 커널에는 Noop IO 스케줄러, 예상 IO 스케줄러, Deadline IO 스케줄러, CFQ IO 스케줄러 등 4가지 유형의 IO 스케줄러가 포함되어 있습니다.
일반적으로 디스크 읽기 및 쓰기 지연은 헤드가 실린더로 이동하여 발생합니다. 이러한 지연을 해결하기 위해 커널은 주로 캐싱 및 IO 스케줄링 알고리즘이라는 두 가지 전략을 채택합니다.
IO 스케줄러(IO 스케줄러)는 운영 체제에서 블록 장치에 대한 IO 작업 제출 순서를 결정하는 데 사용되는 방법입니다. 존재 목적은 두 가지가 있습니다. 하나는 IO 처리량을 향상시키는 것이고, 다른 하나는 IO 응답 시간을 줄이는 것입니다.
그러나 IO 처리량과 IO 응답 시간은 종종 모순됩니다. 두 가지의 균형을 최대한 맞추기 위해 IO 스케줄러는 다양한 IO 요청 시나리오에 적응할 수 있는 다양한 예약 알고리즘을 제공합니다. 그 중 데이터베이스와 같은 임의 읽기 및 쓰기 시나리오에 가장 유용한 알고리즘은 DEANLINE입니다.
커널 스택에서 IO 스케줄러의 위치는 다음과 같습니다.
블록 장치에서 가장 비극적인 점은 디스크 회전인데, 이는 매우 시간이 많이 걸리는 프로세스입니다. 각 블록 장치 또는 블록 장치의 파티션은 자체 요청 대기열(request_queue)에 해당하며, 각 요청 대기열은 제출된 요청을 조정하기 위해 I/O 스케줄러를 선택할 수 있습니다.
I/O 스케줄러의 기본 목적은 블록 장치의 해당 섹터 번호에 따라 요청을 정렬하여 헤드 이동을 줄이고 효율성을 높이는 것입니다. 각 장치의 요청 대기열에 있는 요청은 순서대로 응답됩니다.
실제로 이 대기열 외에도 각 스케줄러 자체는 제출된 요청을 처리하기 위해 서로 다른 수의 대기열을 유지하며 대기열 상단에 있는 요청은 응답을 기다리기 위해 적절한 과정에서 요청 대기열로 이동됩니다.
IO 스케줄러의 주요 기능은 디스크 회전의 필요성을 줄이는 것입니다. 주로 2가지 방법을 통해 달성됩니다:
각 장치에는 해당 요청 대기열이 있으며 모든 요청은 처리되기 전에 요청 대기열에 있습니다. 새로운 요청이 올 때 이 요청의 위치가 이전 요청과 인접한 것으로 확인되면 하나의 요청으로 병합될 수 있습니다.
병합된 것을 찾을 수 없는 경우 디스크 회전 방향에 따라 정렬됩니다. 일반적으로 IO 스케줄러의 역할은 단일 요청의 처리 시간에 큰 영향을 주지 않고 병합하고 정렬하는 것입니다.
FIFO
입력 및 출력 요청을 FIFO 대기열에 넣은 다음 대기열에 있는 입력 및 출력 요청을 순서대로 실행합니다. 새 요청이 올 때:
병합이 가능하다면 병합하세요
병합할 수 없는 경우 정렬을 시도합니다. 대기열의 요청이 이미 매우 오래된 경우 이 새 요청은 대기열로 이동할 수 없으며 끝에만 배치될 수 있습니다. 그렇지 않으면 적절한 위치에 삽입하세요
병합이 불가능하고 삽입하기에 적합한 위치가 없는 경우 요청 대기열의 마지막에 배치됩니다.
적용 가능한 시나리오
4.1 입력 및 출력 요청 순서를 수정하고 싶지 않은 경우
4.2 NAS 저장 장치와 같이 입력 및 출력에 보다 지능적인 스케줄링 알고리즘을 갖춘 장치
4.3 상위 계층 애플리케이션의 입력 및 출력 요청이 신중하게 최적화되었습니다.
4.4 SSD 디스크와 같은 비회전 헤드 디스크 장치BE(최선을 다해)
유휴(idle)
“
FIFO(읽기) > FIFO(쓰기) > CFQ”
마감일 알고리즘은 주어진 IO 요청에 대한 최소 지연 시간을 보장하므로 DSS 애플리케이션에 매우 적합합니다.
마감일은 실제로 Elevator의 개선 사항입니다:
1. 너무 오랫동안 처리할 수 없는 요청은 피하세요.
2. 읽기 작업과 쓰기 작업을 구별합니다.
deadline IO는 3개의 대기열을 유지합니다. 첫 번째 대기열은 Elevator와 동일하며 물리적 위치에 따라 정렬하려고 합니다. 두 번째 큐와 세 번째 큐는 모두 시간별로 정렬되어 있는데, 차이점은 하나는 읽기 작업이고 다른 하나는 쓰기 작업입니다.
Deadline IO는 읽기와 쓰기를 구분합니다. 디자이너는 애플리케이션이 읽기 요청을 보내면 일반적으로 거기서 차단되고 결과가 반환될 때까지 기다릴 것이라고 믿기 때문입니다. 쓰기 요청은 일반적으로 메모리에 쓰기 위한 애플리케이션 요청이 아니며, 백그라운드 프로세스가 이를 디스크에 다시 씁니다. 응용프로그램은 일반적으로 쓰기가 완료될 때까지 기다리지 않고 계속합니다. 따라서 읽기 요청은 쓰기 요청보다 우선순위가 높아야 합니다.
이 설계에서는 각각의 새로운 요청이 첫 번째 대기열에 먼저 배치됩니다. 알고리즘은 Elevator의 알고리즘과 동일하며 읽기 또는 쓰기 대기열의 끝에 추가됩니다. 이런 방식으로 우리는 먼저 첫 번째 대기열의 일부 요청을 처리하고 동시에 두 번째/세 번째 대기열의 처음 몇 요청이 너무 오랫동안 대기했는지 여부를 감지하여 임계값을 초과한 경우 처리됩니다. 이 임계값은 읽기 요청의 경우 5ms, 쓰기 요청의 경우 5초입니다.
개인적으로는 Oracle의 온라인 로그, MySQL의 binlog 등 데이터베이스 변경 로그를 기록하는 데 이런 파티션을 사용하지 않는 것이 가장 좋다고 생각합니다. 이러한 유형의 쓰기 요청은 일반적으로 fsync를 호출하기 때문입니다. 작성을 완료할 수 없는 경우에도 응용 프로그램 성능에 큰 영향을 미칩니다.
CFQ 및 DEADLINE은 분산된 IO 요청을 충족하는 데 중점을 둡니다. 순차 읽기와 같은 지속적인 IO 요청의 경우 최적화가 없습니다.
혼합 무작위 IO 및 순차 IO 시나리오를 충족하기 위해 Linux는 ANTICIPATORY 스케줄링 알고리즘도 지원합니다. DEADLINE을 기준으로 ANTICIPATORY는 각 읽기 IO에 대해 6ms의 대기 시간 창을 설정합니다. OS가 이 6ms 내에 인접한 위치로부터 읽기 IO 요청을 받으면 즉시 만족할 수 있습니다.
IO 스케줄러 알고리즘의 선택은 하드웨어 특성과 애플리케이션 시나리오에 따라 달라집니다.
기존 SAS 디스크에서는 CFQ, DEADLINE 및 ANTICIPATORY가 모두 전용 데이터베이스 서버에 적합하며 DEADLINE은 처리량 및 응답 시간 측면에서 좋은 성능을 발휘합니다.
그러나 SSD 및 Fusion IO와 같은 새로운 솔리드 스테이트 드라이브에서는 가장 간단한 NOOP가 최고의 알고리즘이 될 수 있습니다. 왜냐하면 다른 세 가지 알고리즘의 최적화는 검색 시간 단축을 기반으로 하고 솔리드 스테이트 드라이브에는 그렇지 않기 때문입니다. 탐색 시간이라고 하며 IO 응답 시간이 매우 짧습니다.
위 내용은 하나의 기사로 Linux 커널의 네 가지 주요 IO 스케줄링 알고리즘을 이해하세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!