You are always integrating through a database - Musings on shared databases in a microservice architecture
마이크로서비스 아키텍처의 공유 데이터베이스에 대한 고찰 -당신은 항상 데이터베이스를 통해 통합하고 있다.-
끄적끄적...
최근 차세대 서비스의 인프라를 준비하고 있는 동기에게 질문을 받았습니다.
"애플리케이션에서 DB 스키마가 변경되면 애플리케이션이 알아서 변경된 스키마를 인식할 수 있게 만들 수 있나요?"
차세대 인프라를 준비하고 있었다는 사실은 알고 있어서 대충 어떤 이슈인지는 감이 왔습니다.
관련 서비스들 공유형 DB를 사용하고 있다 보니, 특정 서비스에서 스키마를 변경하는 작업을 할 경우
다른 서비스까지 전체적으로 영향을 받고 있는 것입니다.
실제 운영에서는 변경된 스키마를 반영한 후 배포하는 것을 꼼꼼하게 체크하기에 문제는 없는데,
이 작업 과정이 순탄치 않았던 모양입니다.
동료에게 DB를 공유하지 말고 부분적으로 분리될 수 있는 부분을 식별해서 서비스로 빼는 게 좋겠다고 조언을 했습니다.
쉽지 않은 작업일 테지만 이런 작업을 한 번, 두 번 성공하다 보면 속도가 붙을 것이니
장기적으로 본다면 괜찮은 솔루션이 될 거라고 했죠.
제 동기는 막내 위치(그것도 인프라...)에 있는 실무진이라서 그런 제안을 드라이빙할 힘이 없었습니다.
그러다 위의 글을 알게 되었고 좋은 글인 것 같아 해당 동료에게 공유했었는데, 개인적인 생각도 글로 남겨보려고 합니다.
공유형 DB는 양날의 칼이다.
DB를 공유한다는 것은 뚜렷한 트레이드오프가 있고 실제 실무 환경에서는 공유형 DB가 매력적인 설루션이라는 점입니다.
운영중인 비즈니스 요구사항이 공유형 DB가 적합한 케이스인지를 먼저 체크해 보는 것.
공유형 DB가 문제를 일으킨다면 Bespoke API 혹은 이벤트 소싱 방식을 검토해 보는 것을 권장한다는 글입니다
저자는 이벤트 소싱 쪽을 긍정적으로 생각하고 이에 대한 내용으로 자연스럽게 넘어갑니다.
공유형 DB의 단점들...
1. A centrally designed schema will by owned by everyone and suite no one.
중앙화된 스키마는 모두가 관리하게 되지만, 모두에게 적합한 DB가 아닙니다.
2. Separate schemas for each application will have an impedance mismatch between them. Domain-driven design has taught us that there is hardly ever agreement over the meaning of terms across different contexts.
공유형 DB에서 각 애플리케이션에 분리된 스키마를 통합하는 경우(의역), 불일치(용어적)가 발생할 수 있습니다. 도메인 주도 설계는 서로 다른 컨텍스트(Bounded Context)에서 용어의 의미에 대해 거의 일치된 의견이 나오지 않는다는 점을 우리에게 가르쳐 줍니다.
3. Applications that expose their own data schema to the outside world suddenly have to deal with schema evolution beyond their own control.
서비스의 데이터 스키마를 외부에 노출하는 애플리케이션은 자신의 통제를 벗어난 스키마 진화(생애주기) 문제를 다뤄야 합니다.
4. The same database technology has to be used by all for a dataset, even if there are radically different requirements for accessing it (some might need strong transactionality, others may need high read scalability)
공유형 DB를 사용하는 모든 개발자가 동일한 데이터 베이스 기술을 사용해야 합니다.
5. Noisy neighbors can affect the performance of other applications
공유 자원들이 애플리케이션 성능에 영향을 미칠 수 있습니다. [DB, 서버, 네트워크 등등...]
6. The central database server becomes a single point of failure for all applications
중앙화된 데이터베이스 서버가 애플리케이션 서비스의 치명적인 fail point가 될 수 있습니다.
나의 생각...
1번의 단점에 공감이 많이 됩니다.
현재 차세대를 진행 중인 팀과 협업 중에 있는데, 데이터베이스 변경건에 대해서 매우 민감하게 반응을 보입니다.
[요구사항 정리, 기획서.. 메일로 공식적인 요청을 요구하는데.. 원하는대로 요청해도 요구사항을 들어주지는 않더군요]
데이터베이스 변경과 관련된 작업이 잡히면 관련 팀들이 모두 모여 이 사안을 다 인지하고 넘어가는 방식으로 작업이 진행되고 있기에 예민하게 반응하고 있었던 것입니다.
단순한 테이블 추가의 문제가 아닌 것인데, 1번의 표현대로 관련된 관계자가 해당 스키마를 가지고 있지만,
그 누구도 이 스키마에 피팅되는 팀이 없기 때문입니다.
결국엔 서비스 개발 속도가 느려지거나 외부 서비스에서 데이터를 조달하는 방식으로 API를 연결하게 되는데,
이는 데이터 관리 측면에서 보면 옳지 않은 방향으로 시스템이 복잡해집니다.
[데이터 관리 주체가 데이터를 주는 게 아닌, 외부 의존 서비스에서 데이터를 보유하고 API로 가져오는 방식이기 때문...]
나중에 분석이나 통계측면의 이슈에서 외부 서비스에 분석, 통계 API가 덕지덕지 붙게 되고
거버넌스 측면에서도 모호한 영역들이 발생합니다.
2번의 경우 용어와 관련된 충돌 이슈인 것 같습니다.
DDD에서는 특화된 도메인별로 컨텍스트를 두는 것을 제안합니다.
거대한 비즈니스도 부분적으로 보면 작은 컴포넌트 형식의 비즈니스로 구분되고 이 구분되는 영역에서는 팀이나 부서가 다르기에 용어를 다르게 사용하죠. (DDD에서 용어는 매우 중요한 개념이다.)
공유형 DB 스키마에서는 많은 도메인 용어들이 사용됩니다.
테이블명부터 칼럼명까지 여러 용어들이 사용되는데, 공유형 DB에 속한 팀들이 협의를 하고 용어를 통일하는 게 아닌 이상 공유형 DB를 사용하는 모든 관계자는 같은 용어이지만 서로 다르게 이해하는 용어들을 피할 수 없는 상황을 마주하게 됩니다.
소규모 인원으로 서비스를 개발하고 있는 현재 팀만 하더라도 LLM에서 나온 결과를 Completion으로 명명하느냐 Result로 명명하느냐에서 차이점이 발생하고 있습니다.
수백 개의 테이블에서 각각의 용어들이 고유하게 사용될 수 있음을 어떻게 보장하고,
모든 관계자가 동일한 개념을 가지고 있다고 어떻게 확인할 수 있을까요? [정말 머리 아픈 일이죠..]
이 부분은 소통 쪽에서 큰 비용을 야기하고 나중 가서는 개발 쪽에서 요구사항을 잘못 이해하거나 요구사항을 잘못 분석하는 결과를 야기할 수 있습니다.
(협업 개발 부서끼리 다르게 이해한 용어로 대화를 진행하다가 어! "용어" ~~ 뜻으로 사용하는 거 아니었어요? 가 빈번하게 발생합니다.)
4,5,6번의 경우 인프라적인 이슈 혹은 기술적 이슈로 생각됩니다.
6번의 경우 SFP(단일 장애 지점) 이슈를 언급합니다.
잘못된 SQL로 DB쪽 자원을 크게 잡아먹는 경우 애플리케이션의 DB IO 병목 현상을 야기하게 되고,
최종적으로는 서비스 가용성에 영향을 주게 됩니다. 이 이슈도 실무에서 자주 만나는 이슈입니다.
공유형 DB 참을수 없는 유혹
시작은 공유형 DB로 시작합니다.
마이크로서비스 아키텍처 전문가인 샘 뉴먼의 조언도 비슷합니다.
처음부터 마이크로서비스로 시작하는 것보다 모놀리식으로 시작해 부분적으로
명확하게 도려낼 수 있는 부분들을 작게 작게 쪼개는 것을 권합니다.
공유형 DB는 참기 힘든 유혹입니다.
프로젝트 초기에 빠르게 결과물을 확인해야 하는 상황에서 DB을 여러 개 둬서 관리하는 작업은 쉽지 않고,
상급자에게 이런 상황을 설득하기도 쉽지 않습니다.
인프라쪽에서도 의문 부호 가득한 질문을 합니다.
(굳이 서비스를 복잡하게 관리하는 이유가 뭐예요?.. 사용자가 아직 얼마 없는 거 아니에요?)
거기에 요구사항을 처음부터 명확하게 이해하기도 쉽지 않습니다.
요구사항이 곧 데이터의 구조(스키마)가 될텐데 이는 작업 도중에 시간에 따라 자주 변경됩니다.
[요구사항이 변경되거나 개발진이 다르게 이해한 부분을 바로 잡거나...]
현재 팀에서는 4개의 서비스에서 의존하고 있는 공통 서비스를 만들고 있는데, 공유형 DB를 사용하고 있습니다.
단 외래키 의존성을 분리하고 스키마 다이어그램으로만 스키마의 정보를 관리하고 있습니다.
스키마 다이어그램을 통해 도려낼 수 있는 부분을 명확하게 두고 있습니다. (언제든 서비스로 빠져나갈 수 있도록...)
이후의 글은 공유형 DB의 대안이 될 수 있는 사례들을 살펴보는 내용입니다... (Bespoke API, Event Souring)
해당 내용은 정리하기엔 너무 많아서 시간이 되면 따로 읽어보기를 권합니다.
'IT 고찰 > 좋은 글' 카테고리의 다른 글
ADR : 아키텍처 결정 기록물. -엔지니어링 결정에 대한 논쟁을 줄여줄 도구- (1) | 2024.11.19 |
---|---|
EU 인공지능 법안 요약본 [GPAI: General Purpose AI] (7) | 2024.09.13 |
Anthrophic에서 시스템 프롬프트를 공개하다 (0) | 2024.08.29 |