-
Notifications
You must be signed in to change notification settings - Fork 0
Description
CHAPTER 6 운영 데이터 분리
모놀리식 애플리케이션을 개별 배포 단위로 분해하는 것과 동일한 방법으로 모놀리식 데이터베이스를 분해하는 것이 바람직한(또는 반드시 필요한) 경우가 있습니다.
애플리케이션 기능을 분해하는 동일한 기술을 데이터 분해에도 적용할 수 있습니다.
컴포넌트는 데이터 도메인으로
클래스 파일은 데이터베이스 테이블로
클래스 간 결합점은 외래 키, 뷰, 트리거, 저장 프로시저 같은 데이터베이스 아티팩트들로 바꿔 생각할 수 있습니다.
6.1 Data Decomposition Driver
아키텍트는 데이터 분해인data disintegrator과 데이터 통합인data integator을 이해하고 분석해야 데이터를 분해하느라 수고를 들여야 하는 이유를 정당화할 수 있습니다.
이 둘의 균형을 맞추고 각자 다른 트레이드오프를 분석하는 것이 데이터를 올바르게 분해하는 핵심입니다.
Figure 6-1. Under what circumstances should a monolithic database be decomposed?
6.1.1 데이터 분해인Data disintegrators
데이터 분해는 어떤 경우에 고려해야 하는가? 에 대한 답과 명분입니다.
- Change control
- Connection management
- Scalability
- Fault tolerance
- Architectural quanta
- Database type optimization
변경 관리Change control
데이터베이스 테이블 스키마의 변경 관리는 데이터를 분해하는 주요 동인 중 하나입니다.
테이블 컬럼을 삭제하고 이름을 바꾸고 테이블 컬럼 타입을 변경하는 중대 변경breaking change이 일어나면 테스트 후 배포해야 합니다. (그림 6-2)
하지만 같은 데이터베이스를 공유하는 개별 배포 서비스가 많으면 이런 작업은 어려워지고 에러가 발생할 가능성이 높아집니다.
Figure 6-2. Services impacted by the database change must be deployed together with the database
위험한 상황은 변경된 테이블에 접근하는 서비스가 있다는 걸 잊고 있을 때입니다. 프로덕션이 제대로 동작되지 않을 때 그 실체가 드러납니다. (그림 6-3)
Figure 6-3. Services impacted by a database change but forgotten will continue to fail until redeployed
데이터베이스를 잘 정의된 경계 콘텍스트로 분해하면 데이터베이스 변경 관리에 매우 유익합니다.
에릭 에반스Eric Evans의 < 도메인 주도 설계 > 에 등장하는 개념으로 소스 코드, 비즈니스 로직, 데이터 구조, 데이터를 모두 특정한 콘텍스트로 캡슐화한 것입니다.
이 경계를 정확히 해 두면 나중에 변경이 발생해도 경계 콘텍스트 내부의 서비스만 영향을 받게 되므로 아주 큰 도움이 됩니다.
경계 콘텍스트는 서비스와 서비스가 소유한 데이터를 중심으로 형성됩니다.
그림 6-4에서 서비스 C는 데이터베이스 D에 있는 데이터를 조회해야 하지만 이는 서비스 D의 경계 콘텍스트 안쪽에 있습니다.
만약 접근할 수 있게 만든다면 경계 콘텍스트 규칙에 위배되고 변경 관리 측면에서 혼란이 생깁니다.
올바르게 접근하려면 서비스 C는 서비스 D에 데이터를 요청하는게 맞습니다.
Figure 6-4. Database changes are isolated to only those services within the associated bounded context
서비스 D는 데이터베이스 추상화를 하는 것이 중요하기 때문에
그림 6-5와 같이 어떤 계약(JSON, XML, Object)을 통해 서비스 C가 요청한 데이터를 전달합니다.
이때 데이터베이스 D에 있는 테이블 스키마와 다르다는 것이 경계 콘텍스트의 강점입니다.
이는 데이터베이스 D 테이블에 중대한 변경이 일어나도 서비스 D만 영향이 있을 뿐이고, 서비스 C에 전달되는 데이터 계약에는 영향을 미치지 않습니다. 이 부분이 추상화입니다.
Figure 6-5. The contract from a service call abstracts the caller from the underlying data base schema
커넥션 관리Connection management
커넥션 풀을 사용하면 성능을 향상시키고 애플리케이션의 동시 접속 수를 제한합니다.
모놀리식일 때는 문제가 없지만 분산 아키텍처의 서비스는 각자 자체 커넥션 풀을 가지고 있습니다.
이 서비스들이 동일한 데이터베이스를 공유하는 구조로 가면 서비스가 늘어날수록 커넥션 풀의 갯수가 빠르게 소진되게 됩니다. (그림 6-6)
Figure 6-6. Database connections can quickly get saturated with multiple service instances
최대 가용 데이터베이스 커넥션 수에 도달하면 데이터베이스 분해 방안을 심각하게 고려할 필요가 있습니다.
분산 아키텍처는 데이터베이스 커넥션 사용량을 관리하는 게 중요한 데 여러 서비스가 사용할 수 있도록 서비스당 커넥션 쿼터를 정해 데이터베이스 커넥션을 최대한 분산시키는게 좋습니다.
처음에는 각 서비스별로 커넥션 쿼터를 균등하게 분배합니다.
하지만 서비스별로 커넥션을 쓰는 갯수가 다르므로 효율적이진 않습니다.
서비스별로 커넥션 쿼터를 다르게 분배하는 건 복잡할 수 있지만 공통 데이터베이스의 커넥션 수를 효율적으로 관리하는 방법입니다.
서비스마다 동시 커넥션 사용량을 측정하는 피트니스 함수를 작성하면 좋습니다.
또 외부 구성 서버(서비스)에 커넥션 쿼터 정보를 저장해 두면 커넥션 고갈 위험을 줄일 수 있고 유휴 커넥션으로 낭비가 되는 문제점을 예방할 수 있습니다.
표 6-1은 최대 100개까지 동시 커넥션이 가능한 데이터베이스에 균등 분배를 적용한 결과입니다.
서비스 B, D는 각각 최대 커넥션 쿼터에 도달해 커넥션 대기 상태에 빠진 적이 있습니다.
Table 6-1. Connection quota allocations evenly distributed
| Service | Quota | Max used | Waits |
|---|---|---|---|
| A | 20 | 5 | No |
| B | 20 | 20 | Yes |
| C | 20 | 15 | No |
| D | 20 | 20 | Yes |
| E | 20 | 14 | No |
서비스 A는 남는 커넥션을 다른 서비스에 재할당하는 것이 합리적입니다.
유휴 커넥션을 재할당해 최종적으로 표 6-3과 같이 커넥션 대기가 없어지는 최적의 커넥션 수를 할당할 수 있습니다.
Table 6-3. Further connection quota tuning results in no connection waits
| Service | Quota | Max used | Waits |
|---|---|---|---|
| A | 8 | 5 | No |
| B | 29 | 27 | No |
| C | 20 | 15 | No |
| D | 25 | 25 | No |
| E | 18 | 14 | No |
각 서비스별로 메트릭을 수집하는 피트니스 함수를 통해 분석하면, 현재 사용 중인 커넥션 수가 최대 커넥션 수에 얼마나 근접했는지, 또 각 서비스마다 쿼터 대비 여유분은 얼마나 되는지 바로바로 파악할 수 있습니다.
확장성Scalability
확장성은 서비스 응답 시간을 일정하게 유지하고 요청량에 따라 서비스 규모를 늘리는 능력을 말하며 분산 아키텍처의 중요한 장점인데, 데이터베이스도 가능합니다.
그림 6-7에서 서비스 확장성은 처리량과 용량에서 데이터베이스에 엄청난 부담을 줄 수 있습니다.
Figure 6-7. The database must also scale when services scale
앞에서 데이터베이스 커넥션 쿼터를 다듬어 개선했지만 표 6-4와 같이 전체 데이터베이스 커넥션 수가 100개에 이르면 사정이 달라집니다.
Table 6-4. When services scale, more connection are used than are available
| Service | Quota | Max used | Instances | Total used |
|---|---|---|---|---|
| A | 8 | 5 | 2 | 10 |
| B | 29 | 27 | 3 | 81 |
| C | 20 | 15 | 3 | 45 |
| D | 25 | 25 | 2 | 50 |
| E | 18 | 14 | 4 | 56 |
| Total | 100 | 86 | 14 | 242 |
커넥션 100개를 잘 분배해도 총 커넥션 수가 242개면 커넥션 대기가 빈번하게 발생하고 타임아웃이 자주 발생할 것입니다.
이럴 때 그림 6-8처럼 데이터를 개별 데이터 도메인 또는 서비스별 데이터베이스database-per-service로 분해하면, 데이터베이스당 커넥션 수가 현저히 줄어들어 서비스가 확장돼도 데이터베이스 확장성과 성능을 크게 높일 수 있습니다.
Figure 6-8. Breaking apart the database provides better database scalability
내고장성Fault tolerance
내고장성은 고장이 나도 시스템의 다른 부분은 중단 없이 가동시킬 수 있는 능력을 말합니다.
그림 6-9처럼 여러 서비스가 하나의 데이터베이스를 공유하면 단일 장애점single point of failure(SPF)이 돼 전체 시스템의 내고장성이 좋지 않게 됩니다.
Figure 6-9. If the database goes down, all services become nonoperational
그림 6-10처럼 내고장성이 필요하다면 데이터를 나눠 시스템에 단일 장애점을 제거해야 합니다.
그러면 데이터베이스 B에 고장이 발생해도 서비스 B, C만 가동이 중지되고 다른 서비스는 운영이 가능합니다.
Figure 6-10. Breaking apart the database achieves better fault tolerance
아키텍처 퀀텀Architectural quanta
아키텍처 퀀텀은 어떤 겨웅에 데이터베이스를 분해하는 게 좋을지 제시하는 훌륭한 길잡이 역할을 합니다.
그림 6-11은 5개 서비스가 단일 데이터베이스를 공유합니다. 따라서 단일 아키텍처 퀀텀입니다.
Figure 6-11. The database is part of the architectural quantum
그림 6-12와 같이 데이터베이스를 양분하면 서비스 A, B의 아키텍처 퀀텀과 서비스 C, D, E의 아키텍처 퀀텀이 분리됩니다.
Figure 6-12. Breaking up the database forms two architectural quanta
데이터베이스 타입 최적화Database type optimization
모놀리식 데이터베이스는 모든 데이터를 해당 데이터베이스 타입에 맞춰야 하므로 특정 타입의 데이터는 최상의 결과를 내지 못합니다.
모놀리식 데이터를 분해하면 특정 데이터를 그 특성외 최적화된 데이터베이스 타입으로 옮길 수 있습니다.
(예, 키-값 쌍 형식 데이터는 키-값 데이터베이스에 저장하는 것이 더 효과적)
6.1.2 데이터 통합인Data Integrators
데이터 분해인과 반대로
'어떤 경우에 데이터를 다시 합쳐야 하는가?' 에 대한 답변과 명분입니다.
데이터를 다시 합쳐야 하는 중요한 통합인을 두 가지 정리하면 다음과 같습니다.
- Data relationships
- Database transactions
데이터 관계Data relationships
그림 6-13 처럼 외래 키, 트리거, 뷰, 저장 프로시저 등의 아티팩트는 테이블과 엮여 데이터를 분해하기 어렵게 만드는 요인들입니다.
Figure 6-13. Foreign keys (FK), triggers, and views create tightly coupled relationships between data
외래 키, 트리거, 뷰는 데이터 일관성과 무결성을 지원하기 위해 꼭 필요한 물리적 아티팩트입니다.
그러나 데이터를 다른 스키마나 데이터베이스로 이전해 경계 콘텍스트를 구성하려면 그림 6-14와 가티 특정 아티팩트는 모두 들어내야 합니다.
마이크로서비스 아키텍처에서 서비스별 데이터베이스 패턴database-per-service pattern을 적용하려면 기존 왜래 키와 뷰는 제거해야 합니다.
Figure 6-14. Data artifacts must be removed when breaking apart data
서비스 A에 속한 테이블들은 동일한 경계 콘텍스트, 동일한 스키마, 동일한 데이터베이스에 있으므로 외래 키 관계를 유지시킬 수 있지만,
서비스 B와 C에 있는 테이블 사이의 외래 키는 다른 데이터베이스나 스키마와 연결돼 있으므로 모두 삭제해야 합니다.
데이터 간의 관계는 논리적이든 물리적이든 데이터 통합인입니다.
데이터를 분해해야 하는지 통합해야 하는지에 대한 트레이드오프가 발생합니다.
데이블 간 외래 키 관계를 유지하는 것(데이터 통합인)보다 변경 관리를 잘하는 것(데이터 분해인)이 더 중요한가?
내고장성(데이터 분해인)을 높이는 것과 테이블 간의 구체화 뷰(materialized view)를 유지하는 것(데이터 통합인) 중 어느 쪽이 더 가치 있는가?
어느 쪽이 가치가 있고 중요한지 잘 따져보면 데이터를 분해해야 하는지, 분해한다면 어느 정도로 스키마를 나눌지 판단하는 데 결정적인 힌트가 될 것입니다.
데이터베이스 트랜잭션Database transactions
그림 6-15 처럼 한 서비스가 데이터베이스의 모든 작업에 작업 단위로 커밋이나 롤백이 된다면 데이터 통합인입니다.
Figure 6-15. A single transactional unit of work exists when the data is together
그림 6-16과 같이 한 테이블에서 일어난 쓰기 작업은 커밋이 가능하지만 다른 테이블에서 발생한 에러는 같은 트랜잭션으로 묶을 수 없으므로 반드시 데이터 일관성, 무결성 이슈가 발생합니다.
Figure 6-16. Single unit of work transactions don’t exist when data is broken apart
6.2 모놀리식 데이터 분해
그림 6-17의 5단계 프로세스는 데이터를 분해하는 체계로, 데이터 도메인 개념을 적극 활용해 데이터를 개별 스키마로 옮기는 마이그레이션을 점진적으로, 반복적으로, 체계적으로 진행합니다.
Figure 6-17. Five-step process for decomposing a monolithic database
데이터 도메인은 테이블, 뷰, 외래 키, 트리거 등과 같은 연관된 데이터베이스 아티팩트들의 집합입니다.
표 6-5는 데이터 도메인에 해당하는 테이블입니다.
Table 6-5. Existing Sysops Squad database tables assigned to data domains
| Table | Proposed data domains |
|---|---|
| customer | Customer |
| customer_notification | Customer |
| survey | Survey |
| question | Survey |
| survey_administered | Survey |
| survey_question | Survey |
| survey_response | Survey |
| billing | Payment |
| contract | Payment |
| payment_method | Payment |
| payment | Payment |
| sysops_user | Profile |
| profile | Profile |
| expert_profile | Profile |
| expertise | Profile |
| location | Profile |
| article | Knowledge Base |
| tag | Knowledge Base |
| keyword | Knowledge Base |
| article_tag | Knowledge Base |
| article_keyword | Knowledge Base |
| ticket | Ticketing |
| ticket_type | Ticketing |
| ticket_history | Ticketing |
데이터베이스를 축구공이라고 생각하면 데이터 도메인의 개념을 이해하기 쉽습니다.
그림 6-18에서 축구공의 흰색 육각형은 각각의 데이터 도메인을 나타내며, 이 도메인에 관련된 테이블과 그와 결합된 모든 아티팩트는 이 육각형 안에 들어 있습니다.
Figure 6-18. Database objects in a hexagon belong in a data domain
흰색 육각형 내부에서는 테이블 디펜던시 및 관계가 보존되지만, 그 경계를 벗어나 육각형들 상호 간에는 보존되지 않습니다.
그림에서 실선은 데이터 도메인 내부에 구성된 디펜던시를, 점선은 교차 데이터 도메인 디펜던시를 각각 나타냅니다.
점선의 교차 도메인 디펜던시는 데이터 도메인을 개별 스키마로 추출하면서 반드시 제거해야 할 대상입니다.
스콧 앰플러Scott Ambler와 프라모드 세달라지Pramod Sadalage가 쓴 < Refactoring Databases: Evolutionary Database Design > 에 있는 다양한 리팩터링 패턴을 활용하면 데이터 디펜던시를 안전하고 반복적으로 제거할 수 있습니다.
그림 6-19를 보면서 데이터 도메인을 정의하고 교차 도메인 디펜던시를 제거하는 과정 중에 결제를 나타내는 도메인을 확인해 볼 수 있습니다.
여기서 Customer 테이블과 V_Customer_Contract 뷰는 도메인이 다르므로 뷰를 제거합니다.
예제를 더 자세히 살펴보면 V_Customer_Contract 뷰는 Customer 테이블과 Payment 테이블과 조인해 오픈 티켓 정보를 조회하는 뷰입니다.
여기서 Customer 테이블에서 조회하는 컬럼은 customer_name 뿐이어서 우선 Customer 테이블 조인을 삭제하고 고객 명은 고객 서비스를 호출해 가져오는 것으로 변경합니다.
Figure 6-19. Tables belonging to data domains, extracted out, and connections that need to be broken
1단계: 데이터베이스 분석과 데이터 도메인 생성
현재 그림 6-20처럼 모든 서비스는 데이터베이스의 모든 데이터에 접근할 수 있습니다.
이는 그레고르 호페Gregor Hohpe)와 바비 울프(Bobby Woolf)의 < 기업 통합 패턴 > 에서 공유 데이터베이스 통합 스타일shared database intergration style로 언급된 내용입니다.
이렇게 데이터와 서비스가 긴밀하게 엮이면 데이터베이스 변경 관리가 아주 힘들어집니다.
Figure 6-20. Multiple services use the same database, accessing all the tables necessary for read or write purposes
데이터베이스 분해 첫 단계로 표 6-5에서 확인할 수 있듯이 연관된 테이블을 그룹핑해 데이터 도메인 후보를 추려낼 수 있습니다.
2단계: 데이터 도메인에 테이블 할당
테이블들을 특정 경계 콘텍스트로 묶고 특정 데이터 도메인에 속하는 테이블을 해당 스키마에 할당합니다.
그림 6-21처럼 데이터 도메인마다 스키마를 만들고 테이블들을 각자 속한 스키마로 옮깁니다.
Figure 6-21. Services use the primary schema according to their data domain needs
서로 다른 데이터 도메인에 속한 테이블 간에 밀접한 연관성과 커플링이 존재하다면, 해당 데이터 도메인들은 반드시 통합해야 합니다.
그러면 더 넓은 경계 콘텍스트가 형성됩니다.
예로 Billing 테이블을 원래 스키마(Other)에서 Payment라는 다른 데이터 도메인의 스키마로 변경할 수 있습니다.
ALTER SCHEMA Payment TRANSFER Other.Billing;다른 예로 자기 스키마에 속하지 않는 테이블에 시노님synonym(동의어)을 만들어 쓰는 방법도 있습니다.
시노님은 심볼릭 링크와 비슷한 일종의 별칭으로, 동일한(또는 상이한) 스키마나 서버에 존재할 수 있는 다른 데이터베이스 객체를 가리키는 또 다른 이름입니다.
하지만 다른 스키마에 있는 테이블을 시노님으로 참조하면 애플리케이션 관점에서 또 다른 커플링이 됩니다.
데이터 도메인을 올바르게 구성하려면 어차피 이런 결합점을 분해해야 하므로 통합점을 데이터베이스 레이어에서 애플리케이션 레이어로 옮기는 게 좋습니다.
시노님은 교차 스키마 쿼리를 없애는 건 아니지만, 디펜던시 체크와 코드 분석이 용이해져 결국 나중에 교차 스키마 쿼리를 분해하는 작업도 쉬워집니다.
3단계: 데이터 도메인에 접속하는 데이터베이스 커넥션 분리
각 서비스가 특정 스키마에 확실히 연결돼 자기 데이터 도메인에 속한 테이블에 읽기/쓰기 액세스가 가능하도록 데이터베이스 커넥션 로직을 리팩터링합니다.
모든 교차 스키마 액세스를 서비스 수준에서 제거해야 하므로 이 전환 작업이 가장 어렵습니다.
그림 6-22는 모든 데이터 액세스가 서비스와 그 서비스에 연결된 스키마를 통해서만 이뤄지도록 데이터베이스 구성을 변경한 것입니다.
서비스C는 서비스D를 통해 스키마 D를 조회하는 방법으로 변경하고, 앞서 시노님으로 생성했던 것들도 모두 삭제합니다.
Figure 6-22. Move the cross-schema object access to the services, away from direct cross schema access
이 단계를 거치면 데이터베이스는 각 서비스마다 서비스별 데이터 주권data sovereignty per service 체제로 전환됩니다.
장점
- 다른 도메인에 영향을 주지 않고 데이터베이스 스키마 변경 가능
- 서비스별 적합한 데이터베이스와 기술 사용 가능
단점
- 대량의 데이터를 처리할 때 성능 이슈 발생
- 데이터 참조 무결성을 지킬 수 없어 데이터 품질 저하
- 다른 도메인에 속한 테이블에 접근하는 데이터베이스 코드는 모두 서비스 레이어로 옮겨야 함
4단계: 개별 데이터베이스 서버로 스키마 이전
스키마를 물리적으로 분리된 다른 데이터베이스로 옮기는 작업은 백업 및 복원backup and restore, 복제replication라는 두 가지 방법이 있습니다.
백업 및 복원
데이터 도메인에 있는 각 스키마를 백업하고, 데이터 도메인 별로 데이터베이스 서버를 구성합니다.
스키마를 복원한 후 새 데이터베이스 서버에 있는 스키마 서비스를 연결합니다.
원래 데이터베이스 서버에서 스키마를 제거합니다.
복제
데이터 도메인별로 데이터베이스 서버를 구성한 다음, 스키마를 복제하고 새 데이터베이스 서버로 커넥션을 전환합니다.
원래 데이터베이스 서버에서 스키마를 제거합니다.
그림 6-23은 데이터 도메인 당 하나의 데이터베이스 서버가 있도록 여러 데이터베이스 서버를 복제 방식으로 구성한 예입니다.
Figure 6-23. Replicate schemas (data domains) to their own database servers
5단계: 독립적 데이터베이스 서버로 전환
그림 6-24처럼 이전 데이터베이스에 있는 스키마를 삭제하고 접속했던 모든 커넥션을 삭제합니다.
Figure 6-24. Independent database servers for each data domain
이후 데이터베이스 서버를 최적화하면 가용성, 확장성을 개선할 수 있습니다.
또 데이터 분석을 통해 어떤 데이터베이스가 적합한지 결정해 폴리글랏 데이터베이스 체계를 도입할 수 있습니다.
6.3 데이터베이스 타입 선택
다음의 측면에서 다양한 데이터베이스 제품을 분석해 등급으로 나타내 볼 것입니다.
- Ease-of-learning curve
- Ease of data modeling
- Scalability/throughput
- Availability/partition tolerance
- Consistency
- Programming language support, product maturity, SQL support, and community
- Read/write priority
6.3.1 Relational Databases
| Rating subject | RDBMS databases (Oracle, SQL Server, Postgres, etc.) |
|---|---|
| Ease-of-learning curve | ⭐⭐⭐⭐ |
| Ease of data modeling | ⭐⭐⭐ |
| Scalability/throughput | ⭐⭐ |
| Availability/partition tolerance | ⭐ |
| Consistency | ⭐⭐⭐⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐⭐⭐ |
| Read/write priority | Read -----*----- Write |
Figure 6-25. Relational databases rated for various adoption characteristics
애그리거트 지향
애그리거트(aggregate)는 상호 연관돼 있고 구조가 복잡한 데이터를 다룰 때 많이 사용되는 개념으로 에릭 에반스Erik Evans의 < 도메인 주도 설계 > 에서 나온 용어입니다.
장점
- 전체 애그리거트를 여러 다른 서버에 복사할 수 있어 데이터를 서버 클러스터에 배포하기 쉬움
- 데이터베이스에서 조인 사용이 줄어 읽기/쓰기 성능 향상
- 애플리케이션 모델과 스토리지 모델 간의 임피던스 불일치impedence mismatch가 감소
- 객체와 관계의 불일치, 즉 관계형 모델과 메모리 내 데이터 구조의 차이를 의미함
단점
- 적절한 애그리거트를 설정하기 어렵고 경계를 바꾸기도 어려움
- 여러 애그리거트에 걸쳐 데이터를 분석하기 어려움
6.3.2 Key-Value Databases
NoSQL 데이터베이스가 부상하게 된 계기와 사용법, 그리고 사용할 때 어떤 장단점이 있는지는 프라모드 세달라지Parmod Sadalage와 마틴 파울러Martin Fowler가 함게 쓴 < NoSQL > 에 자세히 소개되어 잇습니다.
키-값 데이터베이스는 니즈에 따라 선택할 수 있습니다.
아마존 다이나모DB나 리악 KV(Riak KV)와 같은 영구 저장형 키-값 데이터베이스가 있고,
멤캐시DB(MemcacheDB)와 같은 비영구 저장형 키-값 데이터베이스도 있으며,
레디스 처럼 저장 방식을 영구/비영구 모두 설정 가능한 데이터베이스도 있습니다.
| Rating subject | Key value databases (Redis, DynamoDB, Riak, etc.) |
|---|---|
| Ease-of-learning curve | ⭐⭐⭐ |
| Ease of data modeling | ⭐ |
| Scalability/throughput | ⭐⭐⭐⭐ |
| Availability/partition tolerance | ⭐⭐⭐⭐ |
| Consistency | ⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐⭐ |
| Read/write priority | Read --*-------- Write |
Figure 6-26. Key-value databases rated for various adoption characteristics
Consistency
쓰기 작업을 하면서 읽기 작업 도중 쿼럼을 적용하는 것과 유사한 설정을 할 수 있습니다.
*쿼럼: 분산 시스템에서 작업을 수행하기 위해 분산 트랜잭션이 획득해야 하는 최소 투표 수입니다. 쿼럼 기반 기술은 분산 시스템에서 일관된 작업을 수행하기 위해 구현합니다.
(이를 조정 가능한 일관성tunable consistency이라고 합니다.).
레이턴시를 양보하면 높은 일관성을 얻을 수 있습니다.
쓰기 작업의 일관성을 높이려면 모든 노드가 응답해야 하므로 내분할성이 떨어집니다.
과반수 쿼럼majority quorum을 사용하는 것도 방법입니다.
*과반수 쿼럼: 리악 레플리카를 5개로 구성했을 때 3개 이상의 레플리카가 응답할 때 쓰기 작업이 처리된 것으로 간주하는 방법
Sharding
개념상 파티셔닝과 비슷하지만, 데이터가 다른 서버나 노드에 있다는 차이점이 있습니다.
노드들은 샤딩 키에 따라 데이터가 어디에 있고 어디에 저장해야 할지를 서로 협력해 알아냅니다.
샤드는 수평 파티션을 의미하는 데이터베이스 분야의 전문 용어입니다.
6.3.3 Document Databases
문서는 사람이 읽을 수 있고, 자기 기술적이며self-describing, 계층적인 트리 구조를 가진 데이터입니다.
| Rating subject | Document databases (MongoDB, CouchDB, Marklogic, etc.) |
|---|---|
| Ease-of-learning curve | ⭐⭐⭐ |
| Ease of data modeling | ⭐⭐⭐ |
| Scalability/throughput | ⭐⭐ |
| Availability/partition tolerance | ⭐⭐⭐ |
| Consistency | ⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐⭐ |
| Read/write priority | Read --*-------- Write |
Figure 6-27. Document databases rated for various adoption characteristics
Schema-less Databases
데이터와 스키매 애트리뷰트가 중복 가능한 특징이 있습니다.
두 엔트리의 스키마 또는 애트리뷰트명이 같아야 할 필요가 없으므로 동적인 변경 관리가 가능하고 구조적으로 유연합니다.
하지만 데이터는 항상 스키마를 가지고 있다는 사실을 잊어선 안됩니다.
실제 애플리케이션은 데이터베이스가 반환한 여러 버전의 스키마를 처리해야 하므로 NoSQL 데이터베이스가 schema-less하다는 주장은 잘못된 것입니다.
6.3.4 Column Family Databases
Wide column database, big table database 라고 하며 각 컬럼이 이름-값 쌍이고 로우마다 컬럼 수가 가변적입니다.
이름은 column-key, 값은 column-value, 로우의 primary key는 row key라고 합니다.
| Rating subject | Column family databases (Cassandra, Scylla, Druid, etc.) |
|---|---|
| Ease-of-learning curve | ⭐⭐ |
| Ease of data modeling | ⭐ |
| Scalability/throughput | ⭐⭐⭐⭐ |
| Availability/partition tolerance | ⭐⭐⭐⭐ |
| Consistency | ⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐ |
| Read/write priority | Read --------*-- Write |
Figure 6-28. Column family databases rated for various adoption characteristics
Ease-of-learning curve
일무 이름-값 쌍에는 컬럼들의 맵을 포함하는 수퍼 컬럼이 있는데, 이 개념을 이해하고 사용하려면 시간이 필요합니다.
Ease of data modeling
데이터는 단일 로우 식별자가 있는 이름-값 쌍의 그룹으로 정렬돼야 하고, 이런 로우 키를 설계하려면 이터레이션을 여러 번 거쳐야 합니다.
카산드라 쿼리 언어Cassandra Query Language(CQL)라는 유사 SQL 언어를 지원해 데이터 모델링을 할 수 있습니다.
Consistency
일관성 레벨을 높이면 가용성과 내분할성이 저하되는 트레이드오프가 있습니다.
Read/write priority
SSTable(Sorted String Table), Commit Log, MemTable 이라는 개념을 사용하므로 데이터가 존재할 때마다 이름-값 쌍이 채워지며 관계형 데이터베이스보다 희소 데이터를 훨씬 잘 처리합니다.
*카산드라는 데이터가 입력되면 커밋 로그에 내용이 기록되고 SSTable에 바로 저장하면 성능이 저하되므로 메모리에 있는 MemTable을 버퍼 삼아 기록합니다. 커밋 로그와 MemTable이 꽉 차면 그때마다 SSTable로 플러스됩니다.
*희소 데이터(sparse data)는 전체 공간에 비해 데이터가 존재하는 영역이 협소한 데이터를 말하고, 밀집 데이터(dense data)는 그 반대의 경우를 말합니다. nullable 컬럼이 100개인 테이블에 10만개의 row가 있지만 한 두개 컬럼을 제외하고 모두 NULL인 경우가 희소 데이터입니다.
6.3.5 Graph Databases
그래프 데이터베이스는 노드를 이용해 엔티티와 그 속성을 저장합니다.
노드는 엣지라는 명시적인 객체에 연결됩니다.
노드는 관계에 따라 구성되며, 엣지를 순회하면 연결된 데이터를 분석할 수 있습니다.
Figure 6-29. In graph databases, direction of the edge has significance when querying
그림 6-29와 같이 엣지는 방향이 중요합니다.
나가는 방향의 TICKET_CREATED 엣지를 통해 티켓 노드로부터 순회할 수 있고,
들어오는 방향의 TICKET_CREATED 엣지를 통해 고객 노드로부터 순회할 수 있습니다.
| Rating subject | Graph databases (Neo4j, Infinite graph, Tigergraph, etc.) |
|---|---|
| Ease-of-learning curve | ⭐ |
| Ease of data modeling | ⭐ |
| Scalability/throughput | ⭐⭐⭐ |
| Availability/partition tolerance | ⭐⭐⭐ |
| Consistency | ⭐⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐ |
| Read/write priority | Read --*-------- Write |
Figure 6-30. Graph databases rated for various adoption characteristics
Programming language support, product maturity, SQL support, and community
Dijkstra's algorithm, node similarity 같은 알고리즘이 이미 데이터베이스에 구현돼 있어 처음부터 작성해야 하는 부담이 없습니다.
그렘린이라는 언어 프레임워크는 다른 많은 데이터베이스에서도 작동되므로 사용이 간편합니다.
Neo4J는 개발자가 데이터베이스를 쉽게 쿼리할 수 있도록 해주는 사이퍼Cypher 라는 쿼리 언어를 제공합니다.
6.3.6 NewSQL Databases
NewSQL은 매튜 애슬렛Matthew Aslett이 NoSQL 데이터베이스의 특유의 확장성과 ACID 같은 관계형 데이터베이스의 장점을 겸비한 새로운 개념의 데이터베이스를 정의하려고 사용한 언어입니다.
NewSQL 데이터베이스는 자동화 데이터 파티셔닝 또는 샤딩을 제공합니다.
그래서 수평 확장 및 향상된 가용성을 제공할 수 있습니다.
| Rating subject | NewSQL databases (VoltDB, NuoDB, ClustrixDB etc.) |
|---|---|
| Ease-of-learning curve | ⭐⭐⭐ |
| Ease of data modeling | ⭐⭐⭐ |
| Scalability/throughput | ⭐⭐⭐ |
| Availability/partition tolerance | ⭐⭐⭐ |
| Consistency | ⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐ |
| Read/write priority | Read -----*----- Write |
Figure 6-31. New SQL databases rated for various adoption characteristics
6.3.7 Cloud Native Databases
| Rating subject | Cloud databases (Snowflake, Amazon Redshift etc.) |
|---|---|
| Ease-of-learning curve | ⭐⭐ |
| Ease of data modeling | ⭐⭐ |
| Scalability/throughput | ⭐⭐⭐⭐ |
| Availability/partition tolerance | ⭐⭐⭐ |
| Consistency | ⭐⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐ |
| Read/write priority | Read --*-------- Write |
Figure 6-32. Cloud native databases rated for various adoption characteristics
Ease-of-learning curve
Datomic의 경우 모델 자체가 완전히 다르고 불변의 원자적 팩트immutable atomic fact라는 개념을 사용해 학습이 필요합니다.
Ease of data modeling
Datomic은 테이블의 개념이 없고 미리 애트리뷰트를 정의할 필요도 없습니다.
각 애트리뷰트의 속성은 정의해야 하며 엔티티는 모든 애트리뷰트를 소유할 수 있습니다.
Snowflake, Redshift는 data warehouse 타입의 워크로드에 더 많이 사용됩니다.
Availability/partition tolerance
Production Topology를 사용해 배포하면 고가용성을 확보하고 단일 장애점이 사라지며 캐싱을 폭넓게 활용할 수 있습니다.
예로, Snowflake는 여러 region과 acount를 대상으로 데이터베이스를 복제합니다.
Redshift는 단일 가용 영역에서 실행되는데, 다수의 클러스터에서 실행하면 고가용성을 얻을 수 있습니다.
Programming language support, product maturity, SQL support, and community
Datomic은 모든 예제가 Clojure 언어를 사용하고 저장 프로시저도 클로저로 코딩돼 있어서 학습이 필요합니다.
6.3.8 Time-Series Databases
정해진 시간대time window에 수집된 일련의 데이터 포인트를 보관하는 일에 특화된,
그래서 유저가 일정 시간 동안의 변경을 추적하는 데 유용한 데이터베이스입니다.
| Rating subject | Time series databases (InfluxDB, TimescaleDB etc.) |
|---|---|
| Ease-of-learning curve | ⭐ |
| Ease of data modeling | ⭐⭐ |
| Scalability/throughput | ⭐⭐⭐⭐ |
| Availability/partition tolerance | ⭐⭐ |
| Consistency | ⭐⭐⭐ |
| Programming language support, product maturity, SQL support, and community | ⭐⭐ |
| Read/write priority | Read --*-------- Write |
Figure 6-33. Time-series databases rated for various adoption characteristics
Scalability/throughput
타임스케일은 포스트그레스큐엘 기반으로 작동되는 시계열 데이터베이스로, 표준 확장성/처리량 개선 패턴을 적용할 수 있습니다.
인플럭스DB는 클러스터 모드로 실행할 경우, 메타데이터를 관리하는 메타 노드와 실제 데이터를 저장하는 데이터 노드를 사용함으로써 확장성, 처리량을 개선할 수 있습니다.
Availability/partition tolerance
인플럭스DB 같은 데이터베이스는 복제 팩터와 더불어 메타 노드 및 데이터 노드 설정을 조정할 수 있으므로 가용성/내분할성이 우수합니다.
시계열 데이터베이스는 생성된 데이터에 타임스탬프가 자동으로 생성되고, 정보 태그나 애트리뷰트가 데이터에 포함됩니다.
데이터는 주어진 시간대에서 팩트를 기준으로 쿼리합니다.
그래서 범용 데이터베이스는 아닙니다.
6.4 한빛가이버 사가: 폴리글랏 데이터베이스
고객 설문 관련 DB 변경건에 대한 대화...
그림 6-34는 현재 관계형 데이터베이스의 테이블 구조입니다.
Figure 6-34. Tables and relationships in the sysops survey data domain
그림 6-35는 두 테이블의 실제 데이터를 보여줍니다.
Figure 6-35. Relational data in tables for survey and question in the survey data domain
이 데이터를 문서형 데이터베이스 모델링 하는 방법으로 단일 애그리거트 문서와 분할된 애그리거트 문서 두 가지이며
그림 6-36은 단일 애그리거트 방식을 보여줍니다.
예제 6-3의 JSON 문서는 설문 데이터와 전체 문항 데이터가 하나의 문서로 저장돼 있어 한 번에 고객 설문 데이터를 데이터베이스에서 가져올 수 있습니다.
Figure 6-36. Survey model with single aggregate
Example 6-3. JSON document for single aggregate design with children embedded
# Survey aggregate with embedded questions
{
"survey_id":"19999",
"created_date":"Dec 28 2021",
"description":"Survey to gauge customer...",
"questions":[
{
"question_id":"50001",
"question":"Rate the expert",
"answer_type":"Option",
"answer_options":"1,2,3,4,5",
"order":"2"
},
{
"question_id":"50000",
"question":"Did the expert fix the problem?",
"answer_type":"Boolean",
"answer_options":"Yes,No",
"order":"1"
}
]
}이 방식은 각 설문 문서마다 문항이 중복되기 때문에 데이터베이스에서 추가 작업이 필요하다는 지적이 나와
그림 6-37처럼 여러 애그리거트로 분리해 설문 문항이 독립적으로 작동되게끔 만들었습니다.
예제 6-4는 이 모델에 따라 생성된 JSON 문서입니다.
Figure 6-37. Survey model with multiple aggregates with references
Example 6-4. JSON document with aggregates split and parent document showing references to children
# Survey aggregate with references to Questions
{
"survey_id":"19999",
"created_date":"Dec 28",
"description":"Survey to gauge customer...",
"questions":[
{
"question_id":"50001",
"order":"2"
},
{
"question_id":"50000",
"order":"1"
}
]
}
# Question aggregate
{
"question_id":"50001",
"question":"Rate the expert",
"answer_type":"Option",
"answer_options":"1,2,3,4,5"
}
{
"question_id":"50000",
"question":"Did the expert fix the probelm?",
"answer_type":"Boolean",
"answer_options":"Yes,No"
}UI 개발 쪽에서는 단일 애그리거트 모델이 낫다고 생각했고
DBA는 각 설문 레코드별로 문항 데이터의 중복을 방지할 수 있는 다중 애그리거트 모델을 선호했습니다.
모두 트레이드오프를 신중히 따져본 결과 문항 데이터가 중복되더라도 UI에서 변경과 렌더링이 쉬운 방향으로 설계하는 게 낫다고 의견을 모았습니다.
이 내용을 ADR을 작성해 근거를 남겼습니다.
ADR: 고객 설문은 문서형 데이터베이스를 사용
Context
고개은 수리 완료 후 웹 페이지에 접속해서 설문 응답을 할 수 있다.
수리 또는 설치된 전자 제품의 종류에 따라 설문은 다섯 가지 종류로 나뉜다.
현재 설문 데이터는 관계형 데이터베이스에 넣고 관리하지만, 개발 팀은 JSON을 사용하는 문서형 데이터베이스로 마이그레이션하길 원한다.
Decision
고객 설문은 문서형 데이터베이스를 사용한다.
마케팅 부서에서 고객 설문을 변경하는 작업은 더 큰 유연성과 적시성을 요한다.
문서형 데이터베이스로 바꾸면 더 유연하게 변경할 수 있고 적시에 반영할 수 있을 것이다.
또 문서형 데이터베이스를 사용하면 고객 설문 UI를 단순화하고 설문을 더 쉽게 변경할 수 있다.
Consequences
단일 애그리거트 형태로 사용할 예정이므로 공통 설문 문항이 수정, 추가, 삭제될 때마다 여러 문서를 변경해야 한다.
관계형 데이터베이스에서 문서형 데이터베이스로 데이터를 마이그레이션 하는 중에는 설문 기능이 잠시 중단될 것이다.
Metadata
Metadata
Assignees
Labels
Projects
Status