Discord 에서 Go 에서 Rust 로 넘어간 이야기
Discord의 서비스 중에 Read States Service 라는 것이 있는데, 이것을 Go 에서 Rust 로 옮겼다고 함.Read States 은 message 를 보내고, 읽을때 계속해서 접근하게 된다고 함.
user 의 read state 를 저장하려고, "Read State" 라는 data sturucture 를 가지고 있는데, Discord 가 몇백만개의 Read State 를 갖게 된다. 이 Read State 는 한채널에서, user 당 1개를 갖는다. 그리고 이 Read State 가 여러개의 counter 를 갖고 있다. 예를 들면, 이 채널에서 당신의 @mention 이 얼마나 있는지등에 대한 counter.
이런 counter 의 update 를 빠르게 하기 위해 Read States Server 는 Read State 에 대한 cache 를 갖고 있는데, 이 cache 는 LRU(least recently used, 가장안쓰는 것을 버리는) 방식을 사용한다.
각 cache 에는 몇백만의 users 들이 있고, 몇백만개의 Read States 몇십개가 각 cache 에 있다. 초당 몇백, 몇천의 cache update 가 있다.
그런데, latency and CPU spikes 가 매 2분 마다 있다.
이것이 Go 의 Garbage Collector 때문이었다. 소스로 확인한 결과, Go 가 강제로 최소 매 2분마다 GC 를 돌리도록 하고 있다.
나중에 보니, spike 의 이유는 ready-to-free memory 가 많아서가 아니라, 어떤 메모리를 free 해야 하려고, GC 가 LRU cache 를 scan 하는 과정 때문이었다.
그래서 LRU cache size 를 줄여서 GC 가 scan 하는 시간을 줄였다. 그리고 한 서버에서 LRU cache 를 여러개로 쪼개서(partitioned) 가졌다. 그런데 cache size 가 줄면서, 이것이 database 의 load 로 이어졌다. 그래서 여러번의 load testing 으로 최적의 setting 을 찾아서 설정했다.
하지만, 결과적으로 Rust 로 옮긴 것이 golang 에서 최적의 setting 을 한 것보다 나은 결과를 가져왔다.
...
댓글 없음:
댓글 쓰기