Primary Key Tsid 도입기 #54
morenow98
started this conversation in
backend-tech
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Auto Increment
팀원들이 보통 Entity의 키를 결정하던 방식은 Auto Increment 였다. 기본 설정도 이와 같다. 이 방법의 장단점을 분석해보았다.
장점
Clustered Index
Primary Key는 MySQL에서 Clustered Index 로 설정된다. Clustered Index로 설정된다는 건, 데이터의 물리적인 위치가 PK의 순서로 결정된다는 것이다. 이 부분에서 Auto Increment는 다음 2가지의 장점을 가지게 된다.
WAS가 여러 개 있을 경우
WAS가 여러 개 있고 WAS에서 PK를 결정하게 된다면 DB에 insert시 충돌이 될 수도 있고, 물리적인 위치가 모두 수정될 위험도 있다.
단점
보안
예를 들어, jabiseo.com/members/{memberId} 로 멤버 페이지를 접속하는 경우를 생각해보자.
만약 회원가입시 내게 부여된 memberId 가 30이라면 이 사이트의 회원이 30명이라는 사실을 간접적으로 알 수 있다.
또한, jabiseo.com/members/29 로 간단하게 접속하면 다른 멤버의 페이지에 접속할 수도 있다. 물론 기본적으로 접속할 수 없게 해야 하겠지만 이 허점도 전부 막아야 더욱 좋을 것이다.
성능
만약 많은 인원들이 북마크를 동시에 많이 한다면, 수많은 데이터가 insert 될 것이다. 이 때, PK를 설정하는 과정에서 DB에 더 긴 Lock이 걸리게 된다. 또한 여러 테이블이 외래키로 연결된 경우라면 연쇄적으로 많은 테이블에 Lock을 걸고, 해제하는 과정이 반복될 것이다.
따라서 DB에게 PK를 결정하도록 하는 것은 특정 상황에서 성능에 문제가 생길 수 있다.
충돌
만약, 여러 DB가 Auto Increment하는 대규모 분산 시스템에서는 각 DB가 독립적으로 PK를 생성하기 때문에 충돌이 일어날 가능성이 있다.
해결방안
장점은 그대로 가져가되, 단점은 해결할 방법을 찾아보자.
해결방안 1. UUID
DB에게 PK를 결정하지 않게 하고, 보안적인 문제도 해결하기 위해 WAS에서 PK를 결정해 직접 넣어주기로 했다.
따라서 기본적인 UUID를 우선 생각해볼 수 있다.
PK값이 수정될 가능성도 없고, UUID가 충돌될 가능성도 굉장히 적다. 하지만 다음의 단점이 있다.
해결방안 2. 티켓 서버
PK만을 생성하는 서버를 둔다. 구현하기 쉬울 수도 있지만, SPOF가 발생한다. 이를 해결하기 위해서 티켓 서버를 여러 대 둔다면 또 다른 동기화 문제가 발생한다.
https://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/
해결방안 3. Tsid
Twitter의 Snowflake와 ULID를 합친 ID 생성기이다.
https://github.com/ulid/spec
Twitter Snowflake
위의 모든 것들을 해결하기 위해 WAS에서 PK를 결정하지만, 다음과 같이 64비트의 값으로 PK를 생성한다.
이 원리를 이용해 Tsid는 만들어졌다. 이제 처음의 장점은 모두 취하고, 단점은 모두 해결했다.
관련 라이브러리를 설정한 후 다음과 같이 적용하면 된다.
주의해야 할 점
JavaScript/ECMAScript 수준의 정밀도에는 정수의 경우 53비트로 제한되어 있다.
기존 Auto Increment의 경우 53비트를 넘을 경우가 거의 없어 괜찮았지만, Tsid는 64비트를 모두 사용해 문제가 생길 수 있다.
따라서 Response해줄 때 Long을 String으로 바꿔서 전달하는 방식을 사용했다.
Beta Was this translation helpful? Give feedback.
All reactions