2013-04-16 4 views
6

내가 루비 (2.0.0 p39474)에서 매우 빠른 파일 액세스를 수행하고,루비 파일 핸들 관리 (너무 많이 열려있는 파일)

Too many open filesthis thread 보았다면서 예외를 받고 계속하고, here, 다양한 다른 소스 , 나는 OS 제한을 잘 알고있다 (내 시스템에서는 1024로 설정).

액세스가 mutexed되어이 파일을 수행하고 형식을 취 내 코드의 일부 : filename이 섹션을 호출하는 스레드에 따라 신속하게 변경 될 수 있습니다

File.open(filename, 'w'){|f| Marshal.dump(value, f) } 

합니다. 이 형식이 블록 이후에 파일 핸들을 포기한다는 것은 내 이해입니다.

ObjectSpace.each_object(File)을 사용하여 열려있는 File 개체의 수를 확인할 수 있습니다. 이 보고서에는 메모리에 최대 100 명의 상주 인구가 있지만 예상대로 한 사람 만 공개됩니다.

또한 예외 자체는 ObjectSpace에 의해보고 된 개체 수가 10-40 인 경우에 발생합니다. 또한 수동으로 가비지 수집을 수행하면이 카운트가 향상되지 않으며 sleep 호출을 삽입하여 스크립트 속도가 느려집니다.

내 질문은 따라서이다 :

  • 오전 나는 근본적으로는 프로세스의 전체 수명을 포함하고 있는가 --- OS에 제한의 성격을 오해?
    • 그렇다면 ulimit -n 개 파일에 액세스 한 후 웹 서버가 어떻게 충돌하지 않도록합니까?
    • ruby가 객체 시스템 외부에서 파일 핸들을 유지하고 있거나 '동시'액세스를 계산할 때 커널 속도가 너무 느립니 까?

편집 20,130,417는 : strace 루비가 돌아 그렇게하기 전에 뮤텍스를 해제, 파일에 모든 데이터를 기록하지 않음을 나타냅니다. 따라서 파일은 OS 제한까지 스택을 처리합니다. 이 문제를 해결하기위한 시도에서

, 나는/sysreadsyswrite, 동기 모드를 사용하고, close 전에 flush라고했다. 이 방법들 중 어느 것도 효과가 없었습니다.

내 질문에 다음과 같이 수정되었습니다 : 루비가 파일 핸들을 닫지 못하는 이유는 무엇입니까?

답변

3

사용 DTrace를 또는 strace를이든 상응하는 시스템에, 그리고 파일이 열리는 것을 정확히 알아보십시오.

소켓 일 수 있습니다.

붙여 넣은 코드가 적어도 이상한 동시성 버그가 없는데도이 문제를 일으킬 수있는 것 같지 않습니다.

+0

'strace'는 루비가 파일을 열고, 그 함수에서 돌아와서 데이터가 쓰여지기 전에 뮤텍스를 해제한다는 것을 나타냅니다. 경우에 따라서는 플러시되지도 않고 예외 (예 : 종료 중) 후에 리소스를 닫을 때 디스크에 쓰는 경우도 있습니다. –