디스크에 데이터 쓰기를 지연시키는 철학은 무엇입니까? 기록 된 것은 아닙니다. 예를 들어, sync드라이브에서

Linux에서 cp또는 명령과 같은 명령이 완료 dd되었다고해서 데이터가 장치에 기록 된 것은 아닙니다. 예를 들어, sync드라이브에서 “안전하게 제거”또는 “꺼내기”기능을 호출하거나 호출해야합니다.

그러한 접근 방식의 철학은 무엇입니까? 왜 한 번에 데이터가 기록되지 않습니까? I / O 오류로 인해 쓰기가 실패 할 위험이 있습니까?



답변

그러한 접근 방식의 철학은 무엇입니까?

효율성 (디스크 특성을보다 잘 사용함) 및 성능 (쓰기 후 즉시 응용 프로그램을 계속 사용할 수 있음).

왜 한 번에 데이터가 기록되지 않습니까?

주요 이점은 OS가 연속적인 쓰기 작업을 자유롭게 재정렬하고 병합하여 대역폭 사용을 개선 할 수 있다는 것입니다 (작업이 적고 탐색이 적음). 응용 프로그램에 많은 수의 작은 작업이 필요한 경향이있는 반면, 적은 수의 큰 작업이 요청되면 하드 디스크의 성능이 향상됩니다. 또 다른 명확한 최적화는 OS가 동일한 블록을 짧은 시간에 여러 번 쓸 때 마지막 쓰기를 제외한 모든 쓰기를 제거하거나 영향을받는 파일이 그 동안 제거 된 경우 일부 쓰기를 모두 제거 할 수 있다는 것입니다.

이 비동기 쓰기가 완료 write 시스템 호출이 돌아왔다. 이것이 두 번째로 가장 눈에 띄는 장점입니다. 비동기 쓰기는 데이터가 실제로 디스크에있을 때까지 기다리지 않고 작업을 계속할 수 있으므로 응용 프로그램의 속도를 높입니다. 동일한 종류의 버퍼링 / 캐싱도 최근 또는 자주 읽은 블록이 디스크에서 다시 읽히지 않고 메모리에 유지되는 읽기 작업에 대해서도 구현됩니다.

IO 오류로 인해 쓰기가 실패 할 위험이 있습니까?

반드시 그런 것은 아닙니다. 사용 된 파일 시스템과 중복성에 따라 다릅니다. 데이터를 다른 곳에 저장할 수 있으면 I / O 오류는 무해 할 수 있습니다. ZFS와 같은 최신 파일 시스템은 불량 디스크 블록을 자체 치료합니다. 또한 I / O 오류는 최신 OS와 충돌하지 않습니다. 데이터 액세스 중에 발생하면 영향을받는 응용 프로그램에보고됩니다. 구조적 메타 데이터 액세스 중에 파일 시스템이 위험에 처해 파일 시스템이 위험에 노출되면 읽기 전용으로 다시 마운트되거나 액세스 할 수 없게됩니다.

OS 충돌, 정전 또는 하드웨어 오류가 발생할 경우 약간의 데이터 손실 위험이 있습니다. 이것이 데이터가 디스크에 있는지 100 % 확신해야하는 응용 프로그램 (예 : 데이터베이스 / 금융 응용 프로그램)이 덜 효율적이지만보다 안전한 동기 쓰기를 수행하는 이유입니다. 성능 영향을 완화하기 위해 많은 응용 프로그램은 여전히 ​​비동기 쓰기를 사용하지만 사용자가 명시 적으로 파일 (예 : vim, 워드 프로세서)을 저장할 때 동기화 쓰기를 사용합니다.

반면에, 대부분의 사용자와 응용 프로그램은 동기 쓰기가 제공하는 안전성을 필요로하거나 신경 쓸 필요가 없습니다. 충돌이나 정전이 발생하면 마지막 30 초 동안 최악의 데이터가 손실 될 수 있습니다. 시간이 30 초 이상 걸리는 금융 거래 나 이와 유사한 것이 없다면 (비 현상이 아니라 실제적인) 비동기식 쓰기의 큰 이득은 위험을 크게 능가합니다.

마지막으로 동기 쓰기는 데이터 쓰기를 보호하기에 충분하지 않습니다. 응용 프로그램에서 데이터가 손실되지 않도록 반드시 확인해야하는 경우 화재, 홍수 등과 같은 재해에 대비하기 위해 여러 디스크 및 여러 지리적 위치에 데이터 복제를 수행해야합니다.


답변

쓰기가 완료 될 때까지 실제로 기다릴 필요가없는 프로그램에 속도의 환상을 제공합니다. 파일 시스템을 동기화 모드로 마운트하면 (즉석 쓰기 기능이 제공됨) 모든 것이 느리게 진행됩니다.

때때로 파일은 일시적으로 만 존재합니다 … 프로그램은 약간의 작업을 수행하고 작업이 완료된 직후 파일을 삭제합니다. 당신이 그 글을 연기했다면, 처음에 글을 쓰지 않은 채 도망 칠 수도 있습니다.

