이전 Q&A에서 dirty_ratio에 대한 실험을 보여드린 적이 있습니다.
쓰기 저장 캐시("더티")는 dirty_Background_ratio보다 훨씬 작은 것으로 제한되는 것 같습니다. 그 한계는 무엇입니까? 이 한도는 어떻게 계산되나요?
더러운 요금 계산에 대한 이해를 바로잡아 문제를 해결했다고 생각합니다. 하지만 방금 실험을 반복했는데 다시 쓰기 캐시가 이전에 본 것보다 낮게 조절되었습니다. 이 문제를 해결할 수 없습니다. 문제를 제한하는 것은 무엇입니까?
sysctl에 대한 기본값이 있습니다 vm.dirty*
. dirty_background_ratio
10이요, dirty_ratio
20이요. "비율"은 MemFree
+ 의 백분율로 표시되는 더티 페이지 캐시(즉, 다시 쓰기 캐시)의 크기를 나타냅니다 Cached
. 그들은아니요백분율 MemTotal
- 위의 질문에서 제가 혼란스러워하는 부분이 바로 이것입니다.
이러한 비율은 10%에 도달하면 백그라운드 쓰기 저장이 시작되고 20%는 쓰기 저장 캐시의 최대 크기임을 의미합니다. 또한 후기입 캐싱에는 "I/O 없는 더티 제한"이 적용된다는 것을 알고 있습니다. 쓰기 저장 캐시가 15% 이상으로 증가하면 더티 페이지를 생성하기 위해 write()를 사용하는 프로세스가 "제한"됩니다. 즉, 커널은 write() 호출 내에서 프로세스를 휴면 상태로 만듭니다. 따라서 커널은 절전 기간을 제어하여 후기입 캐시의 크기를 제어할 수 있습니다. 참고로 이전 질문에 대한 답변을 참조하세요.
하지만 제가 관찰한 "비율"은 15% 제한 임계값보다 훨씬 낮은 것 같습니다. 내가 놓친 몇 가지 요소가 있어야합니다! 왜 이런 일이 발생합니까?
이전 테스트에서는 15~17.5% 정도의 값을 봤습니다.
내 커널은 Linux입니다 4.18.16-200.fc28.x86_64
.
테스트는 다음과 같습니다. 나는 dd if=/dev/zero of=~/test bs=1M status=progress
. 동시에 달성된 더러운 비율을 모니터링했습니다. dd
15GB 이후에 명령을 중단했습니다.
$ while true; do grep -E '^(Dirty:|Writeback:|MemFree:|Cached:)' /proc/meminfo | tr '\n' ' '; echo; sleep 1; done
...
MemFree: 139852 kB Cached: 3443460 kB Dirty: 300240 kB Writeback: 135280 kB
MemFree: 145932 kB Cached: 3437220 kB Dirty: 319588 kB Writeback: 112080 kB
MemFree: 134324 kB Cached: 3448776 kB Dirty: 237612 kB Writeback: 160528 kB
MemFree: 134012 kB Cached: 3449004 kB Dirty: 169064 kB Writeback: 143256 kB
MemFree: 133760 kB Cached: 3449024 kB Dirty: 105484 kB Writeback: 119968 kB
MemFree: 133584 kB Cached: 3449032 kB Dirty: 49068 kB Writeback: 104412 kB
MemFree: 134712 kB Cached: 3449116 kB Dirty: 80 kB Writeback: 78740 kB
MemFree: 135448 kB Cached: 3449116 kB Dirty: 8 kB Writeback: 0 kB
예를 들어 출력의 첫 번째 줄을 인용하려면 다음과 같이 하세요.
avail = 139852 + 3443460 = 3583312
dirty = 300240 + 135280 = 435520
ratio = 435520 / 3583312 = 0.122...
나는 그것을 제한하는 것을 하나 찾았지만 이러한 결과를 보기에는 충분하지 않았습니다. 나는 그것을 설정하려고 노력했습니다 /sys/class/bdi/*max_ratio
. 질문의 테스트 결과는 max_ratio = 1로 실행한 결과입니다.
위 테스트를 반복하면 max_ratio = 100
더 높은 더티 비율(예: 0.142)을 얻을 수 있습니다.
MemFree: 122936 kB Cached: 3012244 kB Dirty: 333224 kB Writeback: 13532 kB
쓰기 테스트는 이를 안정적으로 관찰하는 데 꽤 오랜 시간이 걸립니다(예: 8GB). 이 테스트에는 약 100초가 소요됩니다. 회전하는 하드 드라이브를 사용하고 있습니다.
4GB로 테스트를 시도했는데 더티 비율이 0.129에 불과했습니다.
MemFree: 118388 kB Cached: 2982720 kB Dirty: 249020 kB Writeback: 151556 kB
내가 말했듯이 이것은 나를 놀라게했습니다. 전문가 소스가 있어요2013년dd
, 시스템이 더티 비율 0.15에 도달할 때까지 더티 페이지를 생성하려면 "자유 실행"해야 한다고 말합니다 . 그것 은 그것에 대해 명시 적으로 이야기 합니다 max_ratio
.
답변1
MemFree
"비율"은 + 의 백분율로 표시되는 더티 페이지 캐시(즉, 다시 쓰기 캐시)의 크기를 나타냅니다Cached
. 이는 MemTotal의 백분율이 아닙니다. 위의 질문에서 제가 혼란스러워한 부분이 바로 여기입니다.
아니요, 해당 설명은 아직 정확하지 않습니다.
Cached
tmpfs
, 및 기타 배포판 Shmem
의 모든 파일을 포함합니다 . 페이지 캐싱을 사용하여 구현되었기 때문에 계산됩니다. 그러나 이는 영구 저장소의 캐시가 아닙니다. 그냥 버릴 수는 없습니다. tmpfs
페이지는 교환될 수 있지만 교환 가능한 페이지는 계산에 포함되지 않습니다.
나는 그 중 500-600MB를 가지고 있습니다 Shmem
. 추적점을 다시 보려고 시도했을 때(이전 질문에 대한 답변 참조) 이것은 대략 적절한 양이었고 limit
/0.20이 예상보다 낮은 이유를 설명할 것입니다.
또한 Cached
제외 Buffers
될 수 있습니다.일부 설정에서는 놀라울 정도로 많은 양이 발생함.
구현을 자세히 살펴봐야 한다고 생각했습니다.global_dirtyable_pages()내 커널 버전에서는 /proc/vmstat
.
답변2
ext2/4에서는 5초마다 기본 새로 고침이 이루어지며 data=ordered
이는 기본값이기도 합니다.
commit=nrsec
Start a journal commit every nrsec seconds. The default value is 5 seconds. Zero means de-
fault.
따라서 페이지가 더러워진 상태를 유지하고 싶지 않다면(또는 너무 오랫동안 더러워진 상태로 유지되는 경우) 가장 먼저 조정해야 할 곳은 바로 여기입니다.
여기에 딜레마가 있습니다. 몇 년 전 ext4 데이터 손실과 관련된 큰 문제입니다(참조:noauto_da_alloc설치 옵션):
커널은 필요한 경우에만 쓸 준비가 되어 있습니다. 따라서 크기와 기간 또는 제한을 기준으로 제한할 수 있습니다. VM은 기본 스토리지의 캐시 역할을 합니다.
"데스크톱" 사용자는 대부분 이 추가 레이어를 사용할 준비가 되어 있지 않습니다. 그가 할 때구하다파일을 제외하면 즉시 스토리지에 파일이 물리적으로 존재합니다. 이것이 vim
fs 또는 fsync 옵션이 있는 이유입니다.
활성화되면 파일에 쓴 후 라이브러리 함수 fsync()가 호출됩니다. 이는 파일을 디스크에 플러시하여 메타데이터 로깅만 수행하는 파일 시스템에서도 안전하게 쓸 수 있도록 보장합니다. 이렇게 하면 노트북 모드로 실행되는 Linux 시스템에서 하드 드라이브가 강제로 회전하게 되므로 일부 경우에는 바람직하지 않을 수 있습니다.
git repo 작업에서 500,000개의 더티 페이지가 있었는데 background
크기 제한에 도달하여 완전히 사라졌습니다. 또한 git이 repack/garbage collection을 결정하면 동기화하는 것처럼 보입니다 . vim
set 과 비슷합니다 .fs
(다른 파티션의) 마운트도 동기화됩니다.
그러나 ext4 log의 길고 ratio
긴 커밋 시간으로 인해 expire_centisecs
5초도 없고 누구도(vim, git) 동기화되지 않습니다.RAM의 절반이 몇 시간 동안 더러워질 수 있습니다.
답변3
dd의 크기를 몇 페이지로 줄였습니다.
dd if=/dev/zero of=zerooo count=250 bs=4096
스크립트에는 중요한 매개변수가 표시됩니다.
grep dirty /proc/vmstat
grep '' /proc/sys/vm/*centi*
grep '' /proc/sys/vm/dirt*ratio
만료는 실제로 해제되어 있으며 임계값은 250dd 페이지보다 높습니다.
nr_dirty 0
nr_dirty_threshold 2398
nr_dirty_background_threshold 1199
/proc/sys/vm/dirty_expire_centisecs:360000
/proc/sys/vm/dirty_writeback_centisecs:360000
/proc/sys/vm/dirty_background_ratio:0
/proc/sys/vm/dirty_ratio:0
비율은 0이며 이는 절대 매개변수를 에코하고 있음을 나타냅니다.
/proc/sys/vm/dirty_background_bytes:9819200
/proc/sys/vm/dirty_bytes:9819200
선행 9는 819200바이트 = 200페이지를 약 1000페이지로 변환합니다. 위의 "임계값"을 참조하세요.
이제 설치 옵션이 중요합니다. 불행히도 "data=writeback"도 설치했는데 이로 인해 일부 새로 고침이 간접적으로 방해가 되었는지는 알 수 없습니다. 그러나 dd가 직접 더티 페이지만 생성하려면 noauto, 긴 커밋 및 "writeback"이 모두 필요한 것 같습니다.
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda3 ext4 rw,relatime,noauto_da_alloc,data=writeback
`-/mnt/sda/4 /dev/sda4 ext4 rw,relatime,noauto_da_alloc,commit=3600,data=writeback
지금:
$ time dd if=/dev/zero of=zerooo count=150 bs=4096
150+0 records in
150+0 records out
614400 bytes (614 kB, 600 KiB) copied, 0.00106973 s, 574 MB/s
real 0m0.003s
user 0m0.000s
sys 0m0.003s
오리지널 버전도 있습니다. 병렬로 실행할 스크립트:
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback:
0으로 내려가는 것이 제가 Zeroooo에서 한 일입니다. 유통기한이 길어서 여기까지 남아있어요.
뒤쪽에:
echo 25600 > /proc/sys/vm/dirty_bytes
임계값은 매우 작습니다. 배경 값은 자동으로 50%로 조정됩니다. :
nr_dirty 0
nr_dirty_threshold 7
nr_dirty_background_threshold 3
이제 나는 다음을 얻습니다:
$ time dd if=/dev/zero of=zerooo count=150 bs=4096
150+0 records in
150+0 records out
614400 bytes (614 kB, 600 KiB) copied, 0.0258571 s, 23.8 MB/s
real 0m0.028s
user 0m0.003s
sys 0m0.000s
더 오래, 더 오래! 조절판! 그리고 남은 12kB의 더티 데이터만 있습니다.
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
... snip
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
rm Zerooo는 nr_dirty를 다시 0으로 설정합니다.
DD#3:
상한은 150페이지보다 훨씬 높지만 배경은 여전히 3개입니다.
nr_dirty 0
nr_dirty_threshold 2448
nr_dirty_background_threshold 3
dd가 최고 속도로 돌아왔습니다. dd는 이 페이지가 정확히 어디에 있는지 신경 쓰지 않습니다. 이미 작성되었습니다.
$ time dd if=/dev/zero of=zerooo count=150 bs=4096
150+0 records in
150+0 records out
614400 bytes (614 kB, 600 KiB) copied, 0.0011005 s, 558 MB/s
real 0m0.003s
user 0m0.003s
sys 0m0.000s
결과는 두 번째 실행과 유사합니다. 일부 kB는 "백그라운드"로 플러시되지 않지만 숫자가 더 낮기 때문에 아마도 인위적인 분수일 것입니다. 내 경험상 시작하면 "0"으로 플러시됩니다.
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
이제 다음과 같이 변경하세요.
mount -o remount,commit=13 /mnt/sda/4
배경이 150페이지를 초과하면(첫 번째 실행 참조) data=writeback을 사용해도 13초 후에 추가 더티 정보를 얻습니다.
Dirty: 0 kB
Dirty: 0 kB
Dirty: 0 kB
Dirty: 456 kB ??? seems to appear always
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 620 kB !!! after 13 seconds commit= mount option
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB rm zeroooo
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB sync
Dirty: 0 kB
이 5초 데이터 및 메타데이터 패킷은 /proc/sys/vm/의 "centsecs" 매개변수에 의해 30초마다 새로 고쳐져야 합니다. 하지만 함께만. 이것이 data=ordered
작용하는 곳 입니다 .
nr_dirty
제목: 물론, ctrl-c dd를 누른 후 모니터링 스크립트를 시작하면 /proc/vmstat의 내용은 상한 임계값을 초과할 수 없습니다.