Kyle Brown (LinkedIn)

IBM Distinguished Engineer, CTO of Cloud Architecture, Cloud Lab Services

원문 (영어)

본 시리즈 1부에서 코드를 마이크로서비스 기반 방식으로 리팩토링 해야 하는 이유와 고려할 점에 대해 소개하였으며, 데이터를 어떻게 할 것인가에 대한 화두를 던지고 마무리를 하였습니다. 큰 규모의 기업용 애플리케이션에서 데이터는 가장 껄끄러운 주제이며 세심한 처리가 필요합니다.

애플리케이션의 구조를 검토하고 이에 가장 적합한 데이터 관리 방식을 선택하는 것은 많은 경우 “데이터베이스에 실제로 무엇을 저장하는가”라는 질문으로 귀착됩니다.

저는 1990년대 초부터 기업들이 객체관계매핑 (object-relational mapping (ORM)) 프레임워크를 구축하고 유지하는 일을 도왔습니다. 여러 경우, 기업이 보유하고 있는 데이터가 관계형 데이터 모델에 잘 매핑되지 않았습니다. 그럴 때는 관계형 모델을 좀 바꾸거나, 프로그램을 고쳐 관계형 데이터 저장소와 코드를 강제로 맞췄습니다.

현재는 다양한 데이터베이스를 동시에 사용 가능하므로 (polyglot persistence), 과거에 내렸던 의사결정을 재검토하고 더 나은 결정을 내릴 수 있습니다. 이제, 관계형 모델이 최선이 아니었던 4가지 사례와, 관계형 모델이 적절하여 데이터를 리팩토링 하지 말아야 할 사례를 살펴보겠습니다.

 

1. 블랍 (Blob: Binary Large Object) 저장소

기업 시스템의 기존 코드를 보면 놀랍게도 관계형 DB에 바이너리로 직렬화된 자바 객체가 저장되어 있는 경우를 종종 발견할 수 있습니다. 일반적으로 이 객체들은 Blob (Binary Large Object) 컬럼에 저장되어 있는데, 자바 객체를 관계형 테이블과 컬럼에 매핑하는 것이 복잡해 매핑을 포기했기 때문입니다. Blob 저장소는 컬럼 기반으로, 쿼리가 불가능하며, 느리고, 자바 객체 구조 변화에 민감합니다. 특히 객체 구조가 크게 변하면 과거 데이터를 읽지 못할 수 있습니다.

따라서 애플리케이션이 (보통 애플리케이션의 일부가) 관계형 DB 내 Blob 저장소를 사용한다면, Memcached 또는 Redis와 같은 키-밸류 저장소를 사용하는 것이 더 좋을 수도 있는 상황입니다.

앱에 구조화된 자바 객체 (깊게 구조화되어 있지만 바이너리는 아닌 객체)를 저장하는 경우라면, 문서 저장소인 클라우던트(Cloudant)나 몽고디비(MongoDB) 를 사용하는 것이 더 좋을 수 있습니다. 조금만 더 문서 저장 방식에 신경을 쓰면, 저장 방식을 이해하기 어려운 Blob 저장소 방식보다 스키마가 변동하는 (“schema drift”) 문제를 좀 더 쉽게 처리할 수 있습니다. 예를 들어 클라우던트나 몽고DB 데이터베이스는 JSON 문서 저장소이며, JSON 파서는 널리 사용되고 쉽게 수정 가능합니다.

2: 플랫(Flat) 객체 및 활성 레코드 패턴

수년 전 마틴 파울러가 “기업 애플리케이션 아키텍쳐의 패턴”(Patterns of Enterprise Application Architecture)을 저술할 때 여러 번 패턴들에 대해 활발한 리뷰 회의를 했었습니다. 당시 제게 특이했던 것이 활성 레코드 패턴 (Active Record Pattern)입니다. 개인적으로 이 패턴을 처음 봤기 때문에 특이하다고 생각했었는데 마틴은 Microsoft .NET 프로그래밍 커뮤니티에서는 흔히 사용된다고 했습니다. 하지만 제가 정말 놀란 것은, 특히 일부 iBatis와 같은 오픈소스 기술을 이용한 자바 구현 시 이 패턴을 사용하기 제일 좋은 경우는 객체가 플랫(flat) 한 경우라는 점입니다.

