dd 쓰기 속도와 VFS 페이지 캐시에 대해 혼란스러워함

dd 쓰기 속도와 VFS 페이지 캐시에 대해 혼란스러워함

Linux VFS 페이지 캐시 및 조정 가능한 매개변수에 대한 기사를 읽은 후 dirty_ratio페이지 캐시가 읽기 및 쓰기 캐싱 계층으로 작동할 것이라는 인상을 받았습니다.

그러나 아래의 간단한 테스트를 사용하면 페이지 캐시에 있지만 쓰기에 사용할 수 없는 파일의 읽기 속도를 향상시키는 데 효과적입니다.

예를 들어

캐시를 지우고 파일에 씁니다.

# swapoff -a
# echo 3 > /proc/sys/vm/drop_caches

# dd if=/dev/zero of=/home/flo/test bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.182474 s, 172 MB/s

파일이 실제로 페이지 캐시에 있는지 확인

# vmtouch /home/flo/test 
           Files: 1
     Directories: 0
  Resident Pages: 7680/7680  30M/30M  100%
         Elapsed: 0.000673 seconds

파일을 읽어 실제로 캐시에서 나오는지 확인하세요.

# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.00824169 s, 3.8 GB/s

캐시를 삭제하고 다시 읽어 속도 차이를 확인하세요.

# echo 3 > /proc/sys/vm/drop_caches
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.132531 s, 237 MB/s

dd와 함께 DIRECT_IO를 사용하지 않기 때문에 페이지 캐시를 쓰기 저장 유형의 캐시로 사용하고 싶습니다. 그리고 dirty_ratio이를 기반으로 dirty_expire_centiseconds최종 데이터가 디스크에 커밋됩니다.

특히 쓰기 중에 VFS가 읽기 및 쓰기 프로세스를 다르게 처리하는 방법과 속도 향상이 없는 이유를 설명할 수 있는 사람이 있습니까?

쓰기 캐싱을 사용하여 vfs를 더욱 공격적으로 만들어 RAID 컨트롤러에 있는 다시 쓰기 캐시처럼 작동하도록 하는 방법이 있습니까?

감사해요

루오

답변1

man ext4에는 (no) 옵션이 소개되어 있습니다 auto_da_alloc.

많은 손상된 응용 프로그램은 fsync()를 사용하지 않습니다...

이것 뒤에는 긴 이야기가 있는 것 같습니다(데이터 손실에 대한 비극). 이는 다음과 관련이 있습니다.지연 할당파일 시스템 블록. Ext2/3에는 이 기능이 없지만 ext4뿐만 아니라 매우 중요한 기능입니다.

애플리케이션이 동기화되지 않고 사용자가 수동으로 동기화하지 않고 커널이 30초 후에도 동기화되지 않으면 일부 파일을 다시 작성할 때 파일 시스템이 즉시 동기화를 수행하는 것이 더 나을 것입니다. 그렇지 않으면 DA를 사용하면 정전 중에 나쁜 일이 쉽게 발생할 수 있습니다. 마지막 변경 사항을 잃는 것보다 더 나쁜 것이 있습니다.

conv=notruncatedd 명령이 없으면 덮어쓰기는 "응용 프로그램"과 같습니다. 새 파일을 만들려면 기존 파일을 삭제해야 합니다. 그렇지 않으면 기존 파일이 더 길면 혼합 파일이 생성됩니다.

mount -o remount,noauto_da_alloc ...ext4에서는 이 동작을 끌 수 있습니다 . 이제 블록 쓰기는 잘린 후에도 오랫동안 완료될 수 있습니다.

다음공격성 수준정기적인 쓰기 저장(/proc/sys/vm/의 dirty_..._centisecs 값)에 대한 만료 시간 30초와 확인 간격 5초가 늘어납니다. 기본 30/5를 사용하면 매우 빨리 삭제하지 않는 한 30분 후에 일부 새 파일이 기록됩니다.

VFS가 사용되지 않은 페이지에 대해 더 공격적일수록 파일 시스템은 장치를 차단하는 데 덜 공격적입니다.


