요약
- 12장. 데이터 시스템의 미래의 나머지 부분에 대해 이해함.
- 데이터베이스 언번들링
- 데이터 저장소 기술 구성하기
- 색인 생성하기
- 모든 것의 메타데이터베이스
- 언번들링이 동작하게 만들기
- 언번들링 대 통합 시스템
- 뭐가 빠졌지?
- 데이터플로 주변 애플리케이션 설계
- 파생 함수로서의 애플리케이션 코드
- 애플리케이션 코드와 상태의 분리
- 데이터플로: 상태 변경과 애플리케이션 코드 간 상호작용
- 스트림 처리자와 서비스
메모
데이터베이스 언번들링
- 데이터베이스, 하둡, 운영체제는 모두 데이터를 저장, 처리, 질의하는 기능을 수행함.
- 데이터베이스는 특정 데이터 모델의 레코드로, 운영체제는 파일 시스템에 파일로 데이터를 저장함.
- 유닉스와 관계형 데이터베이스는 정보 관리 문제를 다른 철학으로 접근했음.
- 유닉스는 저수준의 하드웨어 추상화를 제공하고, 관계형 데이터베이스는 고수준의 추상화를 제공했음.
- 유닉스에서 파이프와 파일, 데이터베이스에서 SQL과 트랜잭션이 개발되었음.
- 유닉스와 관계형 데이터베이스 사이의 갈등은 지속되고 있으며, 이 글에서는 두 철학을 화해시키려 함.
- NoSQL을 유닉스의 저수준 추상화 접근법을 분산 OLTP 데이터 저장소 분야로 적용하는 움직임으로 해석함.
데이터 저장소 기술 구성하기
- 데이터베이스가 제공하는 다양한 기능은 아래와 같음.
- 보조 색인은 필드 값을 기반으로 레코드를 효율적으로 검색할 수 있는 기능임.
- 구체화 뷰는 질의 결과를 미리 연산한 캐시의 일종임.
- 복제 로그는 데이터의 복사본을 다른 노드에 최신 상태로 유지하는 기능임.
- 전문 검색 색인은 텍스트에서 키워드 검색을 가능하게 하는 기능임.
- 또한, 전문 검색 색인을 구축하는 방법, 구체화 뷰를 유지하는 방법, 그리고 데이터베이스의 변경 사항을 파생 데이터 시스템으로 복제하는 방법에 대해 설명했음.
- 데이터베이스에 내장된 기능과 일괄 처리와 스트림 처리로 구축하는 파생 데이터 시스템 사이에는 유사점이 있음.
색인 생성하기
- 관계형 데이터베이스에서 색인을 생성하기 위해 CREATE INDEX를 실행하면 테이블의 일관된 스냅샷을 사용해 스캔하고, 필드 값을 골라 정렬하며 색인에 기록함.
- 이후에는 스냅샷을 만든 이후에 실행된 쓰기의 백로그를 처리함.
- 색인 생성 완료 후에는, 트랜잭션이 테이블에 쓸 때마다 색인이 꾸준히 갱신되어야 함.
- 이 과정은 새 팔로워 복제본을 구축하는 과정과 상당히 유사하며, 스트림 시스템에서 변경 데이터 캡처의 예비 과정과도 유사함.
- CREATE INDEX를 실행할 때마다, 데이터베이스는 기존 데이터셋을 재처리해서, 기존 데이터를 반영하는 새로운 뷰로서 색인을 파생시킴.
- 기존 데이터는 발생한 모든 변경 로그보다는 특정 상태의 스냅샷일 수 있지만, 변경 로그와 상태 스냅샷은 상당히 관련이 있음.
모든 것의 메타데이터베이스
- 전체 조직의 데이터플로가 거대한 데이터베이스처럼 보이며, 일괄 처리나 스트림 처리, ETL 처리를 통해 데이터를 특정 장소에서 다른 장소로 전송할 때마다 데이터베이스의 하위 시스템과 동일하게 작동함.
- 이러한 일괄 처리와 스트림 처리는 트리거, 스토어드 프로시저, 구체화 뷰 유지 루틴을 구현한 것과 비슷하며, 이들은 파생 데이터 시스템을 유지함.
- 두 가지 접근법이 제시됨.
- 연합 데이터베이스
- 연합 데이터베이스는 다양한 저장소 엔진과 처리 메서드를 통합하여 질의 인터페이스를 제공함.
- 이는 하단 저장소에 직접 접근할 수 있게 하며, 필요시 다른 장소의 데이터를 결합할 수 있음.
- 언번들링 데이터베이스.
- 언번들링 데이터베이스는 다른 기술에 걸친 쓰기를 동기화할 수 있는 방식으로 데이터베이스의 색인 유지 기능을 확장함.
- 이는 데이터가 올바른 장소에 반영되도록 보장함.
- 이러한 접근법은 유닉스 전통의 작은 도구를 사용하여 하나의 잘 하는 작업을 수행함.
- 이 도구들은 통일된 저수준 API를 통해 통신하며, 필요시 고수준 언어를 사용해 구성할 수 있음.
언번들링이 동작하게 만들기
- 연합과 언번들링은 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 시스템을 만드는 방법임.
- 연합된 읽기 전용 질의는 한 데이터 모델을 다른 모델로 사상하고, 여러 저장 시스템에 적용되는 쓰기를 동기화하는 것은 더 큰 엔지니어링 문제임.
- 이종 저장소 시스템 간 분산 트랜잭션이 쓰기 동기화의 전통적인 접근법이지만, 멱등성을 기반으로 쓰기를 수행하는 비동기 이벤트 로그를 사용하는 것이 더 강력하고 현실적인 접근법이라고 봄.
- 로그 기반 통합의 장점은 다양한 구성 요소 간 느슨한 결합임.
- 이는 시스템 수준과 인적 수준에서 모두 명확함.
- 시스템 수준에서는 전체 시스템이 개별 구성 요소의 장애나 성능 저하에 잘 견디며, 인적 수준에서는 각 팀이 소프트웨어 구성 요소와 서비스를 독립적으로 개발하고 유지보수할 수 있음.
언번들링 대 통합 시스템
- 언번들링이 실제로 미래에 사용될 방법이라고 가정해도 현재 형태의 데이터베이스를 대체하지는 못할 것임.
- 데이터베이스는 여전히 필요하며, 스트림 처리자의 상태를 유지하고, 일괄 처리와 스트림 처리자의 출력에 대한 질의를 처리하는 데 필요함.
- 여러 다른 인프라에서 수행하는 복잡성도 문제가 될 수 있으며, 각 소프트웨어마다 학습 곡선, 설정 문제, 운영상에서만 나타나는 특성이 있음.
- 따라서 동적 부분을 가능하면 적게 배포해야 유리함.
- 언번들링의 목표는 특정 작업부하에 대한 성능 측면에서 개별 데이터베이스와 경쟁하는 것이 아니라, 단일 소프트웨어로 가능한 것보다 더 넓은 범위의 작업부하에 대해 좋은 성능을 달성하기 위함임.
- 필요한 모든 것을 만족하는 단일 기술이 있다면 그냥 해당 제품을 사용하는 것이 좋음.
- 언번들링과 합성의 장점은 요구사항을 모두 만족하는 단일 소프트웨어가 없는 상황에서만 드러남.
뭐가 빠졌지?
- 데이터 시스템을 구성하는 도구는 점점 좋아지고 있지만, 아직까지 유닉스 셸처럼 저장소와 처리 시스템을 구성하는 고수준 언어로서의 언번들링된 데이터베이스가 존재하지 않는다고 주장함.
- 이러한 상황에서, mysql과 elasticsearch를 유닉스 파이프와 비슷한 방식으로 단순하게 선언할 수 있다면 좋을 것이라고 제안함.
- 이러한 선언은 MySQL 데이터베이스에서 모든 문서를 가져와 엘라스틱서치 클러스터에서 이 문서들을 색인하는 작업을 언번들링된 데이터베이스 관점으로 보여줌.
- 이 과정은 애플리케이션 코드 없이도 모든 변경 사항을 캡처하고 자동으로 검색 색인에 반영할 것임.
- 또한, 캐시를 사전계산하고 갱신하는 것을 쉽게 만들면 좋을 것이라고 제안함.
- 이러한 아이디어에 따라 복잡한 질의에 대한 구체화 뷰를 선언적으로 지정함으로써 캐시를 만드는 것을 상상할 수 있음.
- 이 분야에서는 미분 데이터플로 같은 초기 연구가 진행되고 있으며, 이런 아이디어가 프로덕션 시스템에 적용되기를 희망함.
데이터플로 주변 애플리케이션 설계
- '데이터베이스 인사이드 아웃' 접근법은 애플리케이션 코드로 특화된 저장소와 처리 시스템을 조립하는 언번들링 데이터베이스를 다루는 방식임.
- 이 접근법은 새로운 아키텍처라기보다는 디자인 패턴 또는 논의의 출발점으로 볼 수 있음.
- 이 아이디어는 여러 사람의 아이디어를 합친 결과로, 오즈와 저틀 같은 데이터플로 언어, 엘름 같은 함수형 반응형 프로그래밍 언어, 그리고 블룸과 같은 논리적 프로그래밍 언어와 많은 부분이 겹침.
- 스프레드시트는 데이터플로 프로그래밍 능력에서 주류 프로그래밍 언어보다 앞섬.
- 스프레드시트에서 한 셀에 수식을 넣으면 입력이 바뀔 때마다 결과가 자동으로 재계산됨.
- 이것은 데이터 시스템에서도 필요한 기능으로, 데이터베이스의 레코드가 변할 때마다 해당하는 색인이나 의존하는 캐시 뷰, 집계가 자동으로 갱신되어야 함.
- 비지칼크와 같은 초기 스프레드시트에서 배울 점이 아직 많이 있음.
- 현대 데이터 시스템과의 차이점은 내결함성과 확장성이 필요하며, 지속적으로 데이터를 저장해야 한다는 점임.
- 또한, 다른 그룹의 사람들이 개발한 이종 기술과 통합 가능하며, 기존 라이브러리와 서비스를 재사용해야 함.
- 이 아이디어를 확장하여 언번들링 데이터베이스와 데이터플로 주변에서 애플리케이션을 구축하는 방법을 탐구하는 것이 이번 절의 주요 내용임.
파생 함수로서의 애플리케이션 코드
- 데이터셋은 변환 함수를 거쳐 다른 데이터셋으로 파생됨.
- ex) 보조 색인은 파생 데이터셋의 일종으로, 기반 테이블의 각 로우나 문서마다 색인할 칼럼이나 필드를 선택하고 정렬함.
- 전문 검색 색인은 자연어 처리 함수를 사용하여 효율적인 검색을 위한 자료 구조를 만듦.
- 머신러닝 시스템의 모델은 특징 추출과 통계 분석 함수를 사용하여 학습 데이터로부터 파생되며, 새 입력 데이터가 모델에 적용될 때 모델의 출력이 파생됨.
- 캐시는 사용자 인터페이스에 보여질 형태의 데이터 집합을 포함하며, UI가 변하면 캐시를 채우고 재구축하는 방법의 정의를 갱신해야 함.
- 보조 색인용 파생 함수는 많은 데이터베이스의 핵심 기능으로, 간단한 명령으로 생성할 수 있음.
- 복잡한 기능을 지원하려면 특화된 튜닝이 필요함.
- 파생 데이터셋을 생성하는 함수가 표준 함수가 아니라면 사용자 정의 코드를 사용하여 애플리케이션에 특화된 요소를 다루어야 함.
- 많은 데이터베이스는 이 사용자 정의 코드에서 어려움을 겪음.
- 관계형 데이터베이스는 데이터베이스 내에서 애플리케이션 코드를 실행할 수 있게 해주는 트리거, 스토어드 프로시저, 사용자 정의 함수를 지원하지만, 이는 데이터베이스 설계 이후에 추가된 기능임.
애플리케이션 코드와 상태의 분리
- 데이터베이스는 이론적으로 애플리케이션 코드를 배포하는 환경이 될 수 있으나, 실제로는 이런 용도로 적합하지 않음.
- 데이터베이스는 의존성, 패키지 관리, 버전 컨트롤, 롤링 업그레이드, 발전성, 모니터링, 지표, 네트워크 서비스 호출, 외부 시스템과의 통합 등의 애플리케이션 배포 요구사항과 잘 맞지 않음.
- 반면에, 메소스, 얀, 도커, 쿠버네티스 등과 같은 배포와 클러스터 관리 도구는 애플리케이션 코드를 실행하는 목적으로 특별히 설계됐음.
- 이 도구들은 사용자 정의 함수의 실행을 지원하는 것보다 훨씬 잘 할 수 있음.
- 이렇게 시스템의 일부가 데이터 저장을 전문으로 하고, 다른 일부는 애플리케이션 코드 실행을 전문으로 하는 것이 합리적이라 생각함.
- 대부분의 웹 애플리케이션은 상태 비저장 서비스로 배포되며, 상태 관리(데이터베이스)와 상태 비저장 애플리케이션 로직을 분리하는 추세임.
- 웹 애플리케이션 모델에서 데이터베이스는 네트워크를 통해 동기식으로 접근 가능한 변경 가능한 공유 변수처럼 동작함.
- 그러나 대부분의 프로그래밍 언어에서는 변경 가능한 변수의 변경을 구독할 수 없으며, 주기적으로 읽을 수밖에 없음.
- 데이터베이스는 이 수동적 접근법을 상속하며, 변경된 데이터를 확인하려면 폴링, 즉 주기적으로 질의를 반복하는 것이 유일한 방법임.
- 변경 데이터 구독은 이제 막 등장하기 시작한 기능임.
데이터플로: 상태 변경과 애플리케이션 코드 간 상호작용
- 데이터플로는 애플리케이션 코드와 상태 관리 간의 관계를 재조정하며, 상태와 상태 변경, 그리고 상태를 처리하는 코드 간의 상호작용과 협동을 강조함.
- 원본 데이터베이스 외부에 파생 데이터셋을 생성하며, 이에는 캐시, 전문 검색 색인, 머신러닝 또는 분석 시스템 등이 포함됨.
- 파생 데이터를 유지할 때 상태 변경 순서와 내결함성이 중요하며, 이를 위해 안정적인 메시지 순서화와 내결함성이 있는 메시지 처리가 필요함.
- 최신 스트림 처리자는 대규모로 순서화와 신뢰성 보장을 제공하며, 애플리케이션 코드를 스트림 연산자로 실행할 수 있음.
- 이를 통해 데이터베이스에 내장된 파생 함수가 지원하지 않는 임의 처리가 가능하고, 데이터플로를 중심으로 대형 시스템을 구축할 수 있음.
스트림 처리자와 서비스
- 최근의 애플리케이션 개발 트렌드는 기능을 서비스로 분리하고, 이들 간 통신을 동기 네트워크 요청 (ex: REST API)을 통해 이루는 것임.
- 이런 서비스 지향 아키텍처의 장점은 조직적 확장성과 느슨한 연결을 통한 팀 간 협업 향상임.
- 스트림 연산자를 사용한 데이터플로 시스템 구성은 마이크로서비스 접근법과 많은 유사성을 가지지만, 통신 메커니즘이 크게 다름.
- 마이크로서비스는 동기식 요청/응답 상호작용을 사용하는 반면, 데이터플로 시스템은 단방향 비동기식 메시지 스트림을 사용함.
- 데이터플로 시스템은 높은 내결함성 및 성능을 제공함.
- 예를 들어, 특정 통화로 가격이 책정된 상품을 다른 통화로 구매하는 경우, 환율 변환에 대한 처리가 필요함.
- 이는 마이크로서비스 접근법과 데이터플로 접근법을 통해 다르게 처리될 수 있음.
- 마이크로서비스 접근법에서는 환율 서비스나 데이터베이스에 질의하여 현재 환율을 얻는 반면, 데이터플로 접근법에서는 환율 갱신 스트림을 미리 구독하고 환율이 변경될 때마다 로컬 데이터베이스에 기록함.
- 이 방식은 동기식 네트워크 요청을 로컬 데이터베이스 질의로 대체함으로써 성능 향상과 서비스 장애에 대한 높은 내성을 제공함.
- 구매 이벤트와 환율 갱신 이벤트 간의 스트림 조인은 시간 의존성이 있음.
- 구매 이벤트를 재처리할 때, 환율이 변경되어 구매 시점의 과거 환율을 얻어야 함.
- 이 시간 의존성은 환율 서비스에 질의를 하든 환율 갱신 스트림을 구독하든 다뤄야 함.
- 변경 스트림 구독은 필요할 때 현재 상태를 조회하는 것보다 스프레드시트의 연산 모델에 더 가까움.
- 데이터가 변경될 때, 해당 데이터에 의존하는 파생 데이터가 신속히 갱신됨.
- 이 방식은 시간 의존성 조인과 관련된 문제 등을 포함해 아직 해결되지 않은 문제들이 있지만, 데이터플로 아이디어를 사용해 애플리케이션을 구축하는 것은 매우 유망한 방향임.
댓글