6.4. 설정
먼저 결정해야 할 사항중 하나는 어떤 I/O 스케줄러를 사용하는가 하는 것입니다. 다음 부분에서는 워크로드에 가장 적합한 스케줄러를 결정할 수 있도록 각각의 주요 스케줄러에 대한 개요를 제공합니다.
6.4.1. CFQ (Completely Fair Queuing)
CFQ는 I/O를 시작한 프로세스에 따라 I/O 스케줄링 결정에 공정성을 제공합니다. 실시간 (RT), 최선형 (BE), 유휴라는 세 가지 다른 스케줄링 클래스가 있습니다. 스케줄링 클래스는
ionice
명령을 사용하여 수동으로 할당하거나 ioprio_set
시스템 호출을 통해 프로그램에 할당할 수 있습니다. 기본값으로 프로세스는 최선형 스케줄링 클래스에 배치됩니다. 실시간 및 최선형 스케줄링 클래스는 각 클래스 내에서 8 개의 I/O 우선 순위로 나뉘며 우선 순위 0은 가장 높은것이고 7은 가장 낮은것이 됩니다. 실시간 스케줄링 클래스에 있는 프로세스는 최선형이나 유휴 상태에 있는 프로세스 보다 적극적으로 스케줄되기 때문에 스케줄된 실시간 I/O는 항상 최선형이나 유휴 I/O 보다 먼저 실행됩니다. 즉 실시간 우선 순위의 I/O는 최선형과 유휴 클래스 모두를 실행할 필요 없게 할 수 있습니다. 최선형 스케줄링은 기본값 스케줄링 클래스로 이 클래스에 있는 기본값 우선 순위는 4입니다. 유휴 스케줄링 클래스에 있는 프로세스는 시스템에 실행되지 않는 다른 I/O가 없는 경우에만 실행됩니다. 즉 프로세스에서 I/O가 프로세스 진행에 전혀 필요하지 않은 경우에만 프로세스의 I/O 스케줄링 클래스를 유휴로 설정하는 것은 매우 중요합니다.
CFQ는 I/O를 실행하고 있는 각 프로세스에 타임 슬라이스를 할당하여 공정성을 제공합니다. 타임 슬라이스 동안 프로세스는 (기본값으로) 공중에서 최대 8 개의 요청을 동시에 받을 수 있습니다. 스케줄러는 기록 데이터를 기반으로 애플리케이션이 조만간 더 많은 I/O를 실행할 지에 대한 여부를 예측 시도합니다. 프로세스가 더 많은 I/O를 실행할 것으로 예상되면 다른 프로세스에서 I/O가 실행을 기다리고 있는 상태에서도 CFQ는 유휴 상태가 되어 I/O를 기다립니다.
CFQ에 의해 수행되는 유휴 상태로 인해 빠른 외장 스토리지 배열이나 솔리드 스테이드 디스크 등과 같은 대형 탐색 페널티에서 손상을 받지 않는 하드웨어에 적합하지 않을 경우가 많습니다. 이러한 스토리지에서 CFQ의 사용이 필요한 경우 (예: cgroup 비례 가중 I/O 스케줄러도 사용하고자 하는 경우), CFQ 성능을 개선하기 위해 일부 설정을 튜닝해야 합니다.
/sys/block/device/queue/iosched/
에 있는 동일한 이름의 파일에서 다음과 같은 매개 변수를 설정합니다:
slice_idle = 0 quantum = 64 group_idle = 1
group_idle
이 1로 설정된 경우에도 I/O 스톨 (백엔드 스토리지는 유휴 상태로 인해 사용 중이지 않음)의 가능성은 여전히 남아 있습니다. 하지만 이러한 스톨의 빈도는 시스템에 있는 각 큐의 유휴 상태보다 적습니다.
CFQ는 비작업 보존형 I/O 스케줄러로 이는 (위에서 설명한 대로) 보류 중인 요청이 있을 때에도 유휴 상태가 될 수 있다는 것을 의미합니다. 비작업 보존 스케줄러의 스택은 I/O 경로에 상당한 대기 시간을 도입할 수 있습니다. 이러한 스택의 예에는 호스트 기반 하드웨어 RAID 컨트롤러의 상단에 CFQ를 사용하는 것입니다. RAID 컨트롤러는 자신의 비작업 보존 스케줄러를 구현할 수 있습니다. 즉 이는 스택에서 두 가지 수준의 지연을 일으키는 원인이 될 수 있습니다. 비작업 보존 스케줄러는 결정의 기반이 되는 가능한 많은 데이터가 있을 때 가장 최선으로 작동합니다. 스케줄링 알고리즘과 같은 스택의 경우 가장 하단의 스케줄러는 상단의 스케줄러가 하단으로 보내는 것만 볼 수 있습니다. 따라서 하위 계층은 실제 워크로드와는 동떨어진 I/O 패턴을 보게 됩니다.
조정 가능한 매개 변수
back_seek_max
- 뒤로 검색은 헤드의 위치 변경에 있어 앞으로 검색보다 상당한 지연을 발생시킬 수 있으므로 일반적으로 성능이 나빠집니다. 하지만 뒤로 검색 크기가 크지 않은 경우 CFQ가 여전히 이를 실행합니다. 이러한 조정 가능한 매개 변수는 I/O 스케줄러가 뒤로 검색을 허용하는 최대 거리를 KB 단위로 제어합니다. 기본값은
16
KB입니다. back_seek_penalty
- 뒤로 검색의 비효율성으로 인해 각각에 패널티가 연결됩니다. 패널티는 승수로 예를 들어 1024KB의 디스크 헤드 위치를 생각해 봅시다. 큐에 두 개의 요청이 있다고 가정합니다. 하나는 1008KB이고 다른 하나는 1040KB입니다. 이러한 두 요청은 현재 헤드 위치에서 등거리에 있습니다. 하지만 뒤로 검색 패널티 (기본값: 2)를 적용하면 디스크에서 나중 위치에 있는 요청은 이전 요청의 위치보다 2배 가까운 거리에 있게 됩니다. 따라서 헤드가 앞으로 이동합니다.
fifo_expire_async
- 이러한 조정 가능한 매개 변수는 비동기 (버퍼링된 쓰기) 요청이 실행되지 않는 시간을 제어합니다. 만료 후 (밀리초 단위) 단일 비동기 요청은 디스패치 목록으로 이동합니다. 기본값은
250
밀리초입니다. fifo_expire_sync
- 이는 동기화 (읽기 및 O_DIRECT 쓰기) 요청의 fifo_expire_async 조정 가능한 매개 변수와 같습니다. 기본값은
125
밀리초입니다. group_idle
- 이것이 설정되면 CFQ는 cgroup에서 I/O를 실행하는 마지막 프로세스에서 유휴 상태가 됩니다. 비례 가중 I/O cgroup을 사용할 때 이를
1
로 설정하고slice_idle
을0
으로 (일반적으로 고속 스토리지에서 실행) 설정해야 합니다. group_isolation
- 그룹 분리(group isolation)가 활성화되어 있는 경우 (
1
로 설정) 이는 처리량을 대가로하여 그룹 간의 분리를 강화합니다. 일반적으로 그룹 분리가 비활성화되어 있는 경우 공정성은 연속 워크로드에만 제공됩니다. 그룹 분리를 활성화하면 연속 및 임의의 워크로드 모두에 공정성을 제공합니다. 기본값은0
(비활성화)입니다. 보다 자세한 내용은Documentation/cgroups/blkio-controller.txt
에서 참조하십시오. low_latency
- 낮은 대기 시간 (low latency)이 활성화되어 있는 경우 (
1
로 설정) CFQ는 장치에서 I/O를 실행하는 각 프로세스에 대해 최대 300 밀리초의 대기 시간을 제공하려 합니다. 이는 처리량 보다 공정성을 우선으로 합니다. 낮은 대기 시간을 비활성화하면 (0
으로 설정) 대상 대기 시간이 무시되고 시스템에 있는 각 프로세스는 전체 타임 슬라이스를 가져옵니다. 낮은 대기 시간은 기본값으로 활성화되어 있습니다. quantum
- quantum은 CFQ가 한번에 스토리지에 전송하는 I/O 수를 제어하고 실질적으로 장치 큐 깊이를 제한합니다. 기본값으로 이는
8
로 설정되어 있습니다. 스토리지는 더 깊은 큐 깊이를 지원할 수 있지만quantum
을 증가시키면 대기 시간에 부정적인 영향을 미치고 특히 대량의 연속 쓰기 워크로드가 있을 경우 더욱 그러합니다. slice_async
- 이러한 조정 가능한 매개 변수는 비동기 (버퍼링된 쓰기) I/O를 실행하는 각 프로세스에 할당된 타임 슬라이스를 제어합니다. 기본값으로 이는
40
밀리초로 설정되어 있습니다. slice_idle
- 이는 추가 요청을 기다리는 동안 CFQ가 유휴 상태가 될 시간을 지정합니다. Red Hat Enterprise Linux 6.1 및 이전 버전에서 기본값은
8
밀리초입니다. Red Hat Enterprise Linux 6.2 및 이후 버전에서 기본값은0
입니다. 값이 0일 경우 큐와 서비스 트리 레벨에 있는 모든 유휴 상태를 제거하므로 외부 RAID 스토리지 처리량이 향상됩니다. 하지만 이는 전체 검색 수를 증가시키기 때문에 내부의 비 RAID 스토리지 처리량을 저하시킬 수 있습니다. 비 RAID 스토리지의 경우slice_idle
값을 0 보다 크게 할 것을 권장합니다. slice_sync
- 이 매개 변수는 동기화 (읽기 또는 직접 쓰기) I/O를 실행하는 프로세스에 할당된 타임 슬라이스를 규정합니다. 기본값은
100
밀리초입니다.