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 파일을 시작 부분에 두는 것은 좋지 않습니다. 큰 여유 공간의 시작 부분에 큰 파일을 넣으면 조각화가 줄어 듭니다.