2012-12-31 2 views
3

대부분의 도메인 특정 모델에 대해 NoSQL 데이터 저장소를 사용할 REST 중심 응용 프로그램을 만들고 있습니다. REST 데이터 프레임 워크를 중심으로 구축 할 기본 사이트의 경우 사용자, 청구 정보 및 도메인 데이터 모델의 범위를 벗어나는 기타 메타 데이터에 대해 기존의 관계형 데이터베이스를 계속 사용하고자합니다.Django 세션을 사용하여 로그인 한 사용자 저장

가능한 한 같은 요청으로 RDBMS 및 NoSQL 데이터 저장소 모두에 대한 I/O 수행을 피할 수 있다면이 접근법은 좋은 생각 일뿐입니다.

내 질문 :

  1. 이 좋은 충고인가? (나는 가정하고 있지만 첫 번째 전제가 틀리면 나머지 질문은 쓸모가 없다.)
  2. 가능한 한 로그온 한 사용자를 캐시하고 싶습니다. Django 세션을 사용하여 안전하고 신뢰할 수 있으며 올바른 방식으로이를 수행 할 수 있습니까? 이상적으로는 세션 API를 가능한 한 사용자 테이블과 거의 상호 작용하지 않고 현재 사용자를 검색하기위한 안전한 드롭 인 대체품으로 만들고 싶습니다. 모든 것을 연결하기 위해해야 ​​할 일은 무엇입니까?
  3. 너무 많은 번거 로움이 생기면 django-nonrel을 사용하지 않고 NoSQL 저장소에 사용자 정보를 저장하는 것 (즉, RDBMS를 완전히 제거하는 것)이 얼마나 쉬운가요? 커스텀 인증/권한 부여 백엔드가 이것을 할 수 있습니까?

답변

4

내 응용 프로그램에 대해 동일한 접근 방식을 사용하여 숙고하고 있지만 일반적으로 안전하다고 생각하지만 캐시 일관성 문제를 해결하려면 특별한주의가 필요합니다.

장고가 정상적으로 작동하는 방식은 요청이 수신되면 세션 테이블에 대해 쿼리를 실행하여 요청의 쿠키와 연결된 세션을 찾습니다. 그런 다음 request.user에 액세스하면 사용자 테이블에 대해 쿼리가 실행되어 특정 세션에 대한 사용자를 찾습니다 (있는 경우 Django가 익명 세션을 지원하기 때문에). 따라서 기본적으로 Django는 각 요청을 사용자와 연관시키기 위해 두 가지 쿼리가 필요합니다. 이는 비쌉니다.

Django 세션에 대한 좋은 점은 모델 클래스를 확장하지 않고도 키 저장소로 사용할 수 있다는 것입니다 (예 : 추가 필드로 확장하기 어려운 사용자 클래스와 달리). 따라서 예를 들어 request.session['email'] = user.email을 입력하면 세션에 추가 데이터를 저장할 수 있습니다. 이것은 어떤 의미에서는 request.session 사전에서 읽은 것이 무엇을 넣었는지 확실히 알고 있기 때문에 클라이언트는이 값을 변경할 수있는 방법이 없습니다. 따라서이 기술을 사용하여 User 테이블에 대한 쿼리를 피할 수 있습니다.

세션 테이블에 대한 쿼리를 피하려면 세션 캐시를 활성화하거나 클라이언트 쿠키의 세션 데이터를 django.contrib.sessions.backends.signed_cookies으로 저장해야합니다. 클라이언트의 수정으로부터 암호로 보호되기 때문에 안전합니다.

캐싱을 사용하면 사용자 데이터와 요청을 연결하기 위해 0 개의 쿼리가 필요합니다. 그러나 문제는 캐시 일관성입니다. 쓰기 캐시 옵션 (django.core.cache.backends.locmem.LocMemCachedjango.contrib.sessions.backends.cached_db)을 사용하여 메모리 캐시에서 로컬 캐시를 사용하는 경우 세션 데이터는 각 수정시 DB에 기록되지만 캐시에있는 경우 DB에서 읽지 않습니다. Django 프로세스가 여러 개있는 경우이 문제가 발생합니다. 한 프로세스가 세션을 수정하면 (예 : session['email'] 변경) 다른 프로세스는 이전의 캐시 된 값을 계속 사용할 수 있습니다.

공유 캐시 (Memcached 백엔드)를 사용하여 해결할 수 있습니다.이를 통해 한 프로세스에서 수행 한 변경 사항을 다른 모든 프로세스에서 볼 수 있습니다.이런 식으로 Memcached 백엔드에 대한 요청으로 세션 테이블에 쿼리를 대체하는 것이 훨씬 빨라졌습니다.

클라이언트 쿠키에 세션 데이터를 저장하면 캐시 일관성 문제도 해결할 수 있습니다. 쿠키의 전자 메일 필드를 수정하면 클라이언트가 보내는 모든 향후 요청에 새 전자 메일이 있어야합니다. 클라이언트는 의도적으로 이전 쿠키를 보낼 수 있지만 여전히 오래된 값을 전달합니다. 문제인지 여부는 응용 프로그램에 따라 다릅니다.

+0

와우, 아주 좋은/철저한 대답, 감사합니다. +1. 나는 확실히 생산에서 memcached를 사용하려고 생각했다. 개발을 위해 로컬 사용자가있는 로컬 서버에서 로컬 인 메모리 캐시를 사용하는 것으로 충분합니까? (그 시나리오에 단 하나의 장고 프로세스가 있기 때문에) –

+0

그리고 또 하나의 질문 - 로그인 한 사용자에 해당하는 전체'User' 모델 *을 세션에 저장하고 싶다면 그 작업이 필요한가요? 먼저 직렬화할까요? –

+0

@PlatinumAzure Django 개발 서버의 경우 로컬 캐시가 충분해야합니다. 이 문제는 여러 작업자가있는 서버를 사용할 때 발생합니다 (예 : -w 매개 변수가있는 gunicorn). 사용자 사전을 세션 사전에 넣는 것이 효과적 일지는 모르겠지만 실제로는 필요 없을 것입니다. 사용자가 올바르게 serialize 및 deserialize되어 있지만 액세스시 사용자 테이블에 대해 쿼리가 실행되므로 캐싱의 이점이 손실됩니다. 내 응용 프로그램의 경우 수동으로 User 개체의 모든 관련 필드를 세션 사전에 복사하고 업데이트 할 계획입니다. –

관련 문제