b

LINE 앱 ID Generator (snowflake) 본문

카테고리 없음

LINE 앱 ID Generator (snowflake)

dev.bistro 2021. 11. 12. 14:36
새로운 서비스를 구현하면서 ID Generator 가 필요하게 되었다. 대량의 코멘트가 작성될 시스템이기 때문에 이것에 대한 고민을 하였고, twitter snowflake를 약간 변경한 ID Generator 를  사용하기로 하였다. 
마침, LINE 세미나에서 비슷한 주제가 있는 것을 확인하여서 해당 내용을 정리하였다.

나와 크게 다른점은 timestamp step 을 1ms 가  아닌 10ms 로 변경하여서  사용범위를 100년 이상으로 증가시킨 점 정도이다. 

 

  1. 글로벌 유니크하고, 선형으로 커지는 ID 이고 백엔드에서 ID가 생성된다
  2. 메신저의 액티브 유저는 2억명이고, 하루 40억개의 메시지가 발행된다.
  3. 메시지가 발행될때에는 ID 가 없고, 서버에서 메시지를 받았을 때 ‘서버에서 ID를 채번’ 그리고 그 ID를 다시 클라이언트에게도 보내준다.

 

 

이 라인앱의 ID Generator 가 필요로하는 Requirements : 빠르고, 단순하고, 유지보수가 쉬워야 한다.

 


첫번째 적용 :  Redis Master-Replica 모델을 적용함

 

 

단순하다. 하지만 정말 괜찮을까?

 

 

Master 가 죽으면 Replica 를 바라보게 할 것이다. 하지만 Async 로 Master 데이터가 복제되므로 '데이터가 유실되거나,  Replica 마다 마지막 복제 ID가 다를 수 있기 때문에 정확한 마지막 ID를 알기 어렵다' -> ID의 채번에 문제가 생기므로 장애

 

ID 생성 자체가 '백엔드(레디스)' 에서 이루어지므로 라인앱 <-> 레디스 네트워크 상에 문제가 발생한다면 장애

 

 

어떻게 고칠까 고민해보니... 결국엔 snowflake 로 도달하게 된다

 

 

 


Snowflake 를 그대로 적용하기 보다는 약간 커스텀 해서 사용하기로 결정함

 

 

 

이 이름을 MIG 라고 하였다.

- resolution 를 1ms -> 10ms 로 변경해서 2188년까지 사용가능
- seq bit 를 18 bit 로 확장
- 그래서 2600 만개의 ID가 1개의 MIG 인스턴스에서 생성가능하다. 
(주, 나는 NodeBit 12, Seq 를 8 bit로 선언했고 GSI 라고 이름 붙였는는데-_-)

 

 

이렇게 MIG 를 멀티 IDC 에서 사용하면 모든 것이 Happy 할줄 알았지만 

 

또 다른 문제가 남아있다.

테스트 중에 발견된 사례 2가지를 소개하겟다.

 

 


이슈1 : ID가 선형증가되지 않는다

clock drift(backword) (주: 나는  if (current < lastTimestamp) 이렇게 에러 로그만 찍고 있다. 이걸 throw exception 하고, 아마 retries 에 의해 다른 MIG  가  채번을 하겠지. 그 동안 이 인스턴스는 ID 생성을 하지 않는다. 그래서 '언젠가는 monotonic 하게 다시 동작할 것이다')

 

 

RTT 감소와 와 atomic command 을 lua script로 사용중. 
(주: 우리도 그렇게 했다. 그럼 라인은 어떤어떤 커맨드들을 합쳤을까?)

하지만 LUA 를 쓸때 큰 버그를 하나 겪음
lua script 에서 문자->숫자를 변환할 때 'redis lua 버전에 따라 integer 대응이 정상적이지 않음. LUA 5.3 에서는 정수형이 도입이 되었지만, 하위호환성 때문에 여전히 이 문제는 있어서 루아에서 BigInteger를 구현하는 등 다른 방식으로 이용함)

Comments