IO 오류로 인해 쓰기가 실패 할 위험이 있습니까?

아 절대적으로 이 경우 일반적으로 전체 파일 시스템이 읽기 전용 모드가되고 모든 것이 끔찍합니다. 그러나 일반적으로 성능상의 이점을 잃어 버리는 데는 아무런 의미가 없습니다.


답변

리눅스 이전과 심지어 유닉스 이전에도 비동기식 버퍼 I / O가 사용되었다. 유닉스는 그것을 가지고 있었고 모든 파생물을 가지고 있습니다.

다음은 Ritchie와 Thompson이 CACM 백서 인 UNIX 시간 공유 시스템에 작성한 내용입니다 .

사용자에게는 파일 읽기와 쓰기가 모두 동 기적이며 버퍼되지 않은 것으로 보입니다. 즉, 읽기 호출에서 복귀 한 직후에 데이터를 사용할 수 있으며 반대로 쓰기 후 사용자의 작업 공간을 재사용 할 수 있습니다. 실제로 시스템은 파일에 액세스하는 데 필요한 I / O 작업 수를 크게 줄이는 다소 복잡한 버퍼링 메커니즘을 유지 관리합니다.


귀하의 질문에, 당신은 또한 썼습니다 :

IO 오류로 인해 쓰기가 실패 할 위험이 있습니까?

예, 쓰기에 실패 할 수 있으며 프로그램에서 알지 못할 수도 있습니다. 결코 좋은 일은 아니지만, I / O 오류로 인해 시스템 패닉이 발생하는 경우에는 이로 인한 영향을 최소화 할 수 있습니다 (일부 OS에서는 패키징 대신 시스템을 계속 실행할 수는 있지만 영향을받는 파일 시스템은 마운트 해제 또는 마운트 된 읽기 전용). 그런 다음 해당 파일 시스템의 데이터가 의심스러운 것으로 사용자에게 알릴 수 있습니다. 그리고 디스크 드라이브를 사전에 모니터링하여 증가 된 결함 목록 이 빠르게 증가하고 있는지 확인할 수 있으며 이는 드라이브가 실패했음을 나타냅니다.

BSD는 fsync시스템 호출을 추가하여 프로그램이 진행하기 전에 파일 데이터가 디스크에 완전히 기록되었는지 확인할 수 있었고 후속 Unix 시스템은 동기 쓰기를 수행하는 옵션을 제공했습니다. GNU dd에는 conv=fsync명령이 종료되기 전에 모든 데이터가 기록되도록 하는 옵션 이 있습니다. 버퍼링 된 데이터를 기록하는 데 몇 분이 걸릴 수있는 느린 이동식 플래시 드라이브에 쓸 때 유용합니다.

파일 손상의 또 다른 원인은 갑작스러운 시스템 종료 (예 : 전원 손실)입니다. 사실상 모든 현재 시스템 은 파일 시스템에서 clean / dirty 플래그를 지원합니다 . 쓸 데이터가 더 이상없고 일반적으로 시스템이 종료되는 동안 또는 수동으로 호출하여 파일 시스템을 마운트 해제하려고하면 플래그가 정리 되도록 설정됩니다 umount. fsck파일 시스템이 완전히 종료되지 않은 것을 감지하면 시스템은 일반적 으로 재부팅시 실행 됩니다.


답변

많은 좋은 답변이지만 다른 것을 추가하겠습니다. 유닉스는 다중 프로세스 및 다중 사용자 시스템이므로 잠재적으로 많은 사용자가 (거의) 파일 작업을 수행하려고 할 것입니다. 같은 시간. 네트워크에 마운트 된 오래된 느린 하드 디스크를 사용하면 시간이 오래 걸리고 (기본적으로 프로그램이 잠기고 사용자가 기다려야 함), 읽기 / 쓰기 헤드를 많이 움직입니다. 디스크 앞뒤로.

대신 쓰기 대기중인 파일은 메모리에 잠시 동안 보관되어 디스크에서 종료되어야하는 위치와 버퍼가 가득 찼을 때 정렬 되었거나 디스크 동기화 디먼이 필요한 초 수 (보통 약 30 초라고 생각합니다)-전체 버퍼가 디스크에 “순서대로”쓰여졌습니다. 쓰기 헤드는 하나의 연속 스위핑 동작 만 수행하면됩니다. 그것은 도처에 뛰어 내리는 대신에 갔다.

솔리드 스테이트 장치는 말할 것도없이 오늘날의 빠른 디스크로 꾸준히 증가하면서, 한 번에 한 명의 사용자 만 작업하는 소수의 프로그램 만있는 홈 리눅스 시스템에서는 이득이 훨씬 적습니다.

어쨌든, 요청한 것보다 더 많이 (캐시 / 버퍼로) 읽음으로써 읽기를 예상하고, 쓰기를 기다리는 데이터를 정렬하여 “한 번의 동작”으로 쓰여질 수있었습니다. 실제로는 시간, 특히 많은 사용자들이 읽고 쓰는 시스템이 많은 경우.


답변

