안녕하세요. 현재 문제가 되는 상황 첨부된 사진과 같습니다. 스택과 메세지로 봤을 때

 
Jae-bong Jeong

안녕하세요.

현재 문제가 되는 상황 첨부된 사진과 같습니다.

스택과 메세지로 봤을 때 소켓이 지나치게 많이 열려 발생하는 문제이고 아직 개발 중이기 때문에 실제 커넥션이 많아서 발생하는 문제는 아닌 것을 알고 있습니다.

구글에서 검색해본 결과로는 특정 쿼리에서 문제가 발생하고 커넥션이 정상적으로 종료되지 않은 상태로 유지가 되어서 발생하는 문제 정도로만 추측을 하고 있습니다.

실제 ensure_connection에서 하는 일도 위에서 서술한 내용과 같은 것이 connection이 존재하면 사용하고 존재하지 않으면 connect 함수를 호출하여 새로 connection을 맺는 것이 전부입니다.

아마 이 문제 자체는 장고(그 중에서 Tastypie)의 결함은 아닐 것이 분명하기에 문제를 해결하고자 질문을 올린 것은 아니고요.

이런 DB와 관련한 문제가 발생하였을 경우에는 일반적으로 어떻게 해결하나 궁금해서 질문을 올립니다.

스크립트 언어에 익숙하지도 않은 상태에서 여러 요인이 많은 DB와 엮인 문제가 발생하니 찾기가 어렵네요.

스택 전부를 보더라도 평범하게 조회하는 쿼리여서 더 원인을 알기 어렵습니다.

다른 분들의 경험담을 들어보고 싶습니다.


  • Donghyun Cho

    소스 코드를 보면 도움이 될 듯 한데.. 없으니 우선 간단히 기본적인 설명만 드릴께요.. 이미 아시면 패스~

    Donghyun Cho

    tastypie는 Resource간의 relationship이 있으면 queryset에 따라 연결된 resource에 대한 데이터를 가져오기 위하여 db 를 한 번 실행 합니다. 쉽게 설명을 드리면, pizza라는 Resource가 있고, PIzza list를 출력을 하려 하는데 topping이란 Resource와 연결이 되어 있다고 가정합니다. 그럼 각 pizza record별로 연결된 topping이 같거나 다르겠죠? 그럼 tastypie가 각 record별로 topping에 대한 데이터를 가져오기 위하여 db에 엑세스를 해서 데이터를 로드하게 됩니다. 이 문제를 해결하기 위해선 queryset에 select_related()나 prefetch_related()를 사용하면 한 번의 db 연결로 연결된 데이터들을 다 갖고 와서 메모리에 로드한 후 사용하게 됩니다. 머 다른 case들이 있긴 한데 이 부분이 가장 많이 일어나는 issue인 듯 해요. 아차 이 부분은 tastypie뿐만 아니라 일반적으로 모든 queryset에 해당하는 부분입니다.

    Donghyun Cho

    참고로.. 코드에 loop이나 recursive가 있고 파일을 직접 건드린다면 같은 증상이 나타날 수 도 있어요. 파일을 사용하실 땐 꼭 with 문을 사용하시기 바랍니다. 또한 exception이 발생할 경우를 대비해 finally:에서 파일을 꼭 닫아주세요.

    Donghyun Cho

    tastypie에서 문제가 되는 부분은 POST, PUT, PATCH와 같이 데이터를 저장할 때 연결된 Resource들을 같이 저장하는 나쁜 습관이 있는데요.. 이건 API를 디자인 할 때 많이 신경써서 해결해야 하는 부분이고, 강제로 이 부분을 bypass할 수 있습니다. Performance를 높일 수 있는 부분들이 여기 저기 좀 있네요..

    Donghyun Cho

    아차.. django-debug-toolbar를 이용하면 디버깅하는데 스트레스 덜 받습니다. https://github.com/django-debug-toolbar/django-debug-toolbar

    Jae-bong Jeong

    친절한 답변 매우매우 감사합니다.

    외부에서 휴대폰으로 두 번째 답변보고서는 번뜩하고 떠올랐네요. Relationship 때문에 순환 구조가 되어버린 상황을 몇 번 목격했었던 것 같습니다. 제가 작성한 코드는 아니고 Stackoverflow 같은 곳에서요.

    저도 쿼리문을 직접 작성해왔었는데 Tastypie나 Django에서 쿼리하는 방식이 좀 과하다는 생각이 들 때가 많았습니다. 고민을 하면서 짜고 있는데 한계가 있어 좀 답답하더라고요.

    Donghyun Cho

    혹시 문제가 resource업뎃 시 m2m 연결된 부분에서 발생하고, 해당 resource에서 그 field를 업뎃하지 않아도 되는 상황이면 m2m field에 read_only=True로 해보세요. 왠만하면 relationship이 있는 field들은 read only로 디자인 하는게 architecture와 성능면에서도 좋습니다.

Advertisements