2009-05-12 5 views
5

나는 사용자가 파일을 업로드 할 수있게 해주는 장고 응용 프로그램을 만들고 있습니다. Amazon S3로 보내기 전에이 파일들에 대해 서버 측 처리를 수행해야합니다. this questionthis blog post에 대한 응답을 읽은 후이를 처리 할 가장 좋은 방법은 내 뷰 핸들러가 Pyro 원격 객체의 메서드를 호출하여 비동기 적으로 처리를 수행 한 다음 즉시 HTTP 200을 클라이언트에 반환하는 것입니다. 나는이 프로토 타입을 가지고 잘 작동하는 것 같다. 그러나 클라이언트가 애플리케이션을 폴링하여 파일이 처리되고 S3에 업로드되었는지 확인할 수 있도록 처리 상태를 저장하려고한다.Django에서 실행 된 장기 실행 프로세스의 상태를 어떻게 저장해야합니까?

폴링을 쉽게 처리 할 수 ​​있지만 적절한 위치가 프로세스 상태를 저장하는 위치가 확실하지 않습니다. Pyro 프로세스가 쓰기 가능하고 내 폴링보기에서 읽을 수 있어야합니다.

  • 실제로 30-60 초 동안 지속되어야하는 데이터에 대해 데이터베이스에 열을 추가하는 것을 주저합니다.
  • 나는 장고의 low-level cache API을 사용하고 키로 파일 ID를 사용하는 것을 고려해 봤지만 이것이 캐시 프레임 워크가 무엇을 위해 설계되었는지는 믿을 수 없다. 그리고 예상치 못한 문제가 무엇인지 잘 모르겠다. 노선.
  • 마지막으로 Pyro 객체에 처리 상태를 저장하는 것을 고려해 보았지만 여전히 불린 "processing_complete"데이터베이스 열을 추가해야만보기가 Pyro에서 상태를 쿼리할지 여부를 알 수 있습니다. 목적.

물론 데이터베이스에서 디커플링 상태와 관련된 데이터 무결성 문제가 있습니다 (서버가 다운되어이 모든 데이터가 메모리에있는 경우 어떻게됩니까?). 나는 노련한 웹 응용 프로그램 개발자들이 이러한 종류의 상태 저장 처리를 처리 할 수있는 방법에 대해 듣고 자합니다.

답변

6

데이터베이스에 "요청"테이블이 있습니다.

업로드가 도착하면 업로드 된 File 객체를 만들고 요청을 만듭니다.

백그라운드 배치 프로세서를 시작합니다.

우리는 200 개의 "작업 중"페이지를 반환합니다 - 요청과 상태를 보여줍니다.

우리의 배치 프로세서는 Django ORM을 사용합니다. 완료되면 Request 오브젝트를 갱신합니다. 이메일 알림을 보낼 수는 있습니다. 주로 사용자가 다시 로그인하여 처리가 완료된 것을 볼 수 있도록 상태를 업데이트합니다.


배치 서버 아키텍처 노트.

WSGI 서버는 일괄 처리 요청을 위해 포트에서 대기합니다. 요청은 ID 번호가있는 REST POST입니다. 배치 프로세서는 이것을 데이터베이스에서 찾아서 처리합니다.

서버는 REST 인터페이스에 의해 자동으로 시작됩니다. 실행 중이 아니면 스폰합니다. 이렇게하면 사용자 트랜잭션이 느려지 게되지만 잘됩니다. 추락하지 않아야합니다.

또한 crontab이 실행 중인지 확인하는 간단한 crontab이 있습니다. 기껏해야, 30 분 동안 "당신은 살아 있습니까?" 체크 무늬.우리는 정식 시작 스크립트 (mod_wsgi를 사용하여 Apache에서 실행)를 가지고 있지 않지만 WSGI 파일을 다루는 "restart"스크립트를 생성 한 다음 상태 검사를 수행하는 URL에 POST를 수행합니다. 배치 프로세서).

배치 서버가 시작되면 결코 처리되지 않은 요청이있을 수 있습니다. 따라서 기본 시작은 요청 대기열에서 모든 작업을 끌어내는 것입니다. 뭔가 빠졌을 수 있다고 가정합니다.

+0

이 밤새 생각한 후에 나는 당신이 절대적으로 옳다고 결정했습니다. 데이터베이스를 사용하지 않는 것이 의미가 없습니다. 나는 또한 Pyro가 여기에 적합하지 않다고 결정했다. 그리고 나는 정상적인 사람들이하는 일을하고 잠금 파일로 cron 작업을 사용해야 만한다. – bouvard

+0

우리는 cron을 사용하지 않습니다. 우리는 작은 WSGI 서버로 배치 시스템을 가지고 있으며 urllib2로 HTTP 요청을 만들어 깨우려고합니다. WSGI 요청에서 요청 ID를 가져옵니다. 일반 Django ORM으로 세부 사항을 가져옵니다. –

+0

이것은 Pyro와는 일종의 계획 이었지만 예측할 수없는 문제는 서버가 갑작스럽게 중단되어 문서가 절반 처리되고 처리를 다시 시작할 수있는 새 요청 메시지가 없을 수 있다는 것입니다. 크론 작업을 사용하면 요청 테이블에서 이전에 수행되지 않은 10 개의 미완료 작업을 선택할 수 있다는 것을 알았습니다. 중단 중에 중단 된 작업을 픽업합니다. – bouvard

1

그래서 필요한 작업 대기열입니다. 귀하의 경우, 비록 그 주들이 오래 살지 않더라도, 나는 상태를 저장하기 위해 절대적으로 DB와 함께 갈 것입니다. 그것은 당신의 모든 요구 사항을 충족 시키며 이미 구현 가능한 모든 움직이는 부분을 가지고 있으므로 구현하기가 어렵지 않습니다. 뭔가 더 복잡한 것이 필요한 경우가 아니면 간단하게 유지하십시오.

더 강력하거나 세련된 것이 필요한 경우 Gearman과 같은 것을 보겠습니다.

5

나는이 질문이 오래된 것임을 알고 있지만, 누군가는 내 대답이이 시간 이후에도 유용하다는 것을 알 수 있으므로 여기에 간다.

물론 데이터베이스를 대기열로 사용할 수 있지만 그 목적으로 정확하게 개발 된 솔루션이 있습니다.

AMQP이 적합합니다. Celery 또는 Carrot과 함께 브로커 서버 (예 : RabbitMQ 또는 ZeroMQ).

우리가 최신 프로젝트에서 사용하고있는 작업 중 하나입니다.

문제가 있으면 Celery와 RabbitMQ가 가장 적합하다고 생각됩니다. RabbitMQ는 메시지의 지속성을 제공하며 Celery는 폴링에 대한보기를 쉽게 표시하여 병렬로 실행되는 프로세스의 상태를 확인합니다.

당신은 또한에 관심이있을 수 있습니다 octopy.

관련 문제