해당 컨텐츠는 주간동안 읽은 아티클 중 일부를 정리한 내용입니다.
MySQL
에서 UUID
를 PK
로 사용할 경우 성능저하가 있을 수 있다. MySQL
에서 PK
는 클러스터 인덱스이기 때문에 항상 정렬된 상태를 유지한다.
따라서 무작위로 생성되는 UUID
의 경우 삽입시마다 정렬이 이루어지기 때문에 삽입시 성능저하와 세컨더리 인덱스들이 PK를 함께 저장함으로 인덱스 크기도 커진다.
속도 저하는 PK가 아니라 유니크 인덱스를 걸더라도 비슷한 정도의 성능 이슈가 발생 할 수 있다.
회사에서 PK
로 UUID
를 사용하고 있는 테이블이 있어, 관련 내용을 회의 때 Rasing 했다. 이후 팀원들이 좋은 글들을 여러 공유해주었는데 그중 위 글이 인상깊어 기록한다.
위 아티클은 UUID
를 PK
로 가져갈 때의 발생하는 이슈들을 최적화 할 수 있는 방법에 대해 서술하고 있다.
간단히 요약하면, UUID version 1
은 타임스탬프를 기반으로 생성되는데, 이 순서를 생성하는 시점에 바꾼다. 이 순서를 조작해 타임스탬프 부분을 앞쪽으로 땡겨 어느정도 정렬된 UUID
를 사용함으로서 성능상 이점을 얻을 수 있다.
Auto-Increment
를 PK로 사용시 Spring Data Jpa
에서 Repository
의 save
를 호출하면 현재 최대 PK값
을 가져오기 위해 추가 쿼리가 발생함을 삽질 끝에 내부 코드를 뜯어보며 확인했다.
그러고보니 Insert
상황에서는 save
와 saveAndFlush
가 차이가 없지 않을까는 생각이 들었다.
만약 그렇지않다면, save
를 호출 할 때 Flush
가 되지 않아 DB에는 반영이 되지 않은 상태라 PK 경합
이 발생한다.
역시나 찾아보니 삽입 상황에서는 두 메소드는 동일하게 동작하는 것으로 확인됬다. 실제로 로그를 찍어보아도 Flush 됨을 확인 할 수 있다.
참고 - https://docs.jboss.org/hibernate/core/4.3/manual/en-US/html/ch11.html#objectstate-flushing
사내에 Redis 캐시를 메뉴얼하게 삽입하고, Django 서버에서 값을 읽어야 하는 요구사항이 생겨, 관련 작업하던 중에 캐시 값을 제대로 읽어오지 못하는 이슈가 발생했다.
Redis에 접속해서 값을 확인해보니 Django 서버에서 넣어준 키값 앞에 :1:
prefix가 붙어 있었던 것이 원인이었다.
이것의 정체는 Cache Versioning으로 장고에 캐시에 저장하는 특정 오브젝트를 버저닝하기 위한 용도로 사용하는 것임을 해당 아티클을 통해 확인 할 수 있었다.
캐시 버저닝을 통해 장고에서 캐시 값을 가져 올 때,
version
파라미터를 통해 이전 버전의 오브젝트를 가지고 올 수 있다.
위 아티클을 통해 엔진엑스 구조와 설정을 대략적으로 알아볼 수 있다. 인상적이었던 점은 마스터 프로세스와 워커구조와 이벤트 드리븐 방식을 활용한다는 것이었는데, 이 부분은 시간이 나면 깊게 파보고 싶다.
지난 주 공모 첫 날, 일시적으로 서버가 장애 상황이 발생했는데, nginx
에서 50x
응답들이 HTML 형식으로 내려가, 클라이언트의 Json Parsing Error
가 유저까지 노출되었다.
nginx.conf
의 간단한 변경을 통해 해당 이슈를 해결할 수 있었다.
지난 주말부터 Spring
으로 작은 프로젝트를 진행하고 있다. 오랜만에 접하는 Spring
인지라 Lombok
이 가물가물 해서 다시한번 읽어봤다.
내용을 간단히 요약하면 아래와 같다.
@ToString
로 인한 순환참조 발생A.toString
-> B.toString
-> A.toString
으로 인해 순환참조 발생protected
의 기본 생성자가 반드시 필요 -> @NoArgsConstructor(access = AccessLevel.PUBLIC)
를 통해 접근 권한을 최소화하여 객체 생성시 안전성을 보장하자.@Builder
사용시 @AllArgsConstructor
로 인해 모든 인자를 가지는 생성자 발생 -> 필요한 인자만 받는 생성자를 지정하고 해당 생성자 위에 @Builder
를 사용