데이터베이스에 매핑하는 객체가 완전히 플랫(flat)하다면, 즉 다른 객체와 아무 관계가 없다면 (중첩된 객체 등 일부 경우를 제외하고는), 관계형 모델의 장점을 모두 사용하지는 않는 것입니다. 사실 고객만족도 설문지나 문제 보고서처럼 종이 문서를 전자 문서로 옮겨 저장한다면, 클라우던트나 몽고디비 같은 문서 데이터베이스가 더 좋은 선택입니다. 그 데이터베이스에 작용하는 서비스 관련 코드를 분리해내는 것이 코드도 간단해지고 유지보수도 더 쉬워집니다.

3. 참조 데이터

객체형-관계형 매핑 (ORM) 시스템에서 자주 봤던 패턴 하나는 테이블의 참조 데이터가 메모리 캐시에 올라가는 경우입니다. 참조데이터는 자주 업데이트가 되지 않지만 계속 읽힙니다. 예를 들어 미국의 주 이름이나 캐나다의 지역 이름, 의료 코드 및 표준 부품 리스트 등이 해당됩니다. 이런 종류의 데이터는 GUI에서 드랍다운 메뉴로 사용됩니다. 일반적으로는 테이블에서 일반적으로 플랫(flat)한 2컬럼이나 3컬럼짜리 테이블인 리스트를 필요할 때마다 매번 읽습니다. 하지만 그 성능이 문제이기 때문에 시스템을 시작할 때 Ehcache같은 메모리 캐시로 올립니다.

이런 문제에 봉착했다면 좀더 빠르고 간단한 캐시로 리팩토링을 고려할 때입니다. Memcached나 Bluemix의 데이터캐시 서비스 또는 레디스 (Redis)가 이에 적절합니다. 만일 참조 데이터가 나머지 데이터베이스 구조와 독립적이거나 느슨하게 결합된 정도라면 데이터와 관련 서비스를 다른 시스템과 분리하는 것이 좋을 것입니다.

4. 최악의 쿼리

한 고객사 시스템의 경우 복잡한 재무 모델링을 했었는데, 매우 난해한 쿼리 (6회 또는 7회의 테이블 조인)로 프로그램이 다룰 정보를 생성하고자 하였습니다. 데이터 변경은 더 복잡했습니다. 뭐가 바뀌었는지 찾고 데이터베이스 안에 있는 것이 원래 생성하고 조정한 구조와 같은지 확인하기 위해 여러 레벨의 복합적인 체크를 해야 했습니다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

돌이켜보면 우리가 했던 것은 그래프로 모델링이 가능했을 것입니다. 당시 펀드 차입금을 모델링했는데 여러 종류의 주식과 담보부증권으로 구성되어 있었으며 각각은 서로 다른 화폐와, 만기 시점 및 가치 평가 기준이 따로 있었습니다. 이와 같은 경우에는 원하는 것을 쉽게 할 수 있는 데이터 구조를 찾게 됩니다: 그래프의 위 아래로 이동하면서 그래프의 일부분을 옮기고 싶습니다.

Bluemix의 IBM 그래프 데이터서비스 (IBM Graph database service on Bluemix)에서 사용하는 Neo4J 또는 Tinkerpop 을 사용하는 것이 좋은 접근법일 것입니다. 솔루션을 그래프로 직접 모델링함으로써, 여러 복잡한 자바와 SQL 코드를 피할 수 있고, 아마도 런타임 성능을 획기적으로 향상시킬 수 있습니다.

5. 테이터 모델이 잘 작동하는 경우

이제까지 관계형 모델과 잘 맞지 않는 4가지 경우를 보았습니다. 여기서는 기업 데이터 저장소에서 데이터를 분리해내지 않아도 되는 하나의 경우를 설명하고자 합니다.

