Cube.js 디자인 결정
본문
첫 번째 Embedded Analytics 오픈 소스 프레임워크의 설계 결정
https://cube.dev/blog/design-decisions-for-the-first-embedded-analytics-open-source-framework/
지난 2 년 동안 커스텀화와 임베딩을 위해 특별히 개발된 분석 프레임워크인 Cube.js를 연구해 왔습니다.
데이터 엔지니어가 내부 데이터 인프라를 구축하는 데 사용할 수 있는 많은 훌륭한 도구가 있습니다.
그러나 제작, 고객 지향 애플리케이션 및 분석 기능을 이러한 애플리케이션에 임베드 해야 하는 소프트웨어 엔지니어에게는 도구가 부족합니다.
주요 요구 사항은 프론트 엔드에서 전체 UI를 사용자 정의 할 수 있도록 하면서 대규모 데이터 세트로 쉽게 확장 할 수 있도록 하는 것이었습니다.
또한 의존성이 없으며 특히 데이터 파이프 라인 작업의 복잡한 인프라를 배선 할 필요가 없습니다.
이미 페타 바이트 크기의 데이터 세트로 1 년 이상 여러 회사에서 생산되었습니다. Cube.js가 업무를 수행하고 있다고 확신하고 4 개월 전부터 더 많은 잠재 고객이 사용할 수 있도록 오픈 했습니다.
이 기사에서는 Cube.js의 아키텍처에 대한 자세한 설명과 왜 이렇게 설계했는지에 대해 설명하고자 합니다.
그것을 읽은 후, Cube.js를 자신의 분석 애플리케이션에 사용해 보시기 바랍니다.
아래 스키마는 Cube.js가 일반적으로 배포되어 기존 응용 프로그램 아키텍처에 포함되는 방법을 보여줍니다.
Cube.js 백엔드 마이크로 서비스는 데이터베이스 대기열, 데이터 스키마, 캐싱, 보안 및 API 게이트웨이를 관리하면서 하나 이상의 데이터베이스에 연결됩니다.
클라이언트는 백엔드에서 집계 된 데이터를 로드하고 처리 한 다음 원하는 시각화 라이브러리로 보냅니다.
아래에서는 백엔드와 클라이언트 모두에서 정확히 무슨 일이 발생했는지에 대해 자세히 설명 하겠지만 먼저 Cube.j를 디자인 할 때 우리가 내린 가장 중요한 결정을 강조하고 싶습니다.
Data Schema
ORM은 소프트웨어 개발 분야에서 매우 보편적이지만 분석에 있어서는 대개 수 많은 SQL 스크립트와 템플릿으로 끝납니다.
데이터 스키마의 기본 개념은 ORM의 모범 사례를 활용하여 분석 사용 사례에 적용하는 것입니다.
우리는 척도와 치수가 추상화 엔티티로서 다차원 분석이라는 좋은 아이디어를 얻었고 치수와 치수를 SQL 코드로 변환하는 ROLAP (Relational OLAP) 엔진을 사실상 만들었습니다.
데이터 스키마의 가장 큰 점은 완전히 동적 인 것입니다. Cube.js의 데이터 스키마는 XML/JSON과 같은 정적 인 것이 아니라 JavaScript 코드이므로 동적으로 생성 할 수 있습니다. 런타임 중에 측정 값 또는 차원 정의를 데이터베이스 또는 API를 통해 로드할 수도 있습니다.
API 클라이언트에 추상화되고 유연한 쿼리 언어를 제공하려면 스키마를 적절히 배치하는 것이 중요합니다. 아무도 API를 통해 SQL 코드 나 SQL 스 니펫 ID를 보내려고 하지 않으므로 결국 이러한 시스템의 모든 경우에 쿼리 언어가 개발됩니다. 이것이 바로 Cube.js가 OLAP Best Practices에 의해 뒷받침된 이유입니다.
In Database Pre-Aggregations
일반적인 라스트 마일 메모리 캐시가 있지만 사전 집계는 특히 동적 쿼리의 경우 성능면에서 큰 차이를 만듭니다. Cube.js는 창고에 재사용 가능한 집계 테이블을 생성 할 수 있으며 읽기가 매우 빠릅니다.
하나의 집계 테이블은 대개 여러 개의 쿼리를 제공합니다. 새로운 기본 데이터가 들어올 때 Cube.js는 또한 집계 테이블을 새로 고칩니다.
또한 Cube.js는 요청 된 측정 및 패턴의 패턴을 기반으로 필요한 집계 테이블을 자동으로 계산하고 구축 할 수 있습니다. 우리는 이를 위해 데이터 큐브 격자의 원리를 사용하며 향후 블로그 게시물에서 그 뒤에 있는 수학을 다룰 것입니다. 또한 집계 테이블을 별도의 창고에 저장할 수 있습니다. MySQL, 모든 원시 데이터가 BigQuery에 있을 수 있습니다. 이렇게 하면 1 초 미만의 반응을 얻을 수 있습니다. 디자인으로 인해 BigQuery가 포함 된 작은 데이터 세트에서도 가능하지 않습니다.
사전 집계는 스케일링에 필수적입니다. "ETL"에서 "T"로 생각할 수 있습니다. 그러나 변환은 Cube.js가 완벽하게 조율 한웨어 하우스 내부에서 발생합니다.
Visualizations Agnostic
이 기능은 "기능 자체가 기능이라고 말하면 안됩니다"라는 범주에 속합니다. 선하고 성숙한 시각화 라이브러리가 수없이 많기 때문에 새로운 기능을 개발하는 것이 아니라, 그들 모두. Cube.js는 아무 것도 렌더링 하지 않지만 백엔드에서 로드된 후 데이터를 후 처리하는 데 유용한 도우미 세트를 제공합니다. 피벗 작업 및 누락 된 날짜 기입 등의 작업이 포함됩니다. Cube.js 프런트 엔드 클라이언트의 구성 요소를 설명 할 때 나중에 자세히 설명하겠습니다.
이 게시물의 나머지 부분에서는 백엔드 및 프론트 엔드의 구성 요소를 다룰 것입니다.
Cube.js Backend
백엔드 자체는 Node.js 응용 프로그램입니다.이 응용 프로그램은 환경 변수를 통해 구성하거나 보다 복잡한 사용 사례를 위한 몇 가지 Javascript 코드를 작성하여 구성 할 수 있습니다. 또한 측정 값과 차원을 SQL에 매핑하는 방법을 설명하는 JavaScript 코드 인 데이터 스키마가 필요합니다. 스키마에는 캐싱, 보안 및 사전 집계 규칙도 포함됩니다. 백엔드는 대개 클러스터의 마이크로 서비스로 배포됩니다. 필요한 데이터베이스에 연결되어 있으며 외부에서 클라이언트에 직접 또는 클라이언트 용 프록시가 있는 경우 내부적으로 API를 제공합니다.
Cube.js는 4 가지 주요 구성 요소를 갖춘 모듈 식 프레임 워크로 설계되었습니다. 일반적으로 모두 함께 사용되지만 특정 사용 사례에서 필요한 모든 것을 사용할 수 있습니다. 아래에서는 백엔드의 각 구성 요소와 해당 구성 요소가 해결하는 문제점을 설명합니다.
Schema Compiler
스키마 컴파일러는 JavaScript 코드 인 데이터 스키마를 컴파일하고 이를 기반으로 들어오는 쿼리가 SQL 코드를 생성합니다. SQL 코드는 Query Orchestrator로 전송되어 데이터베이스에 대해 실행됩니다. 데이터 스키마를 사용하면 잘 정리되고 재사용 가능한 데이터 모델을 만들 수 있습니다. JavaScript이므로 모든 필수 정의를 동적으로 작성하고 공통 부분을 도우미로 추출 할 수 있으며 일반적으로 최상의 엔지니어링 방법을 적용하여 비즈니스 정의에 따라 데이터를 구성 할 수 있습니다.
스키마는 행 레벨 보안이 정의되는 장소이기도 합니다. 사용자 컨텍스트는 모든 요청과 함께 Cube.js에 전달되어 스키마 레벨로 전파 될 수 있습니다. 스키마에서 사용자 컨텍스트를 사용하여 특정 사용자에 대한 액세스를 특정 데이터로만 제한 할 수 있습니다.
큰 데이터 세트를 위해 널리 사용되는 Cube.js 기능인 사전 집계도 스키마에 정의되어 있습니다. 이 경우 Schema Compiler는 단일 쿼리가 아닌 종속 쿼리 목록을 생성하여 사전 집계를 작성한 다음 최종 쿼리를 생성하여 데이터를 가져옵니다.
Query Orchestrator
Query Orchestrator의 임무는 데이터베이스가 과부하 상태가 아니고 다단계 쿼리가 올바른 순서로 실행되고 새로 고쳐지는지 확인하는 것입니다. 이를 위해 사전 집계 및 데이터 쿼리에 대한 쿼리 실행 큐를 유지 관리합니다. 대기열은 멱등 원입니다. 즉, 여러 개의 동일한 쿼리가 들어 오면 하나만 데이터베이스에 대해 실행됩니다. 쿼리는 데이터베이스 드라이버에 의해 실행됩니다. 현재 Cube.js는 10 개 이상의 기본 데이터베이스 드라이버와 일반 JDBC 드라이버를 지원합니다.
사전 집계를 사용할 때 항상 그렇듯이 다단계 쿼리의 경우 쿼리 자체는 여러 사전 집계와 데이터를 가져 오기 위한 최종 쿼리로 구성됩니다. Orchestrator는 최종 쿼리 이전에 필요한 모든 집계 테이블이 최신 상태인지 확인합니다. 집계 테이블이 없거나 오래된 테이블 인 경우 집계 테이블을 만들거나 업데이트 할 쿼리를 예약합니다.
집계 테이블의 백그라운드 새로 고침은 비동기 프로세스로 추상화되며 독립 실행 형 응용 프로그램 또는 서버가 없는 모드에서 실행할 수 있습니다. 또한 선택적으로 백그라운드 처리를 다중 테넌트 클러스터로 추출 할 수도 있습니다.
API Gateway
API 게이트웨이는 쿼리를 실행하고 메타 데이터를 로드하며 스키마 컴파일러에서 생성 된 SQL을 검사하는 API 끝점을 정의합니다. 게이트웨이는 긴 폴링 멱등 원 API를 구현하여 조회 결과를 로드합니다. 이는 연결 문제에 대해 관대하게 만들고 요청 시간 제한 없이 응답을 보장합니다.
게이트웨이는 인증 및 권한 부여도 담당합니다. 기본적으로 Cube.js의 보안은 JWT 토큰으로 구현됩니다. 모든 요청은 데이터 스키마에 전달 될 보안 컨텍스트에 대한 정보를 선택적으로 포함하는 JWT 토큰으로 서명됩니다. 데이터베이스 또는 특정 마이크로 서비스에서 보안 컨텍스트를 로드하려는 경우 기본 보안 모델을 사용자 지정 미들웨어로 재정의 할 수 있습니다.
Server Core
Server Core는 위의 모든 구성 요소를 함께 연결하고 단일 구성 진입 점을 제공합니다.
Server Core는 기존 Node.js 응용 프로그램에 내장 할 수 있습니다. 독립 실행 형 응용 프로그램으로 Cube.js를 시작하려면 서버 패키지를 사용 해야 합니다. serverless 모드의 경우 serverless 패키지.
Cube.js Client
Cube.js 클라이언트는 Cube.js API 및 후 처리 쿼리 결과와 함께 작동하는 JavaScript 라이브러리입니다. 핵심 클라이언트는 바닐라 자바 스크립트 라이브러리로, 네이티브와 같은 도구를 사용하는 경우 브라우저 나 모바일 장치에서 실행할 수 있습니다. 또한 React, Angular 및 Vue.js 용 패키지를 제공하므로 Cube.js 클라이언트를 이러한 프레임 워크에 쉽게 통합 할 수 있습니다.
Cube.js 클라이언트는 Cube.js 백엔드에서 데이터를 로드하는 전송 계층을 추상화하고 로드 및 오류 상태도 처리합니다. 데이터가 로드되면 클라이언트는 데이터를 후 처리하는 데 필요한 일련의 도우미 메서드를 제공합니다. 클라이언트는 차트 또는 테이블에 데이터를 표시하기 위한 피벗 인터페이스를 제공합니다. 누락 된 날짜를 채우는 것과 같은 메타 데이터 조작 및 일부 유틸리티를 위한 메소드도 가지고 있습니다.
우리는 의도적으로 시각화 부분을 생략했습니다. 첫 번째 날부터 시각화를 제외한 모든 작업을 처리하는 프레임 워크를 구축했습니다. 그것은 최종 사용자를 위한 힘과 사용자 정의의 최상의 조합 인 것 같습니다.
Ecosystem
그것들은 Cube.js 백엔드와 프론트 엔드의 핵심 구성 요소였습니다. 그러나 프레임 워크를 중심으로 커뮤니티가 발전하면서 생태계가 어떻게 성장 하는지를 알게 되어 기쁩니다. 통합, 튜토리얼 및 예제의 생태계는 도구 자체 만큼이나 중요합니다. 놀라운 오픈 소스 커뮤니티에서 이미 데이터베이스 드라이버, 프론트 엔드 프레임 워크의 바인딩, 튜토리얼 및 코드 샘플을 통해 얻은 공헌에 대해 모두 감사드립니다.
Cube.js에 관심이 있고 기여하고 싶다면 Slack 커뮤니티에서 만나 뵙겠습니다. 일반적으로 Cube.js를 시작하고 공헌하기에 이상적인 곳입니다.
- 이전글브라우저 polyfill madness, Mozilla 및 Internet Explorer 19.07.29
- 다음글자바 스크립트에서 CSS 셀렉터 사용하기 19.07.29