[입 개발] 분산 시스템을 설계한다는 것의 의미…

먼저 밝히는 것은 저는 이쪽 전문가는 아니고, 발만 살짝 걸쳐본 하수라는 것입니다. 갑자기 생각난 것을 간단하게 풀어볼려고 합니다.

 

오늘 CloudFoundry 블로그에 다음과 같은 글이 올라왔습니다. Scaling Real-time Apps on Cloud Foundry Using Node.js and Redis 물론 좋은 글입니다. 이 글을 까려거나 그런 의도는 전혀 없지만, 이 글에서 잘못 배우면 위험한 것에 대해서 얘기를 해 볼려고 합니다. Scale out 이라는 말은 참 듣기 좋은 말입니다. 서버가 늘어나는 대로 성능이 늘어난다. 물론 이게 정비례로 2대 늘면 2배 늘어나는 형태는 아니지만, 분명히 아키텍처 적으로 이득입니다. 그런데 분산 시스템이라는 측면에서 본다면, 위의 글에서 설명하는 아키텍처는 SPOF의 위험이 있거나, 진정한 의미의 Scale out이라고 할 수 가 없습니다. 왜냐하면 지금 Redis 서버 한대가 죽으면 전체 서비스가 마비가 되고, 웹 서버가 극단적으로 늘어난다고 한다면 Redis 서버 한대가 이 트래픽을 전부 감당할 수 있을까요? 결국 이런 설계는 지속적으로 데이터 스토리지 또는 큐잉 스토리지로 주는 부하를 나눠주는 형태라고 할 수가 없습니다.

 

그렇다면 어떠한 부분이 고려되어야 할까요? 큐잉이나 데이터 스토리지가 하나의 Scale out 가능한 클러스터 이거나, 웹 서버 수준에서 사용자의 정보에 따라서, 특정 파티션으로 찾아갈 수 있게 하는 아키텍처가 필요합니다. 이렇게 되면, 이 분배는 어떻게 할 것인가 큐는 어떤걸 이용할 것인가에 대한 지식이 필요하게 됩니다.( 예를 들어, ZooKeeper 를 이용해서 Redis 클러스터 멤버쉽을 관리하고 변화가 있을 때 라이브러리 수준에서 해당 서버를 제거하는 형태로 구현하거나, RabbitMQ를 쓰는데, 단순히 클러스터 모드를 쓸때, durable 옵션을 사용하면, 디스크 노드가 죽었을 때, 해당 채널이 동작하지 않으므로, mirror-mode를 쓴다든지 간의 결정들) 그리고 이제 소프트웨어 적인 수준을 넘어서는 문제가 생길 수도 있습니다. 1G 네트웍을 쓰고 있는데, 1G 네트웍을 넘는 데이터를 쓸 수도 있다거나, 아마존 AWS를 쓰면 자체 IDC에서 쓸 수 있던 기술들을 쓸 수 없다거나, 여러가지 이슈들이 있습니다.

 

또한, 하드웨어도 자주 장애가 생깁니다. 단순히 장비 한 두대 장애난 것에 대해서는 대비를 했다고 하지만, 전체 스위치가 나간다던지 로드밸런서를 쓰고 있는데, L4 장비에 장애가 생긴다면, 해당 시스템이 안정적으로 동작할까요? Netflix는 아마존 가용존 전체를 다운시키는 형태로 테스트를 한다고 하던데, 아마 이런 이슈들을 점검하고 싶었던 것일껍니다. 하드웨어 이중화가 있더라도 장비의 버그가 있어서 동작하지 않을 수도 있습니다.

 

자, 이제 한번 상상해 봅시다. 우리가 설계하는 시스템은 “장비 한대만 문제 생겨도 큰일나요!” 인지, “장비 한 두대야 죽을 수도 있죠” 인지, “전체 시스템이 거의 다 죽어도 동작한다” 인지. 다만, 이런 수준을 선택하는 것은, 서비스에 따라서 달라집니다. 항상 하드웨어 다 나가도 서비스가 되어야 한다라는 수준으로 설계를 할 필요는 없습니다. 다만, 이런 시스템을 설계할 수 있을 정도의 능력이 있어야 된다는 것입니다. 아니면 장애를 최대한 국소화 시키는 것도 좋은 설계라고 생각합니다.

 

뭐,팁이라고 하기는 애매하지만, 보통 다음과 같은 형태로 설계하는 것이 좋습니다.

  • 가능한한 Stateless 하게(데이터 스토리지가 문제가 생깁니다.)
  • 하나의 큰 클러스터 보다는 작은 샤딩 Cell 아키텍처로( 문제를 국소화 시키기 위해서, 장비가 늘어날 수 있습니다.)
  • 데이터 스토리지는 꼭 HA 가능하도록 하고, 테스트도 꼭 필요

 

읻단 제가 경험이 적어서 크게 좋은 충고는 해 드릴 수가 없네요. 그럼 고운 하루되시길…