마운트 옵션 및 쓰기 저장 매개변수

]# findmnt --real
TARGET       SOURCE     FSTYPE OPTIONS
/            /dev/sda3  ext4   rw,relatime,noauto_da_alloc
|-/root/sda1 /dev/sda1  ext2   rw,relatime
`-/root/16   /dev/sda16 ext4   rw,relatime

이러한 설정에서 오버레이는 sda16에서 즉시 동기화되지만 다른 두 개에서는 동기화되지 않습니다.

현재 저는 주기적인 쓰기 저장을 완전히 해제했습니다.

]# grep '' /proc/sys/vm/*centisecs
/proc/sys/vm/dirty_expire_centisecs:720000
/proc/sys/vm/dirty_writeback_centisecs:0

이제 마침내 더티 페이지를 수집합니다.

]# grep nr_dirty /proc/vmstat 
nr_dirty 10077
nr_dirty_threshold 437320
nr_dirty_background_threshold 174671

노력하다이를 수집하고 어떻게든 기본 10% 배경 비율에 가까워졌습니다. 어제 메모리 절전 모드로 전환했을 때 동기화를 받았습니다. 이것은 의미가 있습니다. 누가 MB의 더티 페이지를 가지고 자고 싶습니까?

mm/writeback.c세부 사항은 복잡하며 리뷰 자체가 이를 보여줍니다. 한 가지 문제는 "1000 dd가 즉시 더러워지기 시작합니다"라는 조절 지점을 놓치지 않는 것입니다. 장기적으로 '쓰기 저장' 목표는 10% 정도인 것 같습니다. 위의 예에서 볼 수 있듯이 일반적인(최소) 사용량에서 이 10%(총/사용 가능한 RAM)를 채우는 데 오랜 시간이 걸립니다. 탐색 1분에 약 1,000페이지가 더러워집니다.


이론이 끝난 후, 구체적인 증명

위에 나열된 두 파일 시스템에서 10개의 블록을 테스트했습니다.

]# dd if=/dev/zero of=test10  bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0076396 s, 1.4 GB/s

]# dd if=/dev/zero of=test10  bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00514406 s, 2.0 GB/s

-> 루트 파티션(sda3, 위)에서 noauto_da_alloc을 사용하면 덮어쓰기가 더 빨라집니다.

ext4(위의 sda16)의 기본 설치에서는 속도가 느려집니다.

]# rm test10 

]# dd if=/dev/zero of=test10  bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00800839 s, 1.3 GB/s

]# dd if=/dev/zero of=test10  bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0740824 s, 142 MB/s

...그림과 같이 전체 적용 범위가 동기화되기 때문입니다 vmstat 1 |cut....

    0     0
    0     0
    0     0
-----io----
   bi    bo
    0 10240
    0     0
    0     0

수동 sync지연 할당

좋은 점은 원할 때 수행할 수 있고 단일 파일이나 전체 드라이브에서 수행할 수 있다는 것입니다.

플러스: 제거, 종료(및 일시 중단)도 포함됩니다.

나쁜 점은 쓰기(덮어쓰기)와 동기화 사이에 충돌/정전이 발생할 때 길이가 0인 "손상"의 위험이 있다는 것입니다. 이는 실제로 하나 또는 두 개의 외부 저장소에 저장한 콘텐츠만 안전하게 저장할 수 있음을 의미합니다.


결론을 찾을 수 없습니다. 쉬운 해결책은 없으며 단지 긴(그러나 적어도 논리적인) 설명만 있을 뿐입니다.

답변2

빠른 행동을 보려면 rm test먼저 그것을 해야 합니다. 예를 들어 dd150MB/s가 아닌 1GB/s가 보고되었습니다.

인용하다:

참조에서는 이 작업을 시도하려는 이유만 설명하지만 실제로 IO 차단이 발생하는 이유는 설명하지 않습니다.

내 컴퓨터에서는 2016년에 추가된 새로운 WBT("Write Back Limits") 코드에서만 차단이 발생하는 것 같습니다.뒤쪽에질문을 하셨습니다. 아직 분석해본 적은 없어요이로 인해 발생할 수 있습니다. WBT가 비활성화되면 사라집니다.

내 커널 버전은 4.18.16-200.fc28.x86_64.

strace -T모든 시간이 close()에서 소비된다는 것을 보여주는 것이 나에게 가장 의미가 있습니다. 을 사용해 보기도 했습니다 perf. 예상대로 작동하지 않지만 다음과 같은 스택 추적이 표시됩니다.

dd 17068 [003] 475165.381526:       sched:sched_switch: dd:17068 [120] T ==> kworker/3:1H:19326 [100]
    ffffffffa390c172 __sched_text_start+0x352 ([kernel.kallsyms])
    ffffffffa390c172 __sched_text_start+0x352 ([kernel.kallsyms])
    ffffffffa390c6a8 schedule+0x28 ([kernel.kallsyms])
    ffffffffa30def32 io_schedule+0x12 ([kernel.kallsyms])
    ffffffffa3461ed7 wbt_wait+0x337 ([kernel.kallsyms])
    ffffffffa342ee33 blk_queue_bio+0x123 ([kernel.kallsyms])
    ffffffffa342d114 generic_make_request+0x1a4 ([kernel.kallsyms])
    ffffffffa342d3c5 submit_bio+0x45 ([kernel.kallsyms])
    ffffffffa3377d78 ext4_io_submit+0x48 ([kernel.kallsyms])
    ffffffffa335da2c ext4_writepages+0x70c ([kernel.kallsyms])
    ffffffffa3209311 do_writepages+0x41 ([kernel.kallsyms])
    ffffffffa31f808e __filemap_fdatawrite_range+0xbe ([kernel.kallsyms])
    ffffffffa334b9ec ext4_release_file+0x6c ([kernel.kallsyms])
    ffffffffa32a9d4e __fput+0xae ([kernel.kallsyms])
    ffffffffa30cf474 task_work_run+0x84 ([kernel.kallsyms])
    ffffffffa3003e6e exit_to_usermode_loop+0xce ([kernel.kallsyms])
    ffffffffa300425d do_syscall_64+0x14d ([kernel.kallsyms])
    ffffffffa3a00088 entry_SYSCALL_64_after_hwframe+0x44 ([kernel.kallsyms])
        7fcca3a60654 __close+0x14 (/usr/lib64/libc-2.27.so)

deadline이는 현재 WBT("writeback throttling")가 활성화된 I/O 스케줄러를 테스트하고 있음을 상기시켜 줍니다 . WBT를 비활성화하면(호환되지 않는 CFQ로 전환 포함) 다시 빠르게 동작하게 되었습니다!

perf이것을 보기 위해 사용하는 명령은 다음과 같습니다.

sudo perf record -e sched:sched_stat_sleep -e sched:sched_switch -e sched:sched_process_exit -gP -o ~/perf.data dd if=/dev/zero of=test bs=1M count=30
sudo perf script -i ~/perf.data | cat

답변3

그냥 사용하지 마세요 dd. 예를 들어 를 사용하면 cp쓰기를 위한 페이지 캐시를 얻게 됩니다.

관련 정보