Linux에만 국한된 것이 아니며 페이지 캐시 (Linux가 잘 수행하는)라고합니다. 참조 http://linuxatemyram.com/ ; 따라서 파일이 작성되면 몇 초 후에 다시 읽기 때문에 디스크 I / O가 필요하지 않은 경우가 많습니다.

주요 이점은 많은 시스템에 많은 RAM이 있으며 일부는 커널에서 캐시로 사용할 수 있다는 것입니다. 따라서 일부 파일 작업은이 캐싱을 활용합니다. 또한 디스크 I / O 시간은 RAM보다 훨씬 느립니다 (일반적으로 SDD의 경우 수천 번, 기계식 하드 디스크의 경우 거의 백만 배 느립니다).

응용 프로그램 코드는이 캐싱에 대한 힌트를 제공 할 수 있습니다. 예를 들어 posix_fadvise (2) & madvise (2)를 참조하십시오.


답변

회전 플래터가 RAM보다 느립니다. 우리는이 사실을 ‘숨기기’위해 읽기 / 쓰기 캐싱을 사용합니다.

쓰기 IO의 유용한 점은 디스크에서 읽기가 완료 될 때까지 데이터를 사용자에게 반환 할 수없는 읽기와 달리 디스크 IO가 즉시 발생하지 않는다는 것입니다.

따라서 쓰기는 소프트 타임 제약 조건에서 작동합니다. 지속적인 처리량이 디스크의 처리량을 초과하지 않는 한 쓰기 캐시에서 많은 성능 저하를 숨길 수 있습니다.

또한 캐시를 작성해야합니다. 회전 디스크는 비교적 느립니다. 그러나 최신 RAID 유형을 사용하면 작동에 큰 페널티가 있습니다.

예를 들어, 하나의 쓰기 IO를 완료하려면 RAID 6이 다음을 충족해야합니다.

  • 업데이트 블록 읽기
  • 패리티 읽기 1
  • 패리티 2 읽기
  • 새 블록을 쓰다
  • 패리티 쓰기 1
  • 패리티 2 쓰기

따라서 각 쓰기 작업은 실제로 6 개의 IO 작업입니다. 특히 큰 SATA 드라이브와 같은 느린 디스크가있는 경우 비용이 매우 비쌉니다.

그러나 쓰기 쉬운 통합 솔루션이 있습니다. 버퍼에 ‘전체 스트라이프’쓰기를 작성할 수 있으면 디스크에서 패리티를 읽을 필요가 없습니다. 메모리에있는 내용에 따라 계산할 수 있습니다.

더 이상 쓰기 증폭이 없으므로이 작업을 수행하는 것이 매우 바람직합니다. 실제로 RAID 1 + 0보다 쓰기 패널티가 낮아질 수 있습니다.

치다:

RAID 6, 8 + 2-10 스핀들.

쓰기위한 8 개의 연속 데이터 블록-캐시에서 패리티를 계산하고 각 디스크에 하나의 블록을 씁니다. 8 개당 10 개의 쓰기는 1.25의 쓰기 패널티를 의미합니다. RAID 1 + 0의 디스크 10 개는 여전히 쓰기 패널티가 2입니다 (각 서브 미러에 기록해야하기 때문에). 따라서이 시나리오에서는 실제로 RAID 6이 RAID1 + 0보다 나은 성능을 발휘할 수 있습니다. 실제 사용 환경에서는 혼합 IO 프로파일이 조금 더 있습니다.

따라서 쓰기 캐싱은 RAID 세트의 인식 된 성능과 큰 차이를 만듭니다. RAM 속도로 쓰기가 가능하고 쓰기 패널티가 낮으므로 처리량을 늘릴 경우 지속적인 처리량이 향상됩니다.

그렇지 않으면 SATA의 성능 저하로 고통을 겪지 만 6을 곱하고 경합을 추가하십시오. 쓰기 캐싱이없는 10 웨이 SATA RAID-6은 RAID가없는 단일 드라이브보다 약간 빠르지 만 그다지 많지는 않습니다.

주의하십시오. 전원 손실은 데이터 손실을 의미합니다. 캐시 플러시주기, 캐시 배터리 백업 또는 SSD 또는 기타 비 휘발성 캐시를 사용하여이를 완화 할 수 있습니다.


답변

다른 답변들 중 어느 것도 지연된 할당을 언급하지 않았다 . XFS, ext4, BTRFS 및 ZFS는 모두이를 사용합니다. XFS는 ext4가 존재하기 전부터 사용 했으므로 예제로 사용하겠습니다.

XFS 는 쓰기 전까지 데이터를 어디에 둘지 결정하지 않습니다. 할당 지연 은 할당 자에게 결정에 기반을 둔 훨씬 더 많은 정보를 제공합니다. 파일을 처음 작성할 때는 4k 파일인지 1G 및 계속 증가하는 파일인지 알 방법이 없습니다. 어딘가에 10G의 연속 여유 공간이 있으면 4k 파일을 시작 부분에 두는 것은 좋지 않습니다. 큰 여유 공간의 시작 부분에 큰 파일을 넣으면 조각화가 줄어 듭니다.