본문 바로가기

Django

(Django) Django와 PostgreSQL 성능 개선을 위한 7가지 패턴 Django와 PostgreSQL으로 구성된 서비스를 6개월간 최적화를 하면서, 패턴화한 것들을 정리해보고자 합니다. 아래의 9가지 원칙을 반복하면, 점진적으로 시스템을 개선할 수 있습니다. 1. 인덱스 추가하기 2. 인덱스를 잘 타도록 쿼리 개선하기 3. N+1 쿼리 줄이기 4. 불필요한 트래픽 줄이기 5. Transaction은 짧게 유지하기 6. 실시간성이 필요하지 않은 기능은 비동기로 처리하기 7. 캐시 적용하기 1. 인덱스 추가하기 a. 빈번하게 사용되는 검색조건에는 인덱스를 추가해줍니다. 디스크 사용량이 우려된다면, 인덱스 파티셔닝을 적절하게 활용하여 인덱스를 추가하는게 좋습니다. b. FK에 BTREE Index 추가하기 Ruby On Rails와 Django의 마이그레이션은 FK 관계로 설..
(Django) Django에서 비즈니스 로직 관리하기 Django와 Ruby On Rails를 사용하면서, 항상 고민되는 점이 있다. 각 프레임워크에서 비즈니스 로직을 모아두고, 관리하기에 적합한 위치가 어디인가에 대한 점이다. Rails 3/4 버전을 사용하면서, 찾아봤던 글은 레일즈에 Service/Decorator Layer 적용하기에 정리했었다. 이번에는 Django에서 비즈니스 로직을 관리하는 방법에 대해서 정리해보고자 한다. Django에서 비즈니스 로직을 추가할만한 곳은 크게 4가지이다. 그리고 이들 모두 각각 장/단점을 갖고 있다. model view service queryset / manager 1. Model Django에서 제안하는 비즈니스로직 관리 방식은 Model에 기능을 추가하는 것이다. MVC의 기본 설계 패턴은 Fat Mode..
(Django) cached_property 란? 동일한 인스턴스의 Property를 여러번 호출하는 경우, 중복으로 연산작업을 하게 된다. Property 안에서 호출하는 함수가 비용이 큰 연산작업인 경우, 중복 연산 작업이 API 성능을 크게 떨어트릴 수 있다. Django의 cached_property decorator를 사용하면 이러한 이슈를 해결할 수 있다. cached_property는 처음 호출된 Property 함수 결과값을 캐싱해둔다. 그리고 이후에는 캐싱된 결과값을 리턴한다. 그러면 동일한 Property를 여러번 호출하더라도, 한 번의 연산만 하게 된다. Sample from django.utils.functional import cached_property from weather.utils import WeatherAPI from ..
(PostgreSQL) JSON VS JSONB RDB에 JSON 포맷을 저장할 때, 평소처럼 텍스트 포맷으로 저장할지, JSON Format을 적용할지 고민하게 된다. 뫼비우스의 띠 같은 삶을 사는 나는 딱 1년전에도 비슷한 고민을 했었다.( 작년에 조사한 글 : 👉 [MariaDB]RDB 속에서 NOSQL 사용하기 👈)작년에는 리서치만 해보고 말았는데, 올해에는 PostgreSQL에 JSON 타입을 실제로 적용해봐야겠다. 🐜🐜🐜고럼 이만 포스팅 시작~ ㅎ.ㅎ PostgreSQL의 JSON 타입은 크게 2가지이다. JSON, JSONB 두가지 유형이다. JSON Type은 9.4 버전부터 추가되었다. 공통점둘다 JSON 포맷 유효성체크를 한다. 차이점데이터 저장 방식JSON은 들어온 그대로 값을 저장한다. 그런데 JSONB는 그대로 저장하지 않는다...
(Django) Django ORM에서 Row Lock 잡기 - select_for_update Row Lock과 SELECT * FOR UPDATE UPDATE / DELETE 없이, SELECT 만으로 Row Lock을 잡고 싶을 때는, "SELECT * FOR UPDATE" 쿼리를 사용하면 된다. 이렇게 Row Lock을 잡고있는 도중에는 다른 트랜잭션에서 해당 Row를 변경 / 삭제할 수 없다. select_for_update Django에서 SELECT * FOR UPDATE 쿼리를 사용할 때는, Django ORM select_for_update 함수를 사용하면 된다. 이 함수는 항상 transaction과 함께 사용된다. Lock을 잡으려는데, 이미 Lock이 잡혀있는 경우 일반적으로는, 락이 풀릴 때까지 기다린다. ( 이 경우, DB Connection이 무한정 쌓이고 밀릴 수 있다...
(PostgreSQL)Idle in transaction 프로세스 자동으로 죽이기 문제 상황postgresql에서 transaction이 잡혀있지만, 아무것도 하지 않으면, 세션의 상태는 idle in transaction이 된다. 그런데 얘가 connection은 쥐고 있지만, 아무것도 안한다면 서버 자원을 잘 활용하지 못하게 된다. ( 참고 - (Django)PostgreSQL의 Idle In Transaction Connection )그러면 connection이 무한대로 늘어난다거나, connection이 필요한애가 DB를 제대로 활용하지 못하게 될 수 있다. 해결 방법postgresql에는 Idle in transaction이 일정 기간동안 유지되면 자동으로 이 transaction을 죽여주는 기능이 있다. idle_in_transaction_session_timeout 옵션을..
(Django) DB Connection을 관리하는 방법 Connection 재사용 ( Persistent connections ) Django는 데이터베이스에 쿼리를 처음 날리기 전에 Connection을 맺는다. 그리고 커넥션을 계속 열어뒀다가, 다음 요청이오면 이걸 재사용한다. Request가 날라올 때마다 Connetion을 새로 맺는건 부담이 큰 작업이다. 그래서 Django에는 CONN_MAX_AGE라는 설정값이 있다. 여기에 설정된 기간만큼 Connection을 닫지않고, 보존하겠다는 개념이다. 따로 설정해주지 않으면 0으로 설정된다. 즉, Connection을 매번 만들고, 닫겠단 이야기다. 그리고 만약 Connection의 사용기간에 제한을 두고 싶지 않으면, None을 설정해주면 된다. ( Persistent Connections ) Conn..
(PostgreSQL) OOM Killer PostgreSQL 서버에 Out Of Memory가 발생하는 경우, PostgreSQL 자체를 재부팅해야지만 복구할 수 있다. 메모리가 부족해지고, Swap 영역이 증가하게 되면 Linux Kernel의 OOM Killer가 프로세스를 죽이게 된다. 그러면서 부족해진 메모리를 늘리고, Swap 영역을 줄인다. 이러면, 서버에 접속할 수 없는 수준으로 서버가 고장나는 일은 막을 수 있다. 그러나 OOM Killer가 Session을 죽이면서, DB Connection이 제 멋대로 끊길거다. PostgreSQL: SSL SYSCALL error: EOF detected 그러면 PostgreSQL에서 이런 에러가 내뱉어지면서, PostgreSQL을 사용하는 앱에서는 에러가 마구 날거다. 이 경우, Postg..