요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
================
RAID 4/5/6 cache
================
Raid 4/5/6 could include an extra disk for data cache besides normal RAID
disks. The role of RAID disks isn't changed with the cache disk. The cache disk
caches data to the RAID disks. The cache can be in write-through (supported
since 4.4) or write-back mode (supported since 4.10). mdadm (supported since
3.4) has a new option '--write-journal' to create array with cache. Please
refer to mdadm manual for details. By default (RAID array starts), the cache is
in write-through mode. A user can switch it to write-back mode by::
echo "write-back" > /sys/block/md0/md/journal_mode
And switch it back to write-through mode by::
echo "write-through" > /sys/block/md0/md/journal_mode
In both modes, all writes to the array will hit cache disk first. This means
the cache disk must be fast and sustainable.
write-through mode
==================
This mode mainly fixes the 'write hole' issue. For RAID 4/5/6 array, an unclean
shutdown can cause data in some stripes to not be in consistent state, eg, data
and parity don't match. The reason is that a stripe write involves several RAID
disks and it's possible the writes don't hit all RAID disks yet before the
unclean shutdown. We call an array degraded if it has inconsistent data. MD
tries to resync the array to bring it back to normal state. But before the
resync completes, any system crash will expose the chance of real data
corruption in the RAID array. This problem is called 'write hole'.
The write-through cache will cache all data on cache disk first. After the data
is safe on the cache disk, the data will be flushed onto RAID disks. The
two-step write will guarantee MD can recover correct data after unclean
shutdown even the array is degraded. Thus the cache can close the 'write hole'.
In write-through mode, MD reports IO completion to upper layer (usually
filesystems) after the data is safe on RAID disks, so cache disk failure
doesn't cause data loss. Of course cache disk failure means the array is
exposed to 'write hole' again.
In write-through mode, the cache disk isn't required to be big. Several
hundreds megabytes are enough.
write-back mode
===============
write-back mode fixes the 'write hole' issue too, since all write data is
cached on cache disk. But the main goal of 'write-back' cache is to speed up
write. If a write crosses all RAID disks of a stripe, we call it full-stripe
write. For non-full-stripe writes, MD must read old data before the new parity
can be calculated. These synchronous reads hurt write throughput. Some writes
which are sequential but not dispatched in the same time will suffer from this
overhead too. Write-back cache will aggregate the data and flush the data to
RAID disks only after the data becomes a full stripe write. This will
completely avoid the overhead, so it's very helpful for some workloads. A
typical workload which does sequential write followed by fsync is an example.
In write-back mode, MD reports IO completion to upper layer (usually
filesystems) right after the data hits cache disk. The data is flushed to raid
disks later after specific conditions met. So cache disk failure will cause
data loss.
In write-back mode, MD also caches data in memory. The memory cache includes
the same data stored on cache disk, so a power loss doesn't cause data loss.
The memory cache size has performance impact for the array. It's recommended
the size is big. A user can configure the size by::
echo "2048" > /sys/block/md0/md/stripe_cache_size
Too small cache disk will make the write aggregation less efficient in this
mode depending on the workloads. It's recommended to use a cache disk with at
least several gigabytes size in write-back mode.
The implementation
==================
The write-through and write-back cache use the same disk format. The cache disk
is organized as a simple write log. The log consists of 'meta data' and 'data'
pairs. The meta data describes the data. It also includes checksum and sequence
ID for recovery identification. Data can be IO data and parity data. Data is
checksummed too. The checksum is stored in the meta data ahead of the data. The
checksum is an optimization because MD can write meta and data freely without
worry about the order. MD superblock has a field pointed to the valid meta data
of log head.
The log implementation is pretty straightforward. The difficult part is the
order in which MD writes data to cache disk and RAID disks. Specifically, in
write-through mode, MD calculates parity for IO data, writes both IO data and
parity to the log, writes the data and parity to RAID disks after the data and
parity is settled down in log and finally the IO is finished. Read just reads
from raid disks as usual.
In write-back mode, MD writes IO data to the log and reports IO completion. The
data is also fully cached in memory at that time, which means read must query
memory cache. If some conditions are met, MD will flush the data to RAID disks.
MD will calculate parity for the data and write parity into the log. After this
is finished, MD will write both data and parity into RAID disks, then MD can
release the memory cache. The flush conditions could be stripe becomes a full
stripe write, free cache disk space is low or free in-kernel memory cache space
is low.
After an unclean shutdown, MD does recovery. MD reads all meta data and data
from the log. The sequence ID and checksum will help us detect corrupted meta
data and data. If MD finds a stripe with data and valid parities (1 parity for
raid4/5 and 2 for raid6), MD will write the data and parities to RAID disks. If
parities are incompleted, they are discarded. If part of data is corrupted,
they are discarded too. MD then loads valid data and writes them to RAID disks
in normal way.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
RAID 4/5/6 cache 개요
1-21RAID 4/5/6은 일반 RAID disk 외에 data cache용 disk 하나를 추가할 수 있습니다. Cache disk가 생겨도 RAID disk의 역할은 바뀌지 않으며, cache disk가 RAID disk로 향하는 data를 cache합니다.
Cache는 Linux 4.4부터 지원하는 write-through mode와 Linux 4.10부터 지원하는 write-back mode를 제공합니다. mdadm 3.4부터 `--write-journal` option으로 cache가 있는 array를 만들 수 있으며 자세한 내용은 mdadm manual을 참조합니다.
RAID array가 시작될 때 기본 mode는 write-through입니다. 다음 sysfs 명령으로 write-back으로 전환합니다.
echo "write-back" > /sys/block/md0/md/journal_mode
Write-through로 되돌리는 명령은 다음과 같습니다.
echo "write-through" > /sys/block/md0/md/journal_mode
두 mode 모두 array write가 먼저 cache disk에 도달합니다. 따라서 cache disk는 빠르면서 지속적인 write를 감당할 수 있어야 합니다.
Mode, 도입 version과 기본 상태입니다.
같은 sysfs attribute에 원하는 mode 문자열을 기록합니다.
Write hole 문제
22-33Write-through mode의 주된 목적은 `write hole` 문제를 해결하는 것입니다. RAID 4/5/6에서 unclean shutdown이 발생하면 어떤 stripe의 data와 parity가 맞지 않는 등 일관되지 않은 상태가 될 수 있습니다.
Stripe write는 여러 RAID disk에 걸치므로 shutdown 전 모든 write가 모든 disk에 도달하지 않았을 수 있습니다. 문서는 일관되지 않은 data를 가진 array를 degraded라고 부릅니다. MD는 resync로 정상 상태를 복구하려 하지만 resync가 끝나기 전에 다시 crash하면 실제 RAID data corruption이 발생할 수 있습니다. 이것이 `write hole`입니다.
여러 disk에 걸친 stripe write가 중단될 때 생기는 위험입니다.
Write-through mode 동작
34-46Write-through cache는 모든 data를 먼저 cache disk에 기록합니다. Cache disk에서 안전해진 뒤 RAID disk로 flush합니다. 이 2단계 write 덕분에 array가 degraded 상태여도 unclean shutdown 후 MD가 올바른 data를 recover할 수 있어 write hole을 막습니다.
MD는 data가 RAID disk에서 안전해진 뒤에야 upper layer, 보통 filesystem에 I/O completion을 보고합니다. 따라서 cache disk failure 자체로 data가 유실되지는 않지만, cache가 사라진 array는 다시 write hole에 노출됩니다.
Write-through mode에서는 큰 cache disk가 필요하지 않으며 수백 MB면 충분합니다.
Completion은 RAID disk까지 durable해진 뒤 반환됩니다.
Write-back mode와 full-stripe aggregation
47-60Write-back도 모든 write data를 cache disk에 두므로 write hole을 해결하지만 주목적은 write 가속입니다. 하나의 write가 stripe의 모든 RAID disk를 가로지르면 full-stripe write라고 합니다.
Non-full-stripe write에서는 새 parity를 계산하기 전에 MD가 old data를 읽어야 합니다. 이 synchronous read가 write throughput을 떨어뜨리며, 순차 write라도 동시에 dispatch되지 않으면 같은 overhead를 겪습니다.
Write-back cache는 data를 모으고 full-stripe write가 된 뒤에만 RAID disk로 flush하여 old-data read overhead를 완전히 피합니다. Sequential write 뒤 `fsync`를 수행하는 workload가 대표적으로 이득을 봅니다.
작은 write를 full stripe로 모아 read-modify-write를 피합니다.
Write-back completion과 cache sizing
61-76Write-back mode에서 MD는 data가 cache disk에 도달하는 즉시 upper layer에 I/O completion을 보고합니다. 특정 조건을 만족한 뒤에야 RAID disk로 flush하므로 cache disk failure는 data loss를 일으킵니다.
MD는 cache disk에 저장한 것과 같은 data를 memory에도 cache합니다. 따라서 power loss로 data가 유실되지는 않습니다. Memory cache size는 array 성능에 영향을 주므로 크게 설정하는 것이 권장됩니다. 다음 예시는 `stripe_cache_size`를 2048로 설정합니다.
echo "2048" > /sys/block/md0/md/stripe_cache_size
Cache disk가 너무 작으면 workload에 따라 write aggregation 효율이 떨어집니다. Write-back mode에는 적어도 수 GB 크기의 cache disk를 권장합니다.
Completion boundary와 failure semantics가 다릅니다.
Power loss와 cache disk failure가 다른 결과를 내는 이유입니다.
구현: 공통 log format
77-88Write-through와 write-back은 같은 disk format을 사용합니다. Cache disk는 단순 write log이며 `meta data`와 `data` pair의 연속으로 구성됩니다.
Meta data는 뒤따르는 data를 설명하고 recovery 식별을 위한 checksum과 sequence ID를 포함합니다. Data에는 I/O data와 parity data가 올 수 있고 data 자체도 checksum으로 검증합니다. Data checksum은 해당 data 앞의 meta data에 저장됩니다.
Checksum 덕분에 MD는 meta와 data의 write order를 걱정하지 않고 자유롭게 기록할 수 있습니다. MD superblock에는 log head의 유효 meta data를 가리키는 field가 있습니다.
Log head에서 meta-data pair가 이어지는 구조입니다.
구현: mode별 write order
89-104Log 구현 자체는 단순하지만 cache disk와 RAID disk에 write하는 순서가 핵심입니다.
Write-through에서는 MD가 I/O data의 parity를 계산하고 I/O data와 parity를 모두 log에 씁니다. 둘이 log에서 안정된 뒤 RAID disk에 data와 parity를 기록하고 마지막에 I/O를 완료합니다. Read는 평소처럼 RAID disk에서 읽습니다.
Write-back에서는 MD가 I/O data를 log에 쓰고 곧바로 I/O completion을 보고합니다. 같은 시점에 data가 memory에 완전히 cache되어 있으므로 read는 memory cache도 조회해야 합니다.
Flush 조건을 만족하면 MD는 data parity를 계산해 parity를 log에 기록합니다. 그 작업이 끝난 뒤 data와 parity를 RAID disk에 쓰고 memory cache를 release합니다. Flush 조건은 stripe가 full-stripe write가 됨, cache disk free space 부족, in-kernel memory cache free space 부족입니다.
두 mode가 같은 log format을 서로 다른 completion 순서로 사용합니다.
Unclean shutdown recovery
105-111Unclean shutdown 뒤 MD는 log의 모든 meta data와 data를 읽어 recovery합니다. Sequence ID와 checksum으로 손상된 meta data와 data를 식별합니다.
Data와 유효 parity가 함께 있는 stripe는 RAID disk에 기록합니다. RAID4/5에는 parity 하나, RAID6에는 둘이 유효해야 합니다. Parity가 불완전하면 버리고, data 일부가 손상된 경우에도 버립니다. 그 뒤 유효 data를 load해 일반 방식으로 RAID disk에 씁니다.
Sequence ID와 checksum을 기준으로 안전한 log entry만 재생합니다.
요약과 해설
raid5-cache.rst:1-111RAID4/5/6 journal cache는 모든 write를 cache disk에 먼저 기록해 write hole을 닫습니다. Write-through는 RAID disk까지 durable해진 뒤 completion을 반환해 cache failure에 안전하고, write-back은 cache 기록 직후 반환하면서 작은 write를 full stripe로 모아 throughput을 높이는 대신 cache disk failure 시 unflushed data를 잃을 수 있습니다.
두 mode는 sequence ID와 checksum을 가진 meta-data pair log를 공유합니다. Recovery는 완전하고 유효한 data·parity만 RAID disk에 replay하며 손상되거나 불완전한 entry는 버립니다.