제 고객 중 하나는 이런 문제가 있었습니다. 선거구 내 시민을 지원하기 위한 정부 단체인데 시스템 내에서 시민을 표현하는 수 백 가지의 관점이 있었습니다. 따라서 “질문을 한 사람과 양식을 작성한 사람은 동일인인가?” 라는 간단한 질문조차도 답변하는 것이 불가능했습니다. 이는 정부를 당혹스럽게 했고, 시민들의 불만을 고조시켰으며 그 사이에 낀 IT 인력들이 좌절감을 느끼게 하였습니다. 모두 뭔가 다르게 해야 한다는 것을 알고 있었습니다.

고객에게 마이크로서비스에 대해 이야기하면 자주 듣는 답변이 “이미 데이터 모델링에 많은 돈을 투자했기 때문에 고려할 수 없어요”라는 것입니다. 어떤 면으로 맞는 말입니다: 기업 데이터 모델에서 아주 깊이 다른 것과 연결된 것들을 빼낼 수는 없습니다. 그것은 쓸모 없는 일입니다. 데이터 모델이 잘 돌아가고 있고 아무런 문제가 없다면 이를 바꿔야할 이유는 없습니다.

기준정보관리(MDM)로의 이동

하지만 모든 데이터가 다 문제가 없는 것은 아닙니다. 데이터 관리에 대해 비슷한 방향으로 움직이는 새로운 추세가 있는데, 이는 개발자로부터 시작된 것은 아니고, 데이터 모델러와 DBA로부터 시작되었습니다. 그 새로운 추세는 기준정보관리(Master Data Management: MDM)입니다. 어떤 면으로 보면 이것은 같은 아이디어입니다: 즉 중요한 주제, 예를 들어 “고객”에 대해서 여러 뷰가 있으면 안된다는 것입니다. MDM 도구는 여러가지 뷰들을 모두 통합하여 불필요한 중복을 제거합니다.

차이점은 MDM 솔루션은 API 중심이라기 보다는 데이터 중심입니다. 그러나 MDM 솔루션을 적용하면 MDM 도구를 통해 공통 주제로 접근이 가능한 중앙집중화된 API 세트들이 생성됩니다. 이 API들이 마이크로서비스 기반 방식에 토대를 두었다고 생각을 안할 이유는 없습니다. 그냥 같은 도구로 구현이 되지 않는다는 것만 알고 있으면 됩니다. 궁극적으로 마이크로서비스 아키텍쳐에서 취할 것은 API가 중요하고 구현은 관계없다는 것입니다.

결론

이제까지 마이크로서비스 기반으로 데이터 리팩토링을 하면 문제가 풀릴만한 네가지 사례를 살펴 보았습니다. 만일 이런 코딩 이슈를 발견한다면 현재 기업 데이터 저장소에서 데이터를 분리하고 거기에 다른 타입의 데이터 저장소를 적용하는 것을 고려하는 것이 좋겠습니다.

본 시리즈의 다음 편에서는 1부와 2부에서 배운 내용을 가지고 어떻게 단일체 애플리케이션에서 마이크로서비스로 진화해 나가는 지 단계적으로 알려드리겠습니다 .

관련 내용: 마이크로서비스로 리팩토링하기 1부

관련 내용 : 기업 애플리케이션 아키텍쳐의 패턴들

관련 내용: 디벨로퍼웤스 내 마이크로서비스 TV

무료 Bluemix 계정 신청 (Sign up for a free Bluemix trial)

Bluemix 개발자 커뮤니티

본 튜토리얼에 사용된 Bluemix 서비스

  • 데이터 캐쉬 서비스 (Data Cache service)는 느린 디스크 기반 데이터베이스가 아닌 인메모리 캐쉬에서 빠르게 정보를 가져옴으로써 웹 애플리케이션의 성능과 사용자 경험을 향상시킵니다.
  • IBM 그래프 데이터베이스 서비스 (The IBM Graph database service)는 REST 기반 HTTP API 인터페이스를 통해 접근 가능한 그래프 데이터베이스를 사용하여 강력한 애플리케이션 구축을 지원합니다.

[출처] https://developer.ibm.com/kr/cloud/bluemix/2016/05/04/cl-refactor-microservices-bluemix-trs-2/