최근 많은 기업들에서 MSA(마이크로서비스 아키텍쳐)를 사용하고 있습니다. MSA의 다양한 장점들이 있겠지만서도, 아마 모듈화 가능한 업그레이드 / (과거대비 기하급수적으로 올라간 트래픽에 대해) 용이한 스케일링 / 클라우드 활용의 용이함 등의 이점이 있을 것입니다.
하지만 MSA가 항상 정답은 아니라는 사례 또한 있습니다. 우선 MSA에 들어가는 “공유 라이브러리”를 잘 분리하지 못하면 MSA의 이점을 십분 활용하지 못하게 됩니다. 그리고 서비스 간 문제가 발생할 경우 디버깅이 훨씬 어렵고, RPC 등으로 인한 기본 오버헤드 자체가 많이 들게 됩니다. (해당 글을 언제 쓴 적이 있었는데 찾을 수가 없네요… 😇)
그래서 드물게 근래에도 Monolithic 형태로 서비스를 운영하는 곳이 몇 군데 있습니다. 그런데 그 중 꽤 의외였던게 StackOverflow가 바로 그러한 예 중 하나인 것입니다.
어째서 Monolithic 인가?
먼저, 여기서는 MSA가 무안단물이 아님을 이야기합니다. 위에서 이야기한대로 MSA에서의 문제는 발생할 요인이 더 많아집니다. 제각기 다른 플랫폼과 데이터베이스간의 통신/호환 문제, 인프라 자체에서 발생하는 이슈들 등등이 모든 문제요소가 됩니다. 이는 Monolithic에서는 찾아볼 수 없는 문제들이었습니다.
물론 이를 해결하기 위해 Lambda나 Docker과 같은 Container 시스템 및 IaaS 인프라 등이 생기면서 그러한 문제들이 많이 해결되기는 했습니다. 하지만 여전히 남은 문제 중 하나는 바로 “정합성” (혹은 race condition) 입니다. MSA 체제로 옮겨가면서 단일 서비스 혹은 단일 트랜잭션으로 해결될 수 있는 요소가 점점 줄어들고, 따라서 중간에 통신이 실패할 가능성이 있습니다. 이런 형태의 문제는 간혹 발생되기 때문에 찾기도 쉽지 않습니다. 그 모든 것들이 비용으로서 작용하게 됩니다.
의존성이 얼기설기 섥혀있는 MSA 아키텍쳐의 모습 — 출처 https://stackoverflow.blog/2020/11/23/the-macro-problem-with-microservices/
StackOverflow의 경우, 2014년 당시 4000만개의 답변글과 5.6억/month (216 TPS)의 pageview를 가지고도 단 25개의 서버로 운영될 수 있었다고 합니다. 사용되었던 요소들을 조금 더 구체적으로 파헤치면
- .Net 언어 사용 ⇒ 당시를 고려해보면 최적화 자체로는 흠잡을 요소가 없었을 것입니다 (동시대 Java/python 대비)
- MSSQL + ElasticSearch
- 파티셔닝에서 매우 강력한 강점을 지닌 NoSQL을 안 쓰는 것은 의외입니다. 다만 사이트별로 DB를 다르게 가져가서 어느 정도의 파티셔닝을 의도했다고는 함.
- DB에서 SSD는 혁명에 가까운 수준의 향상을 보여주는데, 아예 Lock이 필요가 없어져서.
- 캐싱을 위한 Redis
- Replication 간 정합성을 위해서 Redis를 사용했을 것입니다.
- 그 이외에도 참 많은 곳에서 캐시가 부분적으로 활용되곤 합니다. 네트워크 레벨(CDN), 인메모리, DB 레이어 캐시(수많은 DB가 기본 캐시를 내장하고 있다는 걸 잊으면 안됩니다!), 하드웨어 레벨 등. 인메모리 정도면 충분합니다. 캐시에 너무 많은 공을 들일 필요는 없습니다.
이러한 요소들 만으로도 엄청난 트래픽 부하를 감당할 수 있는 것은 꽤 놀라운 일입니다. 어떻게 보면 대부분의 로드는 DB나 캐시에서 발생한다면 또 납득이 못 갈 수준이 아니지만요. 재미있는 것은, 대부분의 Architecture Interview에서는 모놀리스 디자인을 원하지 않을 거라는 것입니다.
출처: https://twitter.com/alexxubyte/status/1577684758779203584/photo/1
클라우드를 쓰지 않는 이유?
그리고 클라우드 자체에 대한 한계도 있음을 지적합니다.
- 클라우드에는 분명한 제약(capacity limi)이 있음
- 이것은 은근히 큰 제약 요소중 하나입니다. MSA 특성상 클라우드 pod이 메모리가 1GB도 안되는 경우가 태반인데, 이런 일반적이지 않은 환경에서 구동할 경우 OOM이 의도치 않게 발생하는 경우가 꽤 있기도 하고요.
- 보통의 경우, 모든 비용 중에서 하드웨어가 제일 저렴하다
- 마지막으로… 처음부터 모든 것을 클라우드로 짤 필요는 없습니다. 클라우드로의 전환은 나중에 생각해 볼 일입니다.
이 외 Lessons
이외에도 좀 충격적인(?) 내용들이 있어 간략하게 써 둡니다.
- GC-driven 프로그래밍: 말 그대로 Garbage Collection에 드는 비용을 최소화하는 것을 목표로 하고 있습니다. 추상화 없애거나 static 메서드 쓰거나 등… 근데 이게 좀 특이한게 TDD 같은 관행도 없앨 수 있다고 이야기합니다. 이게 와전된건지는 잘 모르겠지만… 물론 최소한의 테스트 케이스는 갖추고 있으니, 아마 여기서 이야기하고 있는 건 불필요한 부분에 대한 추상화 정도가 될 것 같습니다. 어찌됐든 GC 비용을 최소화시켜서 Stop-the-world에서 드는 비용을 줄이는 것이 큰 영향을 끼친다고 이야기합니다. 정말 성능 지상주의적인(?) 개발 철학을 엿볼 수 있습니다.
- 필요한 것만 해라: 테스트 마저도 꼭 필요하지 않다면 굳이 추가할 필요가 없을 지도 모른다고 여기서는 이야기합니다. 물론 테스트는 중요하겠지만… 그만큼 불필요한 곳에 비용을 투자하지 말자는 이야기겠지요.
- 넉넉함의 미덕: Network bandwidth, SSD IO capacity 등은 항상 넉넉하게 마련해 두는 것이 좋다고 이야기하고 있습니다. 피크타임 등 백업과 같은 백그라운드 태스크 같은 걸로 소모되기도 하는 것을 고려해야 한다고.
- 심연(?)을 들여다 보아라: 메모리 덤프, Perf trace 과 같은 것들을 적극적으로 활용하라는 이야기입니다. 성능에서 생각 이상으로 많은 것들을 얻을 수 있다는 것과 일맥상통합니다. 항상은 못 켜더라도, 이따금씩 켜서 확인하는 것은 좋은 전략이 될 듯.
References
- StackOverflow Update: 560M Pageviews a Month, 25 Servers, and It's All About Performance - High Scalability
- https://nickcraver.com/blog/2016/02/17/stack-overflow-the-architecture-2016-edition/
- https://www.infoq.com/news/2015/06/scaling-stack-overflow/
- https://stackoverflow.blog/2020/11/23/the-macro-problem-with-microservices/
- https://twitter.com/alexxubyte/status/1577684758779203584
- https://stackexchange.com/performance
'개발 > Engineering' 카테고리의 다른 글
MTF/LRU 최적화 in Bit level (0) | 2023.05.15 |
---|---|
Optimizing Bit Streaming & Buffering (0) | 2023.05.13 |
[번역] 게임을 최적화하며 느낀 점들 (0) | 2023.02.19 |
Ray Tracing 기술의 발전 (0) | 2022.11.03 |
Sized Memory Deallocation (0) | 2022.11.02 |