개발 공부
[운영체제][OSTEP] RAID
대용량이면서 고속의 신뢰할 수 있는 저장 시스템을 만드는 핵심 기술들에 대해 공부해봅니다.

![[운영체제][OSTEP] RAID](https://www.datocms-assets.com/66479/1686988115-ostep.jpg?auto=format&w=860)
🚪 들어가며
RAID: Redundant Array of Inexpensive Disk
💡 여러 개의 디스크를 조화롭게 사용하여 고속이면서 대용량의 신뢰할 수 있는 디스크 시스템을 만드는 기술
외면적으로 RAID는 하나의 디스크처럼 보임.
내부적으로는 여러 개의 디스크와 메모리(휘발성과 비휘발성을 모두 포함), 시스템을 관리하기 위한 하나 또는 그 이상의 프로세서로 이루어진 복잡한 기계임.
RAID의 하드웨어는 컴퓨터 시스템과 매우 유사하며 디스크의 그룹을 관리하기 위한 전용 시스템임.
✅ RAID는 단일 디스크에 비해 여러 장점들을 제공
디스크 여러 개를 병렬적으로 사용하면 I/O 시간이 크게 개선됨.
더욱 큰 용량을 사용할 수 있음.
데이터 중복 기술(redundancy)을 사용함으로써 디스크 중 하나가 고장나더라도 데이터 손실 없이(고장이 전혀 없었던 것처럼) 동작할 수 있음.
1️⃣ 인터페이스와 RAID의 내부
파일 시스템이 RAID에 논리적 I/O를 요청하면 RAID는 내부에서 어떤 디스크(들)를 접근해야 요청을 완료할 수 있는지 계산한 후에 하나 또는 그 이상의 물리적 I/O를 발생시킴.
미러링 기반의 RAID 시스템에서 블럭에 쓰는 경우 하나의 논리적 I/O에 대해서 두 개의 물리적 I/O를 실행해야 함.
➡️ 서로 다른 디스크에 2개의 복사본을 유지
RAID 시스템은 보통 별도의 하드웨어 박스 형태로 되어 있으며 호스트와 SCSI나 SATA와 같은 표준 인터페이스로 연결됨.
내부적인 구조는 다음을 포함한다.
RAID의 작업을 지시하는 펌웨어를 실행하는 마이크로 컨트롤러
블럭을 읽고 쓸 때 버퍼로 사용할 DRAM 등의 휘발성 메모리
쓰기를 안전하게 버퍼링하기 위한 비휘발성 메모리가 포함되기도 함.
패리티 계산을 위한 전용 논리 회로가 포함되기도 함.
RAID는 프로세서와 메모리, 디스크를 갖고 있음.
➡️ 특수한 컴퓨터 시스템
➡️ 응용 프로그램을 실행하는 대신 RAID를 동작시키기 위해 설계된 전용 소프트웨어를 실행
2️⃣ 결함 모델
RAID는 특정 종류의 결함을 파악하고 이를 복구하도록 설계되어 있음.
➡️ 💡 설계시 어떤 종류의 결함에 대비해야 하는지를 파악하는 것이 매우 중요
고장 시 멈춤(fail-stop) 모델
이 모델에서 디스크는 "정상 작동"이거나 "멈춤" 둘 중 하나의 상태로 있다고 가정
➡️ ✅ 동작 중인 디스크에는 모든 블럭을 읽거나 쓸 수가 있음.
➡️ 🚫 멈춤 상태의 디스크는 완전히 사용 불가능하다고 간주함.
⚠️ 고장 시 멈춤 모델의 치명적인 단점: 결함이 발견되는 경우에 대한 가정
이 모델에서는 디스크가 고장나면 쉽게 파악할 수 있다고 가정
➡️ 디스크 섹터내용이 망가지는 것과 같은 "조용한" 고장들에 대해서는 고려하지 않음.
3️⃣ RAID의 평가 방법
용량
B개의 블럭을 가지는 N개의 디스크가 주어졌을 때 RAID의 클라이언트가 사용할 수 있는 유효 용량
➡️ N * B
각 블럭에 대해 두 개의 복사본을 갖는 경우(미러링)
➡️ (N * B) / 2
패리티 기반 기법과 같은 다른 기법은 그 사이의 값을 가지게 됨.
신뢰성
평가 대상의 설계 방법은 몇 개의 디스크 결함을 감내할 수 있는가?
성능
성능은 디스크 배열이 처리해야 할 워크로드에 따라 크게 달라지기 때문에 평가하기가 만만치 않음.
4️⃣ RAID 설계
RAID 레벨 0: 스트라이핑(striping)
💡 디스크 배열의 블럭들을 라운드 로빈 방식으로 디스크를 가로질러 펼치는 것
➡️ 같은 행에 있는 블럭들을 스트라이프(stripe)라고 부름.
[ RAID 매핑 문제 ]
논리 블럭 주소가 A라고 할 때, 다음과 같이 원하는 디스크와 오프셋을 계산해낼 수 있음.
Disk = A % number_of_disks
Offset = A / number_of_disks (정수 계산, ex) 4/3 = 1)
청크 크기는 RAID의 성능에 큰 영향을 줌.
작은 청크 크기
많은 파일들이 여러 디스크에 걸쳐서 스트라이프됨.
그 결과로 하나의 파일을 읽고 쓰는 데 병렬성이 증가하게 됨.
하지만 블럭의 위치를 여러 디스크에서 찾아야 하므로 위치 찾기 시간이 늘어남.
큰 청크 크기
파일 내의 병렬성이 줄어듦.
➡️ 높은 처리 성능을 얻으려면 여러 요청을 병행하게 실행해야 함.
위치 찾기 시간이 줄어듦.
🚀 성능
지연 시간 측면에서 한 블럭에 대한 요청의 지연 시간은 하나의 디스크에 대한 요청의 지연 시간과 거의 동일
➡️ RAID-0은 받은 요청을 디스크 중 하나에게 전달하는 것뿐이기 때문
순차 워크로드의 경우 S MB/s, 랜덤 워크로드에서는 R MB/s의 속도로 전송한다고 가정하자.
정상 상태에서의 대역폭 측면에서 시스템의 최대 대역폭을 기대할 수 있음.
➡️ 처리 성능 = N(디스크의 수) * S(디스크 하나의 순차 접근 대역폭) MB/s
랜덤 I/O = N * R MB/s
RAID 레벨 1: 미러링
미러링을 사용하는 시스템에서는 각 블럭에 대해서 하나 이상의 사본을 둠.
➡️ 각 사본은 당연히 서로 다른 디스크에 저장되어야 함.(디스크 고장에 대처)
미러링된 배열에서 블럭을 읽을 때 RAID는 원본을 읽을 건지 사본을 읽을 건지 선택할 수 있음.
RAID는 신뢰성을 유지하기 위해서 두 벌의 데이터를 모두 갱신해야 함.
➡️ 이러한 쓰기 요청은 병렬적으로 처리될 수 있음.
용량 측면에서 RAID-1은 비용이 많이 듦.
➡️ 유효 용량 = (N * B) / 2 (B개의 블럭을 가진 N개의 디스크 배열)
신뢰성 측면에서 RAID-1은 괜찮은 편
➡️ 일반적으로 미러링 시스템(미러링 레벌 2)의 경우 한 개의 디스크 고장은 확실히 감내 가능
🚀 성능
단일 읽기 요청의 지연 시간은 단일 디스크에서 읽는 경우의 지연 시간과 동일
➡️ RAID-1이 하는 일은 두 벌의 사본 중에 하나의 디스크로 요청을 전달하는 것이기 때문
쓰기 요청의 완료 = 두 개의 디스크로 전달된 쓰기가 모두 종료
➡️ 쓰기는 병렬적으로 이루어지기 때문에 하나의 쓰기에 소요되는 시간과 거의 동일
➡️ 평균적으로 하나의 디스크에 쓰는 시간보다는 조금 더 긺.
미러링된 배열에 순차 쓰기의 경우 (N / 2) * S 또는 최대 대역폭의 절반의 대역폭을 얻을 수 있음.
➡️ 순차 읽기 상황에서도 동일한 성능
랜덤 읽기가 미러링된 RAID에서는 최고의 워크로드
➡️ N * R MB/s (최대 대역폭)
랜덤 쓰기는 (N / 2) * S MB/s
➡️ 각 논리 쓰기는 두 번의 물리 쓰기로 바뀌어야 하기 때문
RAID 레벨 4: 패리티를 이용한 공간 절약
💡 각 데이터 스트라이프마다 해당 스트라이프에 대한 중복 정보를 담고 있는 패리티 블럭 하나를 추가
XOR를 통해 데이터 값을 복구할 수 있음.
용량 측면에서 RAID-4는 (N - 1) * B의 저장 공간을 제공
➡️ 패리티 정보의 저장을 위해 각 디스크 그룹에 속한 디스크 하나를 사용하기 때문
신뢰성의 경우 RAID-4는 오직 하나만의 디스크 고장을 감내할 수 있음.
🚀 성능
순차 읽기 성능(유효 대역폭) = (N - 1) * S MB/s
➡️ 패리티 디스크를 제외한 모든 디스크를 활용할 수 있기 때문
순차 쓰기 성능(유효 대역폭) = (N - 1) * S MB/s
➡️ 스트라이프 전부 쓰기(full-stripe write)라는 간단한 최적화 방법을 수행할 수 있음.
랜덤 읽기 성능(유효 성능) = (N - 1) * R MB/s
랜덤 쓰기 시 블럭을 갱신하는 두 가지 방법이 존재
가산적 패리티(additive parity)
감산적 패리티(subractive parity)
RAID-4의 I/O 지연 시간은 다음과 같다.
한 개의 읽기 요청의 지연 시간 = 하나의 디스크 요청의 지연 시간
한 개의 쓰기 요청의 지연 시간 = 하나의 디스크 요청의 약 두 배
RAID 레벨 5: 순환 패리티
RAID-5는 RAID-4와 거의 동일하게 동작하지만 패리티 블럭을 순환(rotate)시킨다는 점이 다름.
RAID-4와 RAID-5의 유효 용량과 결함 허용 정도는 동일
➡️ 순차 읽기와 쓰기 성능도 동일
➡️ 한 개의 요청의 지연 시간(읽기, 쓰기)도 동일
🚀 성능
랜덤 읽기 성능은 RAID-4보다 약간 더 좋음.
➡️ 모든 디스크를 다 활용할 수 있기 때문
랜덤 쓰기 성능은 RAID-4 대비 눈에 띄게 개선
➡️ 요청들을 병렬적으로 처리할 수 있기 때문
5️⃣ RAID 비교: 정리
RAID-0 RAID-1 RAID-4 RAID-5
───────────────────────────────────────────────────────────────────────────────
Capacity N * B (N * B) / 2 (N - 1) * B (N - 1) * B
───────────────────────────────────────────────────────────────────────────────
Reliability 0 1 (for sure) 1 1
N / 2 (if lucky)
───────────────────────────────────────────────────────────────────────────────
Throughput
Sequential Read N * S (N / 2) * S (N - 1) * S (N - 1) * S
Sequential Write N * S (N / 2) * S (N - 1) * S (N - 1) * S
Random Read N * R N * R (N - 1) * R N * R
Random Write N * R (N / 2) * R (1 / 2) * R (N / 4) * R
Latency
Read T T T T
Write T T 2T 2T
위의 표에서 T는 단일 디스크에 대한 요청 지연시간
분석을 간단히 하기 위해서 세부 사항들은 생략됨.
➡️ 미러링 기반의 시스템에서 쓰기 연산 시 평균 탐색 시간은 당일 디스크에 쓸 때의 시간보다 약간 더 긴 것 등
두 개의 디스크에서 랜덤 쓰기 성능은 일반적으로 하나의 디스크에 요청되는 랜덤 쓰기 성능보다 더 작음.
RAID-4/5의 패리티 디스크에 갱신할 때에는 먼저 예전의 패리티를 읽어야 함.
➡️ 최대 탐색과 회전 지연을 일으킬 수 있지만 패리티에 두 번째 쓸 때에는 회전 지연만 있음.
🛸 결론
성능만 원하고 신뢰성 고려 X ➡️ 스트라이핑
임의 I/O의 성능과 신뢰성이 목적 ➡️ 미러링(그 대신 용량 손해)
용량과 신뢰성이 목적 ➡️ RAID-5
항상 순차 I/O만을 사용하고 용량 극대화가 목적 ➡️ RAID-5
6️⃣ RAID와 관련된 다른 흥미로운 주제들
레벨 2와 3, 복수의 디스크에서 발생하는 결함에 내성이 있는 레벨 6 등 여러 다른 RAID 설계 방법들이 존재
디스크가 고장났을 때 RAID가 어떻게 대응하는 지에 대한 논의도 존재
➡️ 때때로 대체용 스페어(hot spare)가 있어서 고장난 디스크를 즉시 대신하는 방법이 있음.
잠재된 섹터 오류(latent sector error) 또는 블럭 훼손(block corruption)을 고려하는 결함 모델들도 존재
소프트웨어 레이어로 RAID를 구성할 수도 있음.
➡️ 이러한 소프트웨어 RAID 시스템은 저렴하기는 하지만 일관성-유지 갱신 문제를 포함하여 다른 문제들을 가짐.
📚 참고 문헌
Operating Systems: Three Easy Pieces ― 38: Redundant Arrays of Inexpensive Disks (RAIDs)
운영체제 아주 쉬운 세 가지 이야기 ― 41: Redundant Array of Inexpensive Disk (RAID)