저는 Seagate 디스크(ST5000LM000 - SMR임에 유의)를 가지고 있는데 쓰기 작업량이 많은 경우 I/O 활용도는 100%가 되고 처리량은 기본적으로 0이 됩니다. 드라이버를 사용하여 디스크를 mpt3sas
SAS 컨트롤러에 연결합니다(디스크는 scsi 장치로 나타납니다). 스케줄러를 변경하고 noop
, ncq를 1로 설정하고, 장치 시간 제한을 1시간으로 늘려 보았습니다. 완전히 다른 디스크 컨트롤러(드라이버를 사용함 megaraid
)를 사용해 보았지만 아무 것도 변경되지 않았습니다. 각 드라이브에는 XFS 파티션이 있습니다.
도움이 되는 유일한 방법은 파일을 작성하는 스크립트의 동시성을 줄여 디스크 I/O가 눈덩이 효과로 인해 문제가 발생할 정도로 뒤처지는 일이 없도록 하는 것입니다.
동시 디스크 작업을 방지해야 한다고 생각 echo 1 > /sys/block/sdl/device/queue_depth
하지만 일반적으로 약 150개의 작업이 진행 중인 것으로 보입니다 cat /sys/block/sdl/stat
.
이는 큰 문제입니다. 이 문제가 발생하기 시작할 때 로딩 스크립트를 종료하지 않으면 결국 I/O 작업이 시간 초과되기 때문입니다.디스크 연결 끊김 발생, 이로 인해 프로세스가 끔찍한 상태에 빠지게 되고 D
종종 데이터가 손상되기도 합니다.
이러한 나쁜 상태에 빠지는 것을 방지하기 위해 변경할 수 있는 커널 설정이 있습니까? 충분히 일찍 종료하면 I/O 작업 시간이 초과되어 디스크 연결이 끊어지기 전에 항상 포착될 수 있기 때문에 뭔가 조치를 취해야 할 것 같습니다.
kern.log
실제로 디스크 연결이 끊어진 시점부터
[401217.833235] sd 0:0:6:0: device_block, handle(0x0010)
[401218.583675] mpt3sas_cm0: log_info(0x31110e03): originator(PL), code(0x11), sub_code(0x0e03)
[401218.833518] sd 0:0:6:0: device_unblock and setting to running, handle(0x0010)
[401222.584105] sd 0:0:6:0: device_block, handle(0x0010)
[401230.581727] sd 0:0:6:0: device_unblock and setting to running, handle(0x0010)
[401230.586627] scsi_io_completion: 6 callbacks suppressed
[401230.586641] sd 0:0:6:0: [sdg] tag#0 FAILED Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK
[401230.586656] sd 0:0:6:0: [sdg] tag#0 CDB: Read(16) 88 00 00 00 00 01 3b e5 74 18 00 00 02 00 00 00
[401230.586661] XFS (sdg): metadata I/O error: block 0x800007b8 ("xfs_trans_read_buf_map") error 5 numblks 32
[401230.586670] XFS (sdg): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5.
[401230.597537] blk_update_request: 6 callbacks suppressed
[401230.597540] blk_update_request: I/O error, dev sdg, sector 5299860504
디스크 대역폭이 본질적으로 0으로 떨어집니다. 평균 I/O 요청 시간 급증 디스크 I/O는 100% 활용도를 유지합니다. 실행 중인 I/O 요청은 약 150개로 유지됩니다. (참고로 위 이미지에서는 쓰기 처리량이 크게 떨어졌을 때 로딩 스크립트를 취소했기 때문에 결국 복구되었습니다.)
배포판/커널
$ lsb_release -d
Description: Ubuntu 16.04.6 LTS
$ uname -r
4.15.0-62-generic
fdisk -l
Disk /dev/sdl: 4.6 TiB, 5000981078016 bytes, 9767541168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
xfs_info
meta-data=/dev/sdl isize=512 agcount=5, agsize=268435455 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1 spinodes=0
data = bsize=4096 blocks=1220942646, imaxpct=5
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=521728, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
답변1
다음 커널 매개변수를 변경했는데 높은 쓰기 로드에서 SMR 디스크의 연결이 더 이상 끊어지지 않습니다. 때로는 과도한 I/O(예: 한 자릿수 MB/초 쓰기 속도)로 인해 쓰기 성능이 매우 느려질 수 있지만 적어도 디스크 연결이 더 이상 끊어지지 않습니다.
DEVICE=sdX # insert your device name here
echo 3600 > /sys/block/$DEVICE/device/timeout
echo 3600 > /sys/block/$DEVICE/device/eh_timeout
echo noop > /sys/block/$DEVICE/queue/scheduler
echo 1 > /sys/block/$DEVICE/device/queue_depth
echo 4 > /sys/block/$DEVICE/queue/nr_requests
각각을 개별적으로 테스트하지 않았기 때문에 각각을 설정해야 하는지 잘 모르겠지만 이 조합이 제게는 효과적이었습니다.
답변2
SMR 드라이브에서 XFS나 ext4를 사용하는 것과 비교해 F2FS를 사용하는 것이 좋은 경험이었습니다. 내 ext4는 SMR 드라이브에서 위에서 설명한 것과 유사한 동작을 나타내므로 Linux에서 SMR 솔루션을 조사해야 합니다. 또한 귀하가 설명하는 시간 초과 문제가 발생했습니다. 나는 또한 Ubuntu를 사용하고 있지만 최신 Ubuntu 18.04.3 LTS 버전을 사용하고 있습니다.
우선, 무작위 읽기/쓰기 작업이 많은 서버에는 SMR 드라이브를 권장하지 않습니다. SMR 사용을 피하고 싶은 사용 사례의 예로는 읽기/쓰기 처리량이 높은 데이터베이스 및 NAS 애플리케이션이 있습니다. 내 사용 사례는 NAS의 외부 백업인데, 이는 시간이 중요하지 않고 대부분 연속적이므로 문제가 되지 않습니다.
가장 먼저 해야 할 일은 F2FS 파일 시스템을 얻는 것입니다. 이는 18.04에서 매우 간단합니다.
sudo apt install f2fs-tools
gparted
SMR 드라이브의 모든 파티션을 삭제한 다음 gparted
전체 드라이브에 걸쳐 있는 F2FS 파티션을 생성하는 데 사용 합니다.
내 드라이브(Toshiba)는 MS-Windows 운영 체제 컴퓨터에서 사용할 수 있도록 2개의 파티션으로 사전 포맷되어 제공됩니다. 첫 번째 파티션을 더 작게 유지하면 어떤 파일 시스템을 설치하더라도 쓰기 속도가 끔찍합니다. 나는 첫 번째 파티션이 드라이브의 SMR이 아닌 부분이 로그 및 기타 메타데이터에 할당되는 곳이라고 강하게 의심합니다. 내 경험에 따르면 생성된 파일 시스템이 이 영역에 액세스하여 이점을 얻는 것이 매우 중요합니다.
불행하게도 gparted에는 블록 파티션 SMR 드라이브에 적합한 파일 시스템을 적절하게 생성하기 위한 옵션을 설정할 수 있는 곳이 없는 것 같습니다. 파티션 식별 정보를 기록한 후 gparted
mkfs 명령을 종료하고 수동으로 실행했는데, 이번에는 다음과 같은 마법이 추가되었습니다.
sudo mkfs.f2fs -fm /dev/XXXX
XXXX
이전에 식별한 파티션은 어디에 있습니까 gparted
? -m 옵션은 F2FS에게 SMR 드라이브의 차단 영역 기능을 사용하도록 지시하므로 중요합니다. 그것이 없으면 내 경험에 따르면 당신은 지붕널 지옥에서 괴로움을 겪게 될 것입니다.
이 작업이 완료되고 설치되면 드라이브에 쓰기가 매우 일관됩니다. 내 쓰기 속도는 대부분 117MB/s에서 105MB/s 사이입니다. 때때로 몇 초 동안 쓰기 속도가 70-80MB/s로 떨어지곤 했습니다.
나는 SMR 드라이브가 대상 포진이 겹치는 드라이브 영역을 다시 작성하여 따라잡아야 한다고 생각합니다. 다행스럽게도 이런 일이 자주 발생하지는 않습니다. 하지만 (아직) 하드 드라이브의 사용 가능한 공간을 절반도 활용하지 못한다는 점은 인정합니다. 이런 일이 발생하면 shingled 쓰기가 더 자주 발생하여 백업 시간이 더 오래 걸릴 것으로 예상됩니다. 그러나 이제는 플래터의 타일링된 영역을 피하는 데 매우 효과적이어서 속도가 느려지는 예를 많이 찾기가 어렵습니다. 또한 장치의 캡슐화되지 않은 영역을 활용하여 메타데이터(로그)를 저장하는 것으로 나타나며, 이는 귀하가 설명하는 엄청난 속도 저하를 방지합니다.
또한 읽기가 완료되고 명령 프롬프트가 반환된 후 F2FS가 나머지 데이터를 플러시하는 데 약 10초가 걸린다는 사실도 확인했습니다. 데이터 손실을 방지하려면 이 시간 동안 장치를 제거하거나 플러그를 뽑지 않는 것이 중요합니다. 쉘 스크립트를 사용하는 경우 이 점을 염두에 두십시오.
F2FS를 사용한 내 쓰기 속도가 xfs를 사용한 쓰기 속도보다 훨씬 높다는 데 동의하실 것입니다. 또한 이를 달성하기 위해 시간 제한을 변경할 필요도 없었습니다.