C 프로그램은 Mac OS X Snow Leopard에서 디스크 I/O를 수행하는 동안 무정 상태 대기에 고정되어 있습니다.

StackOverflow https://stackoverflow.com/questions/2017283

  •  19-09-2019
  •  | 
  •  

문제

배경의 한 줄 : 저는 개발자입니다 NOSQL 데이터베이스 인 Redis. 내가 구현하고있는 새로운 기능 중 하나는 Redis가 메모리에서 모든 데이터를 가져 오기 때문에 가상 메모리입니다. VM 덕분에 Redis는 거의 사용하지 않는 객체를 메모리에서 디스크로 전송할 수 있습니다. OS가 미국 교환을 위해 작업하는 것보다 훨씬 더 잘 작동하는 데는 여러 가지 이유가 있습니다 (Redis 객체는 연속적으로 할당 된 많은 작은 물체로 구축됩니다. 장소, Redis에 의해 디스크로 직렬화되면 거주하는 메모리 페이지에 비해 10 배 적은 공간을 취합니다).

이제 저는 Linux에서 완벽하게 작동하지만 Mac OS X Snow Leopard에서는 잘 작동하지 않는 알파 구현입니다. 때때로 Redis가 메모리에서 디스크로 페이지를 이동하려고하는 동안 Redis 프로세스는 몇 분 동안 무질서 대기 상태로 들어갑니다. 이것을 디버깅 할 수 없었지만 이것은 전화로 발생합니다. fseeko() 또는 fwrite(). 몇 분 후 전화가 마침내 돌아오고 Redis는 문제없이 계속 일합니다 : 충돌 없음.

전송 된 데이터의 양은 다음과 같습니다 매우 작고 256 바이트와 같은 것. 따라서 매우 많은 양의 I/O의 문제가되어서는 안됩니다.

그러나 쓰기 작업의 대상이되는 스왑 파일에 대한 흥미로운 세부 사항이 있습니다. 큰 파일 (26 기가 바이트)으로 파일을 열었습니다. fopen() 그런 다음 사용을 확대했습니다 ftruncate(). 마지막으로 파일이 있습니다 unlink()Redis가 계속 참조 할 수 있도록 Ed는 Redis 프로세스가 종료되면 OS가 실제로 스왑 파일을 제거 할 것이라고 확신합니다.

좋아, 그게 전부이지만 나는 더 자세한 내용을 위해 여기에 있습니다. 그리고 BTW는 Redis Git에서 실제 코드를 찾을 수 있지만 상당히 복잡한 시스템이라는 점에서 5 분 안에 이해하는 것은 아닙니다.

도움을 주셔서 대단히 감사합니다.

도움이 되었습니까?

해결책

내가 이해 한 바와 같이, HFS+는 희소 파일에 대한 지원이 매우 좋지 않습니다. 따라서 쓰기가 파일의 많은 부분을 초기화/구체화하는 파일 확장을 트리거 할 수 있습니다.

예를 들어, 나는 새로운 큰 빈 파일을 mmap'ing에 넣은 다음 몇몇 임의의 위치에 쓰면 HFS+가있는 디스크에서 매우 큰 파일을 생성한다는 것을 알고 있습니다. MMAP 및 Sparse 파일은 데이터를 사용하는 매우 편리한 방법이므로 사실상 다른 모든 플랫폼/파일 시스템이이를 우아하게 처리하기 때문에 매우 성가신 일입니다.

스왑 파일이 선형으로 기록됩니까? 즉, 기존 블록을 교체하거나 끝에 새 블록을 작성하고 여유 공간 포인터를 증가시킵니다. 그렇다면 파일을 확장하기 위해 더 자주 작은 ftruncate 호출을 수행하면 일시 정지가 짧아집니다.

제쳐두고, Redis VM이 MMAP를 사용하지 않는 이유가 궁금한 점이 있고 뜨거운 블록을 뜨거운 페이지로 집중시키기 위해 블록을 이동합니다.

다른 팁

Antirez, 내 Apple 경험이 Apple ][, 그러나 나는 그것을 샷을 줄 것이다.

첫 번째는 질문입니다. 가상 메모리의 경우 작동 속도가 디스크 공간보다 더 중요한 측정 값이라고 생각했을 것입니다 (특히 속도가 요점 인 NOSQL DB의 경우 SQL을 사용하지 않습니까?). 그러나 스왑 파일이 26g이면 :-)

시도해야 할 것들 (가능하면).

  1. 실제로 문제를 찾거나 글을 분리하십시오. 나는 최악의 경우 버퍼 포인터 변경이되어야하기 때문에 추구가 오래 걸릴 수 있다고 믿기 힘들다. 그래도 OSX를 쓰지 않았으므로 확실하지 않습니다.
  2. 스왑 파일의 크기를 조정하여 문제가 발생하는지 확인하십시오.
  3. 스왑 파일을 동적으로 확장 한 적이 있습니까 (사전 할당과 달리)? 당신이 그렇게한다면, 그것은 문제를 일으키는 것일 수 있습니다.
  4. 당신은 항상 당신이 할 수있는만큼 파일에 낮은 글을 쓰나요? 26G 파일을 생성하면 실제로 데이터를 채우지 않을 수 있지만,이를 작성하면 마지막 바이트에 쓰기를하면 OS가 바이트를 제로화해야 할 수도 있습니다 (초기화를 연기).
  5. 전체 파일을 미리 할당하고 (모든 바이트에 쓰기) 만족하지 않으면 어떻게됩니까? 다시 말해, 프로그램 실행 사이에 파일을 남겨 두십시오 (물론 존재하지 않으면 생성). 그런 다음 Redis의 시작 코드에서 파일 (포인터 등) 만 초기화하십시오. 위의 4 지점에있는 문제와 같은 문제를 제거 할 수 있습니다.
  6. 다양한 BSD 사이트에 대해서도 문의하십시오. 나는 표지 아래에서 Apple이 얼마나 많이 바뀌 었는지 잘 모르겠지만 OSX는 가장 낮은 수준에서 BSD 일뿐입니다 (Pax Ducks for Covers).
  7. 또한 애플 사이트에 물어 보는 것을 고려하십시오 (아직 그렇게하지 않은 경우).

글쎄, 그것은 나의 작은 기여입니다. 프로젝트에 행운을 빕니다.

파일에 대한 파일 캐싱을 끄셨습니까? IE fcntl (fd, f_global_nocache, 1)

DTRACE 및 OR 악기 (Apple의 실험적 DTRACE 프론트 엔드)로 디버깅을 시도해 보셨습니까?

dtrace와 함께 표범 탐험

OS X에서 크롬 디버깅

Linus가 GIT 메일 링리스트에서 한 번 말했듯이 :

"OS X 사람들은 그것을 받아들이는 데 어려움을 겪고 있지만 OS X 파일 시스템은 일반적으로 Windows보다 훨씬 더 많은 문제입니다."

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top