KR20220011595A - 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 - Google Patents
템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 Download PDFInfo
- Publication number
- KR20220011595A KR20220011595A KR1020210095135A KR20210095135A KR20220011595A KR 20220011595 A KR20220011595 A KR 20220011595A KR 1020210095135 A KR1020210095135 A KR 1020210095135A KR 20210095135 A KR20210095135 A KR 20210095135A KR 20220011595 A KR20220011595 A KR 20220011595A
- Authority
- KR
- South Korea
- Prior art keywords
- data
- temporal
- time
- resource
- datasets
- Prior art date
Links
- 230000002123 temporal effect Effects 0.000 title claims abstract description 215
- 238000013481 data capture Methods 0.000 title claims abstract description 34
- 238000013079 data visualisation Methods 0.000 title claims abstract description 29
- 230000006870 function Effects 0.000 claims description 72
- 238000000034 method Methods 0.000 claims description 64
- 238000012545 processing Methods 0.000 claims description 62
- 230000002776 aggregation Effects 0.000 claims description 57
- 238000004220 aggregation Methods 0.000 claims description 57
- 230000003139 buffering effect Effects 0.000 claims description 7
- 238000001914 filtration Methods 0.000 claims description 6
- 238000011068 loading method Methods 0.000 claims description 6
- 230000001131 transforming effect Effects 0.000 claims description 4
- 239000003795 chemical substances by application Substances 0.000 abstract description 12
- 239000000872 buffer Substances 0.000 abstract description 4
- 241000533950 Leucojum Species 0.000 description 57
- 230000009466 transformation Effects 0.000 description 52
- 230000008569 process Effects 0.000 description 34
- 238000000844 transformation Methods 0.000 description 21
- 238000003860 storage Methods 0.000 description 20
- 230000014509 gene expression Effects 0.000 description 16
- 238000005457 optimization Methods 0.000 description 16
- 230000008859 change Effects 0.000 description 15
- 230000000875 corresponding effect Effects 0.000 description 13
- 238000013459 approach Methods 0.000 description 12
- 238000005192 partition Methods 0.000 description 11
- 238000013499 data model Methods 0.000 description 10
- 238000012856 packing Methods 0.000 description 10
- 238000011144 upstream manufacturing Methods 0.000 description 9
- 230000008901 benefit Effects 0.000 description 8
- 230000000694 effects Effects 0.000 description 7
- 238000005304 joining Methods 0.000 description 7
- 238000006243 chemical reaction Methods 0.000 description 6
- 230000003068 static effect Effects 0.000 description 6
- 238000004040 coloring Methods 0.000 description 5
- 239000002131 composite material Substances 0.000 description 5
- 238000013461 design Methods 0.000 description 5
- 230000010354 integration Effects 0.000 description 5
- 230000007246 mechanism Effects 0.000 description 5
- 230000003321 amplification Effects 0.000 description 4
- 230000002596 correlated effect Effects 0.000 description 4
- 238000010586 diagram Methods 0.000 description 4
- 238000005516 engineering process Methods 0.000 description 4
- 238000003199 nucleic acid amplification method Methods 0.000 description 4
- 238000013138 pruning Methods 0.000 description 4
- 238000000926 separation method Methods 0.000 description 4
- 230000001427 coherent effect Effects 0.000 description 3
- 230000006835 compression Effects 0.000 description 3
- 238000007906 compression Methods 0.000 description 3
- 238000010276 construction Methods 0.000 description 3
- 238000013480 data collection Methods 0.000 description 3
- 238000013500 data storage Methods 0.000 description 3
- 238000013501 data transformation Methods 0.000 description 3
- 230000002452 interceptive effect Effects 0.000 description 3
- 238000013507 mapping Methods 0.000 description 3
- 238000010606 normalization Methods 0.000 description 3
- 238000005070 sampling Methods 0.000 description 3
- 230000009471 action Effects 0.000 description 2
- 238000010923 batch production Methods 0.000 description 2
- 230000001143 conditioned effect Effects 0.000 description 2
- 230000001419 dependent effect Effects 0.000 description 2
- 230000009977 dual effect Effects 0.000 description 2
- 230000037406 food intake Effects 0.000 description 2
- 230000008450 motivation Effects 0.000 description 2
- 230000002085 persistent effect Effects 0.000 description 2
- 230000000750 progressive effect Effects 0.000 description 2
- 238000011084 recovery Methods 0.000 description 2
- 238000005096 rolling process Methods 0.000 description 2
- 238000007493 shaping process Methods 0.000 description 2
- 239000007787 solid Substances 0.000 description 2
- 238000000638 solvent extraction Methods 0.000 description 2
- 238000012546 transfer Methods 0.000 description 2
- 102000020897 Formins Human genes 0.000 description 1
- 108091022623 Formins Proteins 0.000 description 1
- XOJVVFBFDXDTEG-UHFFFAOYSA-N Norphytane Natural products CC(C)CCCC(C)CCCC(C)CCCC(C)C XOJVVFBFDXDTEG-UHFFFAOYSA-N 0.000 description 1
- 238000009825 accumulation Methods 0.000 description 1
- 230000002730 additional effect Effects 0.000 description 1
- 230000004931 aggregating effect Effects 0.000 description 1
- 238000004458 analytical method Methods 0.000 description 1
- 238000003491 array Methods 0.000 description 1
- 238000013473 artificial intelligence Methods 0.000 description 1
- 230000006399 behavior Effects 0.000 description 1
- 235000000332 black box Nutrition 0.000 description 1
- 238000004364 calculation method Methods 0.000 description 1
- 238000004891 communication Methods 0.000 description 1
- 150000001875 compounds Chemical class 0.000 description 1
- 230000006378 damage Effects 0.000 description 1
- 238000012517 data analytics Methods 0.000 description 1
- 238000005034 decoration Methods 0.000 description 1
- 238000009795 derivation Methods 0.000 description 1
- 229910003460 diamond Inorganic materials 0.000 description 1
- 239000010432 diamond Substances 0.000 description 1
- 238000009826 distribution Methods 0.000 description 1
- 238000011156 evaluation Methods 0.000 description 1
- 238000002474 experimental method Methods 0.000 description 1
- 239000000284 extract Substances 0.000 description 1
- 238000000605 extraction Methods 0.000 description 1
- 239000000796 flavoring agent Substances 0.000 description 1
- 235000019634 flavors Nutrition 0.000 description 1
- 238000007667 floating Methods 0.000 description 1
- 230000036541 health Effects 0.000 description 1
- 230000008676 import Effects 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 230000003993 interaction Effects 0.000 description 1
- 230000005923 long-lasting effect Effects 0.000 description 1
- 238000010801 machine learning Methods 0.000 description 1
- 238000012423 maintenance Methods 0.000 description 1
- 230000014759 maintenance of location Effects 0.000 description 1
- 238000007726 management method Methods 0.000 description 1
- 239000000463 material Substances 0.000 description 1
- 230000003340 mental effect Effects 0.000 description 1
- 238000012544 monitoring process Methods 0.000 description 1
- 238000004321 preservation Methods 0.000 description 1
- 230000001902 propagating effect Effects 0.000 description 1
- 238000005086 pumping Methods 0.000 description 1
- ZLIBICFPKPWGIZ-UHFFFAOYSA-N pyrimethanil Chemical compound CC1=CC(C)=NC(NC=2C=CC=CC=2)=N1 ZLIBICFPKPWGIZ-UHFFFAOYSA-N 0.000 description 1
- 238000007670 refining Methods 0.000 description 1
- 238000012857 repacking Methods 0.000 description 1
- 230000004044 response Effects 0.000 description 1
- 238000012163 sequencing technique Methods 0.000 description 1
- 238000012358 sourcing Methods 0.000 description 1
- 238000001228 spectrum Methods 0.000 description 1
- 238000013517 stratification Methods 0.000 description 1
- 230000001360 synchronised effect Effects 0.000 description 1
- 230000007474 system interaction Effects 0.000 description 1
- 230000009897 systematic effect Effects 0.000 description 1
- 230000036962 time dependent Effects 0.000 description 1
- 238000012800 visualization Methods 0.000 description 1
- XLYOFNOQVPJJNP-UHFFFAOYSA-N water Substances O XLYOFNOQVPJJNP-UHFFFAOYSA-N 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/21—Design, administration or maintenance of databases
- G06F16/211—Schema design and management
- G06F16/213—Schema design and management with details for schema evolution support
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/25—Integrating or interfacing systems involving database management systems
- G06F16/254—Extract, transform and load [ETL] procedures, e.g. ETL data flows in data warehouses
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/23—Updating
- G06F16/2308—Concurrency control
- G06F16/2315—Optimistic concurrency control
- G06F16/2322—Optimistic concurrency control using timestamps
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/245—Query processing
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/245—Query processing
- G06F16/2458—Special types of queries, e.g. statistical queries, fuzzy queries or distributed queries
- G06F16/2477—Temporal data queries
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/248—Presentation of query results
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/25—Integrating or interfacing systems involving database management systems
- G06F16/252—Integrating or interfacing systems involving database management systems between a Database Management System and a front-end application
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/25—Integrating or interfacing systems involving database management systems
- G06F16/258—Data format conversion from or to a database
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Databases & Information Systems (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Data Mining & Analysis (AREA)
- Computational Linguistics (AREA)
- Software Systems (AREA)
- Fuzzy Systems (AREA)
- Mathematical Physics (AREA)
- Probability & Statistics with Applications (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템이 개시된다. 예시적인 실시형태는: 수집 에이전트들을 사용하여 데이터를 캡처 및 포워딩하고; 캡처된 데이터를 데이터 웨어하우스로 버퍼링 및 로딩하고; 템포럴 대수 쿼리 언어에 의해 특정된 바와 같이 데이터를 변환하고; 템포럴 대수 쿼리 언어를 사용하여 변환된 데이터의 쿼리를 가능하게 하는 것으로서, 쿼리는 템포럴 데이터 관계들을 포함하는, 상기 쿼리를 가능하게 하고; 그리고 쿼리들의 결과들을 사용자 인터페이스를 통해 사용자에게 프리젠팅하도록 구성된다.
Description
우선권 특허 출원
본 정규 특허 출원은 2020년 7월 21일자로 출원된 미국 가특허 출원 제63/054,679호로부터 우선권을 얻는다. 이 현재의 정규 특허 출원은 참조된 특허 출원으로부터 우선권을 얻는다. 참조된 특허 출원의 전체 개시는 본 출원의 개시의 부분으로 간주되고 이로써 전부 본 명세서에 참조로 통합된다.
저작권 공고
본 특허 문서의 개시의 부분은 저작권 보호를 받는 자료를 포함한다. 저작권 소유자는, 누구든 본 특허 문서 또는 특허 개시를 미국 특허청의 특허 파일들 또는 기록들에 나타나 있는 대로 복제하는 것에는 반대하지 않지만, 그 외에는 어떤 것이라도 모든 저작권들을 보유한다. 다음의 공고는 본 명세서의 개시에 그리고 본 문서의 부분을 형성하는 도면들에 적용된다: Copyright 2019-2021, Observe Inc., All Rights Reserved.
기술 분야
본 특허 문헌은 일반적으로 데이터 프로세싱, 데이터 캡처, 데이터 통신 네트워크들, 및 보다 구체적으로, 그러나 제한 없이, 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템과 관계가 있다.
원래, 데이터는 어디에서든지 나온다. 이러한 데이터는 배치 (batch) 프로세스로부터 콘솔에 인쇄된 메시지들일 수도 있다. 이러한 데이터는 웹 애플리케이션 또는 데이터베이스 서버와 같은, 서버로부터 나오는 디스크 상의 로그 파일들일 수도 있다. 이러한 데이터는 일부 소형 사물 인터넷 (IoT) 센서 또는 디바이스에 의해, 작업 현장의 머신에 의해, 또는 백화점의 금전 등록기에 의해 발생된 이벤트들일 수도 있다. 데이터는 심지어는 이미 일부 다른 시스템에 의해 준비된, 데이터베이스 테이블의 어딘가에 남아 있을 수도 있다 (이것은, 예를 들어, 고객 프로파일 정보에 대해 일반적이다). 어떤 원본 데이터의 출처는, 후속 단계들에서 적절한 프로세싱이 이루어질 수 있도록, 데이터에 관한 메타데이터로서 캡처하는 것이 중요하다. 예로서, 데이터 캡처 당시 유효한 시간대는 나중에, 전세계적으로 분포된 기업에 걸쳐서 이벤트들을 상관시킬 때 중요할 수도 있다. 추가적으로, 데이터가 어떤 물리적 호스트 또는 머신 또는 컨테이너 또는 데이터베이스로부터 나오는지는, 데이터 내에서 아마 언급된 엔티티들과는 대조적으로, 중요한 메타데이터이다. 예를 들어, 웹 서버는 사용자 X 가 인터넷 프로토콜 (IP) Y 로부터 애플리케이션 영역 Z 에 로그인했다고 하는 로그 문 (statement) 을 내보낼 수도 있다. 로그 메시지는 엔티티들 (X, Y, 및 Z) 에 대한 참조 (reference) 들을 포함하지만, 웹 서버가 실제로 로그 문을 내보낸 엔티티는 데이터 자체 내에서 확인되지 않는, 원본에 관한 메타데이터이다. 추가적으로, 데이터의 각각의 아이템에 대한 타이밍 또는 타임스탬프 정보가 매우 중요할 수 있다. 예를 들어, 대부분의 데이터는 하나 이상의 타임스탬프들과 연관되거나 또는 그들을 할당받는다. 이러한 타임스탬프들은 데이터 또는 이벤트의 소스에 의해 주어진 시간과 연관된 "애플리케이션 시간" 을 나타낼 수 있다. 특정 데이터에 대한 타임스탬프들은 또한 이벤트 시간, 시스템 시간, 또는 데이터와의 시스템 상호작용과 연관된 다른 템포럴 데이터를 나타낼 수 있다. 데이터 아이템과 연관된 다른 템포럴 데이터가 또한 다양한 컨텍스트들에서 중요할 수 있다. 그러나 대부분의 경우들에서, 메타데이터 (템포럴 데이터를 포함함) 또는 데이터 그 자체 중 어느 하나가 원하는 정보를 제공하지 않거나 또는 메타데이터가 너무 방대해서 중요한 데이터 관계들이 순전히 데이터의 볼륨에 의해 모호해질 수 있다.
다양한 실시형태들은 첨부 도면들의 도들에 있어서 제한으로서가 아닌 예로서 예시된다.
도 1a, 도 1b, 및 도 2 는 본 명세서에서 설명된 바와 같은, 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 및 플랫폼의 예시적인 실시형태를 예시하는 프로세싱 플로우 다이어그램이다;
도 3 은 데이터 템포럴 피처들을 시각화하기 위해 템포럴 스플라이싱을 제공하는 예시적인 실시형태를 예시한다;
도 4a 는 템포럴 중복제거 (temporal deduplication) 의 예에 관련된 바와 같은 SnowflakeTM 의 샘플 쿼리 계획을 보여주는 예시적인 실시형태를 예시한다;
도 4b 및 도 4c 는 템포럴 중복제거의 예로서 SnowflakeTM 의 실행 계획을 보여주는 예시적인 실시형태를 예시한다;
도 5a 내지 도 5d 는 템포럴 groupby 의 예로서 SnowflakeTM 의 실행 계획을 보여주는 예시적인 실시형태를 예시한다;
도 6 은 분석 함수 (analytic function) 들에 관련된 바와 같은 SnowflakeTM 의 쿼리 계획들을 보여주는 예시적인 실시형태를 예시한다;
도 7 및 도 8 은 분석 함수들에 대한 대안들: ALL 또는 MIN/MAX 에 관련된 바와 같은 SnowflakeTM 의 샘플 쿼리 계획을 보여주는 예시적인 실시형태를 예시한다;
도 9a 내지 도 9e 는 백필링 (backfilling) 및 비동기 프로세싱에 관련된 바와 같은 템포럴 데이터세트들의 예를 예시한다;
도 10 은 엄격한 계층 (strict layer) 들에 관련된 바와 같은 예시적인 실시형태를 예시한다;
도 11 은 통합된 계층 (integrated layer) 들에 관련된 바와 같은 예시적인 실시형태를 예시한다;
도 12 내지 도 14 는 시간 윈도우들에 관련된 바와 같은 예를 예시한다; 그리고
도 15 는 본 명세서에서 설명된 바와 같은 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 및 플랫폼의 예시적인 실시형태를 예시하는 프로세싱 플로우 다이어그램이다.
도 1a, 도 1b, 및 도 2 는 본 명세서에서 설명된 바와 같은, 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 및 플랫폼의 예시적인 실시형태를 예시하는 프로세싱 플로우 다이어그램이다;
도 3 은 데이터 템포럴 피처들을 시각화하기 위해 템포럴 스플라이싱을 제공하는 예시적인 실시형태를 예시한다;
도 4a 는 템포럴 중복제거 (temporal deduplication) 의 예에 관련된 바와 같은 SnowflakeTM 의 샘플 쿼리 계획을 보여주는 예시적인 실시형태를 예시한다;
도 4b 및 도 4c 는 템포럴 중복제거의 예로서 SnowflakeTM 의 실행 계획을 보여주는 예시적인 실시형태를 예시한다;
도 5a 내지 도 5d 는 템포럴 groupby 의 예로서 SnowflakeTM 의 실행 계획을 보여주는 예시적인 실시형태를 예시한다;
도 6 은 분석 함수 (analytic function) 들에 관련된 바와 같은 SnowflakeTM 의 쿼리 계획들을 보여주는 예시적인 실시형태를 예시한다;
도 7 및 도 8 은 분석 함수들에 대한 대안들: ALL 또는 MIN/MAX 에 관련된 바와 같은 SnowflakeTM 의 샘플 쿼리 계획을 보여주는 예시적인 실시형태를 예시한다;
도 9a 내지 도 9e 는 백필링 (backfilling) 및 비동기 프로세싱에 관련된 바와 같은 템포럴 데이터세트들의 예를 예시한다;
도 10 은 엄격한 계층 (strict layer) 들에 관련된 바와 같은 예시적인 실시형태를 예시한다;
도 11 은 통합된 계층 (integrated layer) 들에 관련된 바와 같은 예시적인 실시형태를 예시한다;
도 12 내지 도 14 는 시간 윈도우들에 관련된 바와 같은 예를 예시한다; 그리고
도 15 는 본 명세서에서 설명된 바와 같은 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 및 플랫폼의 예시적인 실시형태를 예시하는 프로세싱 플로우 다이어그램이다.
다음의 설명에서, 설명의 목적들을 위해, 다수의 특정 상세들이 다양한 실시형태들의 철저한 이해를 제공하기 위하여 제시된다. 그러나, 다양한 실시형태들이 이러한 특정 상세들 없이 실시될 수도 있음이 당업자에게 명백할 것이다.
템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템이 개시된다. 본 명세서에서 개시된 다양한 예시적인 실시형태들에서, 시스템은 매우 다양한 소스들로부터 머신 데이터를 캡처 및 시각화하도록 구현될 수 있다. 특정 예시적인 실시형태에서, 플랫폼은, 플랫폼의 피처들을 예시하는 제 1 예로서, Kubernetes 컨테이너 오케스트레이션 시스템 및 AmazonTM Web Services (AWS)TM 클라우드 인프라구조 위에 배치된 정보 기술 (IT) 인프라구조를 관리하기 위한 태스크-특정 애플리케이션을 제공한다.
AmazonTM Web Services (AWS)TM 은 포괄적이고 광범위하게 채택된 클라우드 플랫폼이어서, 전세계 데이터 센터들로부터 많은 완전한 기능을 갖춘 (fully featured) 서비스들을 제공한다. 이러한 서비스들은 컴퓨팅, 스토리지, 및 데이터베이스들과 같은 인프라구조 기술들; 및 머신 학습 및 인공 지능, 데이터 레이크들 및 분석들, 및 사물 인터넷 (IoT) 과 같은 다른 서비스들을 포함한다.
KubernetesTM (K8s) 은 컨테이너화된 애플리케이션들의 배치, 스케일링, 및 관리를 자동화하기 위한 오픈-소스 시스템이다. KubernetesTM Ingress (인그레스) 는, 사용자가 클러스터에서 실행되는 KubernetesTM 서비스들에의 외부 또는 내부 HTTP(S) 액세스를 관리하도록 허용하는 애플리케이션 프로그래밍 인터페이스 (API) 리소스이다. 예를 들어, AmazonTM ELB (Elastic Load Balancing) ALB (Application Load Balancer) 는 한 지역에서, AmazonTM EC2 인스턴스들과 같은 다중 타겟들에 걸쳐서 애플리케이션 계층 (계층 7) 에서 인입 트래픽을 로드 밸런싱하는 인기 있는 AWS 서비스이다. ELB/ALB 는 호스트 또는 경로 기반 라우팅, TLS (Transport Layer Security) 종료, WebSocket들, HTTP/2, AWS WAF (Web Application Firewall) 통합, 통합된 액세스 로그들, 및 건강 체크들을 포함한 다중 피처들을 지원한다. KubernetesTM kubelet 은 각각의 노드에서 실행되는 프라이머리 "노드 에이전트" 이다.
오픈 소스 AWS ALB Ingress 제어기는, Kubernetes 사용자가 클러스터에서 Ingress 리소스를 선언할 때마다 ALB 및 필요한 지원 AWS 리소스들의 생성을 트리거링한다. Ingress 리소스는 ALB 를 사용하여 HTTP(S) 트래픽을 클러스터 내의 상이한 엔드포인트들로 라우팅한다. AWS ALB Ingress 제어기는 AmazonTM Elastic KubernetesTM Service (Amazon EKS) 를 포함한 임의의 KubernetesTM 클러스터에서 작동한다.
AmazonTM Simple Storage Service 또는 Amazon S3 은 웹 서비스 인터페이스를 통한 객체 스토리지를 제공하는 AmazonTM Web Services (AWS) 에 의해 제공되는 서비스이다. Amazon S3 은 Amazon.com 이 그의 글로벌 e-커머스 네트워크를 실행하기 위해 사용하는 것과 동일한 스케일가능한 스토리지 인프라구조를 사용한다. Amazon S3 은 인터넷 애플리케이션들에 대한 스토리지, 백업 및 복구, 재해 복구, 데이터 아카이브들, 분석들을 위한 데이터 레이크들, 및 하이브리드 클라우드 스토리지와 같은 사용들을 허용하는 임의의 타입의 객체를 저장하도록 채용될 수 있다. S3 Proxy 는, 개발자들이 웹 서버를 실행시킬 필요 없이 그들의 웹사이트들을 호스팅하도록 허용하는 S3 에서 이용가능한 정적 웹 사이트 호스팅 피처이다.
ApacheTM Kafka (카프카) 는 Scala and JavaTM 으로 기입된, Apache Software Foundation™ 에 의해 개발된 오픈-소스 스트림-프로세싱 소프트웨어 플랫폼이다. 그 솔루션은 실시간 데이터 피드들을 핸들링하기 위한 단일화된, 고-스루풋, 저-레이턴시 플랫폼을 제공하는 것을 목표로 한다. Kafka 는 Kafka Connect 를 통해 (데이터 임포트/엑스포트를 위한) 외부 시스템들에 연결할 수 있고 Java 스트림 프로세싱 라이브러리인 Kafka Streams 를 제공한다. Kafka 는, 효율성을 위해 최적화되는 바이너리 TCP-기반 프로토콜을 사용하고 네트워크 라운드트립의 오버헤드를 감소시키기 위해 메시지들을 자연스럽게 그룹화하는 "메시지 세트" 추상화 (abstraction) 에 의존한다. 이것은 더 큰 네트워크 패킷들, 더 큰 순차적 디스크 동작들, 인접한 메모리 블록들 등으로 이어질 수 있으며, 이는 Kafka 가 버스티 스트림의 랜덤 메시지 기입들을 선형 기입들로 바꾸도록 허용한다.
SnowflakeTM 은, 일반적으로 "데이터 웨어하우스" 라 불리는, 클라우드-기반 데이터 스토리지 및 분석 서비스를 제공한다. 데이터 웨어하우스는 기업 사용자들이 클라우드-기반 하드웨어 및 소프트웨어를 사용하여 데이터를 저장 및 분석하도록 허용한다. Snowflake 는 AmazonTM S3 에서 실행할 수 있다. SnowflakeTM Data Exchange 는 고객들이 데이터를 발견, 교환, 및 안전하게 공유하도록 허용한다. 본 명세서에서 개시된 예시적인 실시형태들은 SnowflakeTM 의 사용을 포함하지만, 다른 실시형태들이 OracleTM, DB/2, 또는 Hadoop/HIVETM 과 같은 다른 관계형 데이터베이스 또는 데이터 웨어하우스 기술들에 대해 본 명세서에서 개시된 기법들을 고려하여 유사하게 구현될 수 있다.
도 1a, 도 1b, 및 도 2 는 본 명세서에서 설명된 바와 같은 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 및 플랫폼의 예시적인 실시형태를 예시하는 프로세싱 플로우 다이어그램이다. 도 1a, 도 1b, 및 도 2 를 참조하면, 예시적인 실시형태의 데이터 프로세싱 모델 및 플랫폼은 이하에 더 상세히 예시 및 설명된다.
예시적인 실시형태의 플랫폼은, 엔티티들 간의 관계, 및 그러한 관계들의 시간의 경과에 따른 진화에 특별한 관심을 기울여, 데이터를 캡처, 프로세싱, 및 프리젠팅하기 위한 많은 어포던스 (affordance) 들을 포함한다. 예시적인 실시형태에서, 그 플랫폼에 의해 제공된 피처들 및 데이터 프로세싱 동작들은 다음을 포함한다: 데이터 출처 (Data Origin), 데이터 캡처 및 포워딩, 데이터 수집, 데이터 버퍼링, 데이터 로딩, 데이터 변환, 데이터 스토리지, 데이터 쿼리 (Data Querying), 및 데이터 프리젠테이션. 이러한 피처들 및 데이터 프로세싱 동작들의 각각은 이하에 더 상세히 설명된다.
데이터 출처
데이터는 다양한 소스들에서 비롯될 수 있다. 이러한 소스들은 배치 프로세스로부터 콘솔에 인쇄된 메시지들을 포함할 수도 있다. 이러한 데이터는 웹, 애플리케이션, 또는 데이터베이스 서버와 같은 서버로부터 나오는 디스크 상의 로그 파일들일 수도 있다. 이들은 일부 소형 사물 인터넷 센서 또는 디바이스에 의해, 또는 작업 현장의 머신에 의해, 또는 백화점의 금전 등록기에 의해 발생된 이벤트들일 수도 있다. 데이터는 심지어는 이미 일부 다른 시스템에 의해 준비된, 데이터베이스 테이블의 어딘가에 남아 있을 수도 있다 (이것은, 예를 들어, 고객 프로파일 정보에 대해 일반적이다). 데이터의 출처 또는 기원은, 후속 단계들에서 적절한 프로세싱이 이루어질 수 있도록, 데이터에 관한 메타데이터로서 캡처하는 것이 중요하다. 예로서, 데이터 캡처 당시 유효한 시간대는 나중에, 전세계적으로 분포된 기업에 걸쳐서 이벤트들을 상관시킬 때 중요할 수도 있다. 추가적으로, 데이터가 어떤 물리적 호스트 또는 머신 또는 컨테이너 또는 데이터베이스로부터 나오는지는, 데이터 내에서 아마 언급된 엔티티들과는 대조적으로, 중요한 메타데이터이다. 예를 들어, 웹 서버는 사용자 X 가 IP Y 로부터 애플리케이션 영역 Z 에 로그인했다고 하는 로그 문 (statement) 을 내보낼 수도 있다. 로그 메시지는 엔티티들 (X, Y, 및 Z) 에 대한 참조들을 포함하지만, 웹 서버가 실제로 로그 문을 내보낸 엔티티는 데이터 자체 내에서 확인되지 않는, 원본에 관한 메타데이터이다. 예시적인 실시형태들은 이 메타데이터를 생성 및/또는 유지하여, 기원 및 타이밍 메타데이터가 후에 예시적인 실시형태의 플랫폼에 의해 수행된 피처들 및 데이터 프로세싱 동작들에서 사용될 수 있도록 한다. 본 명세서에서 개시된 플랫폼은 데이터가 어떻게 생성되는지에 관하여 불가지론적이다. 예를 들어, 고객이 플랫폼에 대한 데이터를 생성하기 위해 사용해야 하는 고객 애플리케이션 프로그래밍 인터페이스 (API) 에 대한 요건은 없다. 대신에, 예시적인 실시형태의 플랫폼은 이미 이용가능한 모든 수단을 통해 데이터를 캡처한다. 고객이 풍부한 데이터 생성 API (이를 테면 OpenTracingTM 또는 PrometheusTM 또는 로깅 풀 (logging full) JSONTM 인코딩된 객체들) 를 사용하길 원한다면, 플랫폼은, 무엇이든지 그 고객에 대해 가장 잘 작동하는 데이터 메커니즘의 사용을 가능하게 한다.
데이터 캡처 및 포워딩
예시적인 실시형태의 플랫폼에서, 데이터는 "수집 에이전트들" 로 알려진 특수 수집 서비스들을 사용하여, 또는 데이터 생산자들이 수집 서비스들에 직접 지시하는 것에 의해 캡처된다. 고객은 "filebeat" 또는 "fluent-bit" 와 같은 산업 표준 에이전트들을 사용하여 로그 파일들 또는 다른 데이터 입력들을 캡처할 수 있고, 고객은 또한 데이터를 캡처하기 위해 수집 에이전트의 하나 이상의 인스턴스들을 호스팅하도록 선택할 수 있다. 수집 에이전트는, 그 에이전트가 PrometheusTM 엔드포인트들을 쿼리하고 그 결과들을 예시적인 실시형태의 플랫폼으로 푸시할 수 있기 때문에, PrometheusTM 을 사용하는 시스템들에 특히 유용하다. 데이터베이스 또는 데이터 웨어하우스에 이미 저장된 데이터는, 웨어하우스가 일반적으로 SnowflakeTM 데이터 공유 또는 그러한 데이터에 액세스하기 위한 다른 메커니즘을 통해 가시적이라고 가정하여, 에이전트가 필요하지 않다. 수집 에이전트는 또한 그 에이전트가 실행중인 장소 및 그 에이전트가 데이터를 캡처중인 장소에 관한 메타데이터를 추가할 수 있다.
데이터 수집
예시적인 실시형태의 플랫폼은 클라우드에서 수집 (ingestion) 엔드포인트들의 세트를 실행할 수 있다. SnowflakeTM 데이터 공유를 통해 들어오지 않는 데이터의 경우, 이것은 고객이 데이터를 핸드오프하는 목적지이고, 데이터는 더 이상 고객에 의해 직접 수정될 수 없다. 이때에, 어느 등록된 고객이 데이터를 제공했는지, 그리고 어느 고객-정의된 통합 명칭 (integration name) 을 통해 데이터가 수신되었는지와 같은 메타데이터가 데이터에 메타데이터로서 첨부된다. 서비스 인증이 또한 이때에 수행될 수 있다. 적절한 고객-특정 크리덴셜들에 의해 수반되지 않는 데이터는 시스템에 수락되지 않는다.
데이터 버퍼링
고객 데이터 생성이 일순간에 몰릴 수도 있다. 이것은 새로운 시스템들이 온보딩되고, 이력 데이터가 캡처될 때 특히 그렇다. 추가적으로, 예시적인 실시형태의 플랫폼은 업계 최고의 가동시간 (industry-leading uptime) 을 유지하기 위해 작동하지만, 플랫폼 또는 의존적 SnowflakeTM 데이터 프로세싱 측에서의 아웃티지 (outage) 가능성이 존재한다. 고객들에 의해 제공된 데이터를 거부해야 하는 것을 회피하기 위해, 예시적인 실시형태의 플랫폼에 대해 수집된 모든 데이터는, 하루보다 많은 날의 데이터 수집에 충분한 저장 용량으로, 버퍼링 스테이지를 거친다. 정상 상황들 하에서, 이 버퍼에서의 큐잉 레이턴시는 무시해도 될 정도이며; 그러나, 수집 스파이크들 또는 템포럴 용량 아웃티지 동안, 이 버퍼는 일단 수락되면 데이터가 결국 프로세싱될 것을 확실하게 한다. 예시적인 실시형태에서, Kafka 는 버퍼링이 버스티 데이터를 핸들링하게 하는데 사용될 수 있다.
데이터 로딩
데이터는 버퍼로부터 풀링되고 로더로 알려진 프로세스를 통해 SnowflakeTM 데이터 웨어하우스로 로딩된다. 이 로더의 기능은 개개의 고객들에 대해 도달하는 데이터를 고객별 로드 요청들로 대조할 뿐만 아니라 반-구조화된 SQL 프로세싱에 적합한 모드로 데이터 및 메타데이터를 포매팅 및 포워딩하는 것이다. 다른 예시적인 실시형태에서, 데이터 로딩 프로세스는 로더 및 별도의 인코더를 가질 수 있다. 이 실시형태에서, 데이터는 인코더에 의해 보여지고 압축되고, 로더는, 실제로는 그 스스로 데이터를 프로세싱하지 않고, 인코더에 의해 출력된 바와 같은 데이터를 로딩하도록 데이터 웨어하우스에 지시하는 것을 처리할 뿐이다.
상기 설명된 바와 같은 예시적인 실시형태의 플랫폼의 모든 데이터 프로세싱 스테이지들은 고객이 처음에 제공한 "데이터" 와, 그 데이터에 입각하여 캡처된 "메타데이터" 간의 분리를 분명히 유지한다. 데이터는 가능한 한 본래 그대로 제 1 영구 데이터 스토어로 로딩되기 때문에, 고객은, 데이터를 프로세싱하는 방법에 관한 그들의 생각을 바꾸고, 초기 데이터 스토어로 돌아가 새로운 프로세싱 규칙들을 적용하는 것이 항상 가능하다. 이를 수정되지 않은 원본 데이터 "증거 (evidence)" 라고 한다.
데이터 변환
일단 증거 데이터가 베이스 계층 ("옵저베이션 테이블" 또는 "원시 파이어호스" 라 부른다) 으로 로딩되면, 데이터를, 관계들을 갖는 완전 작동 (well-behaved) 데이터 엔티티들로 리파이닝 및 셰이핑하는 프로세스가 시작된다. 예시적인 실시형태의 플랫폼으로 시작할 때, 고객은 예를 들어 AWS 인프라구조 또는 KubernetesTM 클러스터들에 대해, 하나 이상의 사전-설치된 변환 구성들을 얻을 것이며; 그러나, 플랫폼은 고객들이 이러한 초기 구성들을 수정하고, 그들을 추가 도출된 구성들로 확장하고, 그리고 맨 처음부터 새로운 기본 구성들을 생성하도록 허용한다.
변환은, 데이터세트들이 선택, 필터링, 집계, 상관, 및 추가적으로 프로세싱되어 원시 옵저베이션 테이블에서 매우 유용하고 유익한 뷰들 또는 프로세싱된 데이터 옵저베이션들이 생성되는, 리파인먼트의 연속적인 단계들로 보여진다. 예를 들어, 규칙들의 세트는 컨테이너 생성, 수명, 및 종료를 특정하고, 그 로그 이벤트들에서 컨테이너 식별자들 (ID), 클러스터 ID, 및 다른 관련 필드들을 추출하는 KubernetesTM kubelet 으로부터 데이터 옵저베이션들을 선택하고, "컨테이너 이벤트들" 이라 불리는 데이터세트를 생성할 수도 있다. 추가 도출된 변환은 이러한 컨테이너 이벤트들을 가져오고, 그 이벤트들에서 리소스 키들 (이 경우에는, 클러스터 ID + 클러스터-특정 컨테이너 ID) 을 식별하고 시스템에, 이 업데이트들의 세트에서 컨테이너들의 이력 인벤토리 및 시간의 경과에 따른 그들의 상태를 구축시킬 수도 있다. 그 이력 컨테이너들은 그 후 그들 중 우연히 동일한 종류의 식별자를 갖는 다른 프로세싱 스트림들에 이용가능하므로, 플랫폼은 "컨테이너들에서 실행되는 서비스들" 을 제공할 수 있다.
예시적인 실시형태의 플랫폼의 대부분은 모든 필요한 데이터 및 메타데이터를 변환 단계에 이용가능하게 만들고, 사전-구성된, 및 사용자-구성된 데이터세트들 양자 모두에 대해 변환 단계를 효율적으로 구현하는데 초점을 맞춘다. 이 영역에서 행해진 결정들은 인입 데이터를 얼마나 자주 사전-프로세싱할지부터, 요구에 의해서만 데이터를 프로세싱할지 또는 추가 프로세싱 없이 쿼리들에 즉시 액세스가능하게 만들기 위해 변환 결과를 구체화할지 여부까지 무엇이든 포함한다.
변환들은 OPAL (Observe Processing and Analytics Language) 쿼리 언어라 불리는 우리가 생성한 템포럴 대수 쿼리 언어의 문들을 사용하여 설명된다. OPAL 의 구조 및 신택스는 이하에 상세히 설명된다. 이러한 변환들은 또한 해당 변환들에 대해 정의되는 환경에서 실행된다. 예를 들어, 변환이 4 개의 상이한 데이터세트들을 조인하면, 변환은 그 데이터세트들을 생성하는 변환들이 이미 완료된 후에 실행된다. 이것은 작은 배치들의 로우들의 끝이 없는 시퀀스로서 스트림 프로세싱을 처리하도록 선택함으로써 행해진 구현 결정이며, 이는 프로세싱을 한번에 기록하는 스트림-기반 시스템보다 더 효율적으로 만든다.
데이터 스토리지
데이터세트가 정의되면, 그리고 시스템이 (단지 변환 규칙들을 기억하고 그들을 쿼리가 실행될 때 요구에 따라 적용하는 것이 아니라) 그 변환을 물리적으로 구체화하도록 지시되면, 데이터세트는 SnowflakeTM 데이터 웨어하우스에서 하나 이상의 테이블들로 구체화된다. 테이블들은 양자 모두 속성들에 걸쳐서, 시간에 걸쳐서, 그리고 기능 영역들에 걸쳐서 파티셔닝될 수도 있다. 메트릭들과 같은, 리소스의 자주 변경되는 속성들은 호스트의 지정된 이름 또는 중앙 프로세싱 유닛 (CPU) 타입과 같은, 거의 변경되지 않는 속성들과 별도로 저장될 수도 있다. 데이터 세트들은 근본적인 SnowflakeTM 데이터베이스에서 테이블별 사이즈의 특정 내장 볼륨 한계를 초과함 없이 더 큰 데이터 세트들을 허용하기 위해 시간 단위로 파티셔닝될 수도 있다.
사용자에게는, 스토리지 서브시스템에 의해 선택된 특정 물리적 데이터 표현이 가시적이지 않은데, 데이터세트들은 그것들 스스로를 프리젠팅하고 데이터세트 스키마 및 메타데이터에서의 그들의 정의들에 따라 거동하기 때문이다. 그러나, 데이터세트의 물리적 표현의 정확한 선택은 효율성에 상당한 영향을 미친다.
데이터 쿼리
사용자가 옵저브중인 시스템의 일부 상태를 쿼리하길 원하면, OPAL (Observe Processing and Analytics Language) 쿼리 언어를 사용하여 기존 데이터세트들 위에 쿼리가 형성된다. 이 쿼리는 사용자 인터페이스에서 쉽게 프리젠팅되도록 추가적으로 컨디셔닝된다. 예를 들어, 변환으로 실행되는 OPAL 문은 모든 매칭 데이터를 무조건적으로 프로세싱할 것인 반면, 사용자 인터페이스 (UI) 는, 사용자가 모든 이용가능한 결과들 전체를 스크롤할 것으로 예상되지 않을 것이기 때문에, 프리젠팅된 로우들의 수를 약 1,000 개의 로우들로 제한할 수도 있다. 대신에, 사용자는 그들이 관심 있는 결과들을 찾기 위해 쿼리를 추가로 집계 및 필터링할 것으로 예상될 것이다.
사용자 인터페이스에서 공식화된 쿼리들은 일반적으로 OPAL 문들의 직접 사용자-입력으로부터 나오지 않고, 대신에 사용자가 사용자 인터페이스에서, "관련 데이터세트에 대한 링크 따라가기" 및 "상위 10 개 리스트의 값들만 보여주기" 와 같은 어포던스들을 사용하거나, 또는 특정 세트의 엔티티들 또는 시간 범위에 초점을 맞추기 위해 클릭하는 것에 의해 구축된다. 쿼리 언어의 다른 사용은 데이터세트들 및 메타데이터를 브라우징하기 위해 생성된 사용자 인터페이스이다.
데이터 프리젠테이션
대화형 데이터 탐색은 원시 프로세싱 쿼리가 제공할 수 있는 것보다 더 컨디셔닝된 데이터로부터 이익을 얻는다. 따라서, 데이터 프리젠테이션은 리소스 상태들을 "롤업" (예를 들어, 리소스 인스턴스 당 하나의 로우를 반환함, 여기서 시간의 경과에 따른 그 리소스의 모든 상태들은 단일 컬럼에 병합됨), 및 키 컬럼들을 "링크" (예를 들어, 외래 키 관계를 선언하는데 사용되는 특정 키 값 대신에, 타겟 엔티티의 이름을 보여줌) 와 같은 어포던스들을 포함한다.
템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템의 다양한 예시적인 실시형태들에 대한 추가적인 상세들
기본 용어 및 정의들
템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템의 예시적인 실시형태들은 매우 다양한 소스들로부터 머신 데이터를 캡처 및 시각화하도록 구현될 수 있다. 예시적인 구현은 특히 데이터의 템포럴 차원의 시각화를 용이하게 하는 기능 및 동작들에 초점을 맞추고 있다. 템포럴 차원에 초점을 맞추면, 기본적인 대수 구축 블록들을, 템포럴 엔티티 모델링과 구별해야 한다는 것이 분명해진다. 따라서, 다음의 용어는 본 명세서에서 제공된 개시를 명확하게 하는데 사용될 수 있다.
이러한 정의들이 주어지면, "리소스" (엔티티 모델 구성) 를 "인터벌 시간 테이블" (템포럴 관계형 대수 구축 블록) 과 구별하는 것이 중요하다. 일부 경우들에서, 단어들 "리소스" 또는 "이벤트" 는 근본적인 테이블 타입들이 사용되어야 하는 곳에 사용된다.
정규 형태들
마치 관계형 대수가 정규 형태들을 갖는 것처럼, 템포럴 대수는 정규 형태들이 필요하고, 엔티티 모델은 정규 형태들이 필요하다.
위에 "테이블" 이라고 쓰여 있는 곳에서는, 사용자가 알 수 있는 바와 같이 논리적 화합하는 데이터세트에 대해 이야기하며; 그 구현은 시간 유효성 인터벌 필드들을 갖는 기본 관계형 테이블을 사용할 수도 있거나, 또는 제 6 정규 형태 원주형 테이블 포맷을 사용할 수도 있거나, 또는 시간-기반 파티셔닝된 테이블들, 또는 그 구현에서 일부 다른 스토리지 포맷을 사용할 수도 있음에 유의한다. 레귤러 관계형 테이블과 의미 있는 "포인트 정규 형태" 구별이 없을 수도 있다. 이름 정규 형태는 데이터 테이블, 이벤트 정규 형태, 또는 리소스 정규 형태인 데이터세트에 대한 약칭으로서 사용된다.
필연적인 결과 (corollary) 들
테이블에 대한 프라이머리 키 세트가 빈 세트이면, 그 테이블은 "싱글톤" 을 구성한다. 인터벌 테이블들의 경우, "싱글톤" 해석은 테이블이 어떠한 오버랩하는 인터벌들도 가져서는 안됨을 의미한다. 리소스 테이블들의 경우, "싱글톤" 해석은 테이블 자체가 "리소스" 임을 의미한다.
데이터 모델
예시적인 실시형태는 템포럴-관계형 데이터 모델에 기초한다. "레귤러" 관계형 데이터베이스는 세계의 최근 상태를 저장 및 추론하도록 설계된다. 그에 반해서, 예시적인 실시형태는 세계의 도출된 상태 및 이벤트들의 풀 히스토리를 유지하고, 그 히스토리에 대한 쿼리들을 쉽게 공식화하게 한다. 이를 위해, 예시적인 실시형태는 일급 시티즌 (first-class citizen) 으로서 시간을 취급하는 템포럴-관계형 대수 및 타입 시스템을 특징으로 한다.
템포럴 테이블들
예시적인 실시형태의 기본적인 추상화는 템포럴 테이블이다. 템포럴 테이블은 예시적인 실시형태에 의한 특별 취급을 향유하는 하나 이상의 타임스탬프 컬럼들을 갖는 관계형 테이블이다. 예시적인 실시형태는 2 개의 타입들의 템포럴 테이블들을 구별한다:
포인트 테이블들
포인트 테이블은 단일, 지정된 타임스탬프 컬럼을 갖는 관계형 테이블이다. 그 타임스탬프 컬럼에 의해, 각각의 로우는 그와 연관된 어느 시점을 갖는다. 타임스탬프는 테이블의 모든 로우에 대해 상이할 수도 있거나, 또는 모든 로우에 대해 동일한 타임스탬프일 수도 있다 (그 경우에 전체 테이블은 시점을 설명하는 것으로서 고려될 수도 있고, 타임스탬프 컬럼은 물리적 표현에서 생략될 수도 있다).
인터벌 테이블들
인터벌 테이블들은 또한 문헌에서 "시변 관계들 (time-varying relations; TVR)" 또는 단순히 "템포럴 관계들 (temporal relations)" 이라 불린다. 그들을, 대수적으로 및 의미론적으로 매우 상이한 포인트 테이블들과 더 잘 구별하기 위해 용어 "인터벌 테이블들" 을 사용한다. 템포럴 테이블의 규범적 표현은 2 개의 추가적인 타임스탬프 컬럼들: valid_from, valid_to 을 갖는 관계형 테이블이다. 2 개의 타임스탬프들은 그 하한에서 클로즈되고 그 상한에서 오픈되는 인터벌을 형성한다. 왼쪽-클로즈, 오른쪽-오픈 설계 선택은 주로 SQL:2011 과의 호환성을 위해 이루어졌다. 템포럴 테이블의 각각의 로우는 시간 범위 valid_from, valid_to 에 대해 데이터베이스에 "존재하" 도록 정의된다. 그 시간 범위는 통상적으로 템포럴 데이터베이스 문헌에서 로우의 유효 시간이라 불린다. 그것은 또한 SQL:2011 에서 애플리케이션 시간이라 불린다. 개개의 로우들의 유효 시간에 의해, 인터벌 테이블은 특정 시점 (예: 현재로서는 클러스터의 노드들의 세트) 에서의 세계 (의 일부 양태) 의 상태 뿐만 아니라 시간의 경과에 따른 세계 (의 일부 양태) 의 완전한 히스토리를 반영한다. SQL 을 사용하여 (애플리케이션) 시간 t 의 특정 포인트에서 테이블의 스냅샷을 컴퓨팅하기 위해, 단순히 모든 로우들 WHERE t >= valid_from AND t < valid_to 을 선택한다. 시간 범위들은 오픈될 수도 있다. 오픈 시간 범위는 대응하는 바운드를 무한대로 설정함으로써 표현되며, 이는 SQL 에서 NULL 을 사용하여 표현될 수 있다. 시간 t 로부터 무한대까지 존재하는 로우는 valid_from = t 및 valid_to = NULL 을 가질 것이다. 시간에 독립적으로 존재하는 로우는 단순히 valid_from = NULL 및 valid_to = NULL 을 갖는다. 시간-불변 테이블 (즉, 레귤러 테이블) 은 따라서 모든 타임스탬프들이 NULL 인 템포럴 테이블의 특수 경우로 보여질 수 있다. 구현 노트: 오픈 시간 범위들을 수반하는 선택 술어 (predictate) 들은 그에 따라 재공식화되어야 한다; 예를 들어, WHERE t >= valid_from AND t < valid_to 는 SQL 에서 WHERE (t >= valid_from OR valid_from IS NULL) AND (t < valid_to OR valid_to IS NULL) 이 될 것이다. 구현들은 오픈 범위 시맨틱들이 보존되는 한은, 성능 이익을 제공하는 NULL 대신에 그들의 물리적 표현에서 일부 최소 또는 최대 정수를 사용하도록 선택할 수도 있다.
데이터세트들
예시적인 실시형태의 사용자들은 현재 템포럴 테이블들과 상호작용하지 않고 데이터세트들과 상호작용한다 (심지어 용어 "템포럴 테이블" 을 사용자들에게 절대 노출시키지 않도록 선택할 수도 있다). 데이터세트들은 리소스들 또는 이벤트들 중 어느 하나이고, 이는 각각 인터벌 테이블들 및 포인트 테이블들에 대응한다.
리소스들
리소스는 2 가지 방식들로 이해될 수 있다:
1. 인터벌 테이블 (프라이머리 키 및 다른 메타데이터를 가짐)
2. (포인트 테이블들과 같은) 이벤트들로부터 그 인터벌 테이블을 도출하는 변환들의 정의
2 개의 표현들은 서로의 듀얼 (duals) 이다. 첫번째는 세계의 "템포럴 데이터베이스" 뷰이다. 두번째는 세계의 "스트림 프로세싱" 뷰이다. 쿼리들을 이슈할 때, 사용자들은 첫번째 표현과 상호작용한다. 변환들을 관리할 때, 그들은 두번째 표현과 상호작용한다. 첫번째 표현인 템포럴 테이블에 초점을 맞춰보자. 각각의 리소스는 단일, 템포럴 테이블인 규범적 표현을 갖는다. 그 템포럴 테이블은 프라이머리 키를 갖고 다른 리소스들, 즉 그들의 템포럴 테이블들에 대한 외래 키들을 가질 수도 있다. 템포럴 테이블의 각각의 로우는 타임스탬프들의 valid_from, valid_to 쌍을 통해 표현된, 애플리케이션 시간의 일부 인터벌에 대한 리소스의 풀 상태 (모든 그 속성들, 즉, 필드들, 즉 컬럼들) 를 포함한다. 상기 설명된 규범적 표현이 반드시 플랫폼에서 리소스의 (유일한) 물리적 표현은 아님에 유의하는 것이 중요하다. 임의의 파티셔닝 및 오버랩을 갖는, 단일 리소스에 대응하는 다중 데이터베이스 테이블들이 있을 수도 있다. 규범적 테이블은 심지어 이벤트들에 걸친 변환들을 사용하여 요구에 따라 컴퓨팅될 수도 있다 (이하 참조). 특히, 규범적 테이블은 제 6 정규 형태 A6NFB 로 수직으로 파티셔닝되었을 수도 있고, 여기서 각각의 파티션은 단지 리소스의 프라이머리 키, 및 단일 다른 컬럼을 포함한다. 그러한 물리적 설계는 공간을 절약할 수도 있고 오직 작은 서브세트의 컬럼들만이 쿼리에 의해 요청될 때마다 성능 이익들을 갖는다 (템포럴 프로젝션 (Temporal Projection) 을 참조).
이벤트들
이벤트는 단지 타임스탬프된 데이터일 뿐이다. 그것은 어느 시점에서의 측정 또는 믿음 (belief) 이다. 이벤트 또는 이벤트들의 세트로부터 리소스 상태를 도출하는 방법은 이러한 이벤트들의 애플리케이션-특정 해석의 대상이다. 그 해석은 포인트 테이블들 (이벤트들) 로부터 인터벌 테이블들 (리소스들) 로의 변환들을 통해 표현된다. 예를 들어, 타임스탬프 t1 에 이벤트가 있고 (인간이 데이터를 보고 있기 때문에) 그것이 일부 리소스의 생성을 설명한다는 것을 알고 있음을 가정한다. 이 이벤트를 시간 t1 에서의 그 리소스의 템포럴 테이블에 대한 인서트 (insert) 로서 해석한다. 이러한 해석 하에서, 템포럴 테이블은 따라서 valid_from = t1, valid_to = NULL (및 이벤트로부터 추출된 다른 정보) 을 갖는 로우를 포함해야 한다. 이 해석을, 그러한 이벤트에 직면할 때마다 그러한 로우를 템포럴 테이블에 인서트하는 변환으로 표현할 수 있다. 타임스탬프 t2 에 나중의 이벤트가 있고, 시간 t2 에 상기 리소스의 파괴 (destruction) 를 설명한다는 것을 알고 있음을 추가로 가정한다. 이러한 해석 하에서, 리소스의 템포럴 테이블은 따라서 valid_from = t1, valid_to = t2 를 갖는 로우를 포함해야 한다. 이러한 해석을, 템포럴 테이블의 대응하는 로우를 업데이트하여 valid_to = t2 를 설정하는 변환으로 표현할 수 있다. 이벤트들은 임의의 수의 리소스들에 대한 외래 키들을 가질 수도 있고, 그들은 다중 변환들에 입력될 수도 있다.
특수 데이터세트들
옵저베이션들
옵저베이션 테이블은 단지 그 타임스탬프 컬럼으로서 bundle_timestamp 를 갖는 이벤트 테이블일 뿐이다. bundle_timestamp 는 그것이 옵저베이션 테이블로부터 도출된 임의의 이벤트 또는 리소스에 의한 사용을 위해 이용가능하기 때문에 흥미롭다. 즉, 옵저베이션 필드들은 통상적으로 사용자들에게 더 중요한 네스팅된 애플리케이션 타임스탬프들을 포함한다. 당사의 플랫폼은 이러한 애플리케이션 타임스탬프들을, 후에 템포럴 조인들과 같은 템포럴-관계형 연산자들에 의해 특수 처리를 받는 이벤트 타임스탬프들 및 리소스 타임스탬프들로 조작 및 승격시키는 방식들을 제공한다. bundle_timestamp 는 또한 시스템 타임스탬프의 예이다. 그것은 예시적인 실시형태 (확실히 말하면, 옵저버, 센서 또는 수집기) 가 옵저베이션에 대해 학습한 시점을 나타낸다. 시스템 타임스탬프들과 애플리케이션 타임스탬프들 사이에 상당한 스큐가 있을 수 있으며, 이는 (여기서 범위를 벗어나) 변환들의 정의 및 구현에 영향을 미친다. 사이드 노트: 애플리케이션 시간과 시스템 시간 사이의 구별은 스트림-프로세싱 문헌에서 되풀이하여 발생하는 주제이다. 그것은 템포럴 데이터베이스 문헌에서 유효 시간과 시스템 시간 사이의 구별의 듀얼이다. 이상하게도, SQL:2011 은 또한 유효 시간을 애플리케이션 시간으로 지칭한다.
외부 데이터세트들
외부 데이터세트는 옵저베이션 테이블로부터 도출되지 않는 데이터세트이지만, CSV 파일 업로드 또는 Snowflake 데이터 공유와 같은 일부 다른 수단을 통해 정의 또는 임포트된다. 기입할 때 외부 데이터세트들을 지원하지 않지만, 장차 그렇게 할 가능성이 높을 것이다. 외부 데이터세트들은 그들이 변환들의 부분으로서 사용될 때 문제들을 야기한다. 예시적인 실시형태는 만약 있다면 그들의 변환 정의에 액세스하지 않았고, 사용자들이 링크된 외부 데이터세트들의 스키마 또는 컨텐츠들에 브레이킹 변경들을 수행하는 것을 막을 수 없다. 따라서 변환될 때 그들에 몇몇 제한들을 적용해야 할 것이다 (예를 들어: 링크 없음, 단지 카피-온-임포트 (copy-on-import)). 변환들 외에, 외부 데이터세트들은 임의의 다른 데이터세트와 같이 참조 및 쿼리될 수 있다. 사용자가 정적 테이블을, 옵저베이션 테이블을 통해 이동시켜야 하는 대신에 CSV 파일로 업로드하는데 아무 문제가 없다.
스냅샷 테이블들
스냅샷은 특정 시점에서의 인터벌 테이블의 슬라이스이다. 그것은 기하학적으로 시간 인터벌들, 즉 라인 세그먼트들의, 일 시점과의 인터섹션 (intersection) 으로 해석될 수 있다. 시간 인터벌이 원하는 시점과 인터섹트하는 모든 로우는 스냅샷의 부분이다. 일부 스냅샷 시간 t 동안, SQL 에서 그 인터섹션의 구현은 단지 단순한 WHERE t >= valid_from AND t < valid_to 절일 뿐이다. 그 인터섹션의 결과는 분명히 포인트 테이블이다. 스냅샷들은 포인트 테이블들 (여기서 각각의 로우는 동일한 시점을 설명함) 이기 때문에, 스냅샷들은 플레인 관계형 대수 및 SQL 을 사용하여 추론 및 프로세싱될 수 있다. 그것은 스냅샷들에 대한 쿼리들을 인터벌 테이블들에 대한 쿼리들보다 프로세싱하기에 훨씬 더 저렴하게 만든다.
스냅샷 테이블들 대 시간-불변 테이블들
스냅샷 테이블들 및 시간-불변 테이블들은 그들 양자 모두 그들의 타임스탬프 컬럼(들)이 제거되었을 수도 있지만 동일한 것이 아니다. 그들의 물리적 표현은 정확히 동일해 보일 수도 있지만, 다음과 같다:
스냅샷들 및 시간-불변 테이블들은 따라서 다른 테이블들과 쿼리 및 조인될 때 매우 상이하게 거동한다. 사용자들은 타임스탬프 컬럼들을 갖지 않는 외부 데이터세트가 스냅샷 (및 현재 몇시), 또는 시간-불변 테이블로 간주되어야 하는지 여부를 특정해야 한다.
템포럴 테이블들에 대한 조인들
템포럴 조인들의 SQL 구현은 템포럴 조인 (Temporal Join) 에서 논의된다. 현재 문서에서는, 오직 템포럴 조인들의 대수 정의에만 관심을 둔다. 예시적인 실시형태는 모든 보통의 관계형 연산들: 선택 (select), 프로젝트 (project), 합집합 (union), 인터섹트 (intersect), 조인 (join) .. 을 지원한다. 포인트 테이블들은 시점들을 설명하므로, 그들은 마지 레귤러 관계형 테이블들과 같이 거동한다. 단지 흥미로운 경우들은 타임스탬프들이 상이한 포인트 테이블들에 대한 바이너리 연산들 (조인들) 이지만, 시맨틱들은 여전히 분명하다. 예를 들어, 타임스탬프들이 상이한 2 개의 포인트 테이블들의 (내부) 조인은 빈 테이블을 생성하는데, 상이한 시점들이 매칭하지 않기 때문이다. 인터벌 테이블들의 조인들은 효율적으로 구현하기가 까다롭지만, 시맨틱들은 다음으로 요약된다. 예시적인 실시형태에서의 시간은 이산적이다. 정확히 말하면, 크로논이라고도 불리는, 예시적인 실시형태에서의 원자 시간 인터벌은 1 나노초이다. 인터벌 [t, t') 을 갖는 각각의 로우는 개념적으로 인터벌들 [t, t+1), [t+1, t+2), ... [t+n, t') 을 갖는 로우들의 세트로 "언팩킹될" 수 있다. 템포럴 조인과 같은 각각의 템포럴-관계형 연산자는 그 후 (리-팩킹이 후속되는) 언팩킹된 표현에 대한 그 레귤러 관계형 상대물로서 정의될 수 있다. 예를 들어, 임의의 템포럴 조인은 언팩킹된 타임스탬프 컬럼들에 대한 암시적 균등 술어를 포함한다. 그것은 인터벌 테이블들 및 포인트 테이블들이 합집합 또는 조인과 같은 바이너리 연산자에 의해 결합될 때 시맨틱들의 질문을 남긴다. 인터벌 테이블과 포인트 테이블 간의 조인의 결과는 무엇인가? 대수도 클로즈되어 있나?
인터벌 테이블들 및 포인트 테이블들의 내부 조인
템포럴 조인의 본질을 더 잘 이해하기 위해, 그것을 기하학적 연산으로 보는 것이 도움이 된다. 2 개의 인터벌 테이블들 r 및 s 가 있음을 가정한다. 순수 템포럴 조인을 수행중이라고 가정하면, 시간 오버랩 외에 조인 술어는 없다. 그러한 조인은 실제로 템포럴 데카르트 곱이며 - 그것만으로는 좀처럼 유용하지 않지만, 중요한 구축 블록이다. 대부분의 조인들은 인터벌-오버랩 외에, 외래 키 제약들에 기초한 균등 술어들과 같은 추가적인 조인 술어들을 갖는다. 이하의 논의의 어떤 것도 추가적인 술어들을 배제하지 않는다. 우리는 단지 템포럴 술어에만 초점을 맞추도록 선택한다. 템포럴 조인에서 설명된 바와 같이, 다음과 같이 템포럴 조인을 해석할 수 있다. r 의 각각의 로우에 대해, (무한대) 시간 축을 따라, 포인트들 valid_from 로부터 valid_to 로의 대응하는 라인 세그먼트를 그린다. s 에 대해 똑같이 한다. r 및 s 로부터 라인 세그먼트들의 각각의 오버랩하는 쌍에 대해, 이러한 입력 세그먼트들의 인터섹션을 그린다. 이로써 생성된 인터섹션들의 세트는 정확히 템포럴 조인의 결과이다 (기술적으로, 그것은 템포럴 조인의 결과와 동형이다). 인터벌 테이블들 및 포인트 테이블들을 조인하는 시맨틱들은 상기 기하학적 해석을 따른다. 인터벌 테이블 및 포인트 테이블을 조인하는 것은 포인트 테이블을 생성하는데, 포인트와 라인 세그먼트를 인터섹트하면 오직 포인트만이 생성될 수 있기 때문이다. 2 개의 포인트 테이블들을 조인하는 것은 또한: 정확히 동일한 타임스탬프를 갖는 그 로우들의 쌍들만을 반환하는 방식에 의해 잘 정의된다 (그런데, 그것은 상이한 타임스탬프들과 2 개의 스냅샷 테이블들을 조인하는 것이 빈 결과를 생성한다는 것을 의미한다).
인터벌 테이블들 및 스냅샷 테이블들의 내부 조인
스냅샷은 특정 시점에서의 인터벌 테이블의 슬라이스이다. 스냅샷 테이블과 인터벌 테이블을 조인하는 기하학적 해석은 따라서 단일 포인트와 라인 세그먼트들의 세트의 인터섹션이다. 인터섹션은 교환 (commutative) 및 연관 (associative) 연산이다. 스냅샷이 조인 입력들에 대해 수행되는지, 또는 조인의 결과에 대해 수행되는지는 상관없다. 따라서 "스냅샷" 이 쿼리 계획에서 템포럴 조인 아래에 푸시될 수 있다는 결론에 이르게 된다.
정리 1:
시간 조인들은 상대적으로 고가인데, 시간 차원에서 인터벌-오버랩 술어가 균등 술어보다 평가하기에 훨씬 더 고가이기 때문이다. 따라서 쿼리가 조인의 결과를 스냅샷중이면, 이상적으로 스캔 연산자들 내부의 조인 아래에 스냅샷 "연산자" 를 항상 푸시하는 것은 좋은 휴리스틱이다. 더욱이, 시간 t 에서의 스냅샷 r 과 템포럴 테이블 s 사이의 조인의 결과는 오직 시간 t 에서 스냅샷을 생성할 수 있다. 조인은 포인트 t 와 인터섹트하지 않는 s 에서의 어떠한 로우들에도 매칭할 수 없다. 따라서, 모든 s 대신에 시간 t 에서의 s 의 스냅샷을 사용할 수 있다.
정리 2:
조인들은 교환 및 연관되기 때문에, 정리 2 는 임의의 입력 테이블의 스냅샷이 나머지 쿼리를 "감염 (infect)" 시킬 것임을 의미한다. 모든 템포럴 조인들은 실행 비용으로 잠재적으로 극적인 (포지티브) 결과들을 갖는 플레인 올드 조인들이 된다.
인터벌 테이블들 및 포인트 테이블들의 안티-조인 및 왼쪽 조인
템포럴 내부 조인의 기하학적 해석이 주어지면, 템포럴 안티-조인은 설명하기 쉽다. 템포럴 테이블 s 와 템포럴 테이블 r 의 안티-조인을 고려한다. r 의 모든 로우에 대한 라인 세그먼트를 그린다. s 의 모든 로우에 대한 라인 세그먼트를 그린다. r 의 모든 라인 세그먼트에 대해, s 의 모든 오버랩하는 라인 세그먼트들을 뺀다. 나머지 라인 세그먼트들은 안티-조인의 결과이다 (s 의 라인 세그먼트들은 완전히 t 의 일부 라인 세그먼트들 내부에 속할 수도 있기 때문에, 안티-조인의 팩킹된 결과는 실제로 입력보다 많은 로우들을 포함할 수도 있다. 팩킹에 대한 논의에 대해서는 템포럴 프로젝션을 참조한다).
왼쪽 조인은 정의에 의해, 내부 조인과 (NULL-패딩된) 안티-조인의 합집합이다. 인터벌 테이블과 포인트 테이블의 안티-조인 또는 (확장에 의해) 왼쪽 조인을 컴퓨팅할 때 그것은 무엇을 의미하는가? 포인트로부터 라인 세그먼트를 빼는 것은 쉽다. 라인 세그먼트가 포인트와 오버랩하면, 포인트는 제거된다. 따라서, 포인트 테이블이 왼쪽 조인 또는 안티-조인의 왼쪽 입력인 한은, 출력은 포인트 테이블이고 시맨틱들은 분명하다. 그러나 포인트 테이블이 왼쪽 조인 또는 안티-조인의 오른쪽 입력이면 어떨까? 이론상 라인 세그먼트로부터 포인트를 뺄 수 있다; 결과는 그 포인트를 제외한 2 개의 라인 세그먼트들이다. 그러나 데이터 모델 하에서 이러한 상황을 표현할 수 없다. 왼쪽-포함, 오른쪽-제외 시맨틱들을 갖는 이산 valid_from, valid_to 필드들은 단일 포인트의 부재를 표현할 수 없다. 예를 들어, 왼쪽-제외 인터벌들을 허용함으로써 데이터 모델을 확장할 수 있다. 그것은 포인트들을 놓치는 인터벌들을 표현하도록 허용할 것이다. 그러나 그 확장 또는 임의의 등가 확장은 유효성 인터벌들의 물리적 표현 및 따라서 임의의 인터벌 산술 또는 술어들의 SQL 구현을 복잡하게 만들 것이다. 단순성 및 성능을 위하여, 데이터 모델을 있는 그대로 유지하고 대신에 왼쪽 입력이 인터벌 테이블이고, 오른쪽 입력이 포인트 테이블인 안티-조인들, 왼쪽 조인들 (및 풀 외부 조인들) 을 허용하지 않도록 선택한다. 이러한 조인들은 정의되지 않고 컴파일 시간에 타입 에러를 야기할 것이다.
OPAL - Observe Processing and Analysis Language
예시적인 실시형태는 클라우드 스케일 데이터 웨어하우스 위에 구축된, 최신 기술의 템포럴 관계형 모델에 의해 구동된다. 관계형 데이터베이스들 위에 시스템 데이터의 시변 본질을 모델링하는 종래의 시도들은 사용하기 어려워지는 비표준 SQL 확장들로 끝났다. 예시적인 실시형태의 플랫폼은 시스템의 사용자로서 행하길 원하는 동작들의 종류들을 표현하기 위한 단순 언어를 제공하여 시간-의존적 팩터들을 처리함으로써 이 문제를 해결한다. 추가적으로, 플랫폼은 어떠한 쿼리 코드도 반드시 기입할 필요 없이 사용자들이 데이터세트들을 탐색 및 필터링하게 하는 GUI 를 제공한다. 쿼리를 위해, OPAL 은 4 개의 부분들로 스플리팅된다:
1. 입력들, 어떤 데이터를 볼지를 정의
2. 동사들, 어떤 프로세싱을 할지를 정의
3. 함수들, 개개의 데이터를 변환하는 방법을 정의
4. 출력, 쿼리의 결과로 무엇을 할지를 정의
이들은 함께 "쿼리" 로 또한 알려진 "OPAL 파이프라인" 을 구성한다.
입력들
쿼리를 실행하기 위해 판독된 데이터세트들은 보통 GUI 에서 자명하다. 데이터세트를 "탐색" 할 때, 그 데이터세트는 입력이 된다. 다른 데이터세트에서 일부 필드를 룩업할 때, 그 추가적인 데이터세트는 쿼리에 대한 다른 입력이 된다. 쿼리는 원하는 만큼 많은 입력들을 사용할 수 있지만, 개개의 동사들은 얼마나 많은 입력들이 그 특정 동사에 의해 소비되는지에 대한 제한들을 가질 수도 있다. 하나의 중요한 제약은 입력들이 동사에 의해 소비되기 전에 별도로 프로세싱될 수 없다는 것이다. 단일 파이프라인은 "직선 파이프" 이며, 기술적으로 말하면, 풀 DAG (directed acyclic graph) 가 아니다.
출력
쿼리 결과들은 다양한 방식들로 프리젠팅된다. GUI 는 쿼리의 출력의 각각의 컬럼에 대해 상위 K 값들, 히스토그램들, 또는 작은 라인 차트들 (스파크라인들) 과 같은 통계를 계산하도록 백엔드에 요청한다. 추가적으로, 그 상태에 많은 변경들을 갖는 리소스는 속성 변경들을 별도의 변형들의 리스트들로 바꿈으로써 GUI 의 단일 로우로 "롤업될" 수도 있다. GUI 에서, 이는 모두 처리되지만, API 에 직접 예시적인 실시형태에 대해 말하면, 데이터를 프리젠팅하는 방법에 관한 결정을 행해야 한다.
동사들
"동사들" 은 쿼리 파이프라인의 메인 액터들이다. 각각의 동사는 "메인" 입력을 취하고, 이는 파이프라인에서 그 앞의 동사의 출력이다 (제 1 동사는 입력으로서 메인, 또는 제 1 데이터세트를 취한다). 동사는 "룩업" 동사에 의해 사용된 바와 같이, 추가적인 데이터세트들도 입력으로서 취할 수 있다. 동사는 정확히 하나의 결과를 출력하며, 이는 임시 데이터세트로 보여질 수 있다 (그러나 그것은 영구 데이터세트의 프로젝트, 레이블, 및 ID 를 갖지 않는다). 가장 중요한 동사는 필터 동사이며, 이는 디폴트 입력을 취하고, 데이터에 일부 컨디션을 적용하여, 오직 필터 수식의 컨디션에 매칭하는 데이터만 반환한다. 이는 SQL 쿼리에서 WHERE 절과 유사하다. 동사들은 하나 이상의 인수들을 취할 수도 있고, 파이프 문자를 사용하여 함께 스트링된다: |예시적인 파이프라인은 다음이다: filter NUM_RESTARTS > 1 | lookup NODE_ID=@nodes.UID node_name:@nodes.NAME. 이것은 먼저 NUM_RESTARTS 필드가 1 보다 큰 리소스들을 필터링하고, 그 후 NODE_ID 필드를 사용하여 제 2 데이터세트 (노드들) 에서 NAME 을 룩업하여 결과에서 새로운 컬럼 node_name 을 생성한다.
함수들
"함수들" 은 리소스들의 데이터세트들 또는 스트림들에는 작용하지 않고, 개개의 값들에 작용한다. 동사들이 입력 세트들에 대해 작용하고, 출력 세트들을 반환하는 "세트" 연산들인 경우, 함수들은 단일 값들을 반환하는 "스칼라" 연산들이다. 3 개의 종류의 함수들이 있다:
1. 텍스트 표현으로부터 타임스탬프로 변환하는 것, 또는 2 개의 값들을 비교하여 가장 큰 값을 얻는 것과 같은 플레인 함수들 (소위 "스칼라" 함수들).
2. 다중 입력 로우들에 걸쳐서 다중 값들의 일부 요약을 계산하는 요약 함수들 (소위 "집계" 함수들). 이들은 설명하기 쉬운 statsby 와 같은 집계 동사에 사용되어야 한다. 일 예는 statsby 그룹화 기준에 매칭하는 모든 입력 로우들에 걸쳐서 일부 컬럼의 평균을 계산하는 avg() 이다 (이것은 SQL 쿼리에서 GROUP BY 와 유사하다).
3. 포괄 집계 함수들. 이들은 전체 입력 세트에 걸쳐서 집계를 계산하는 손쉬운 방법이다. 예를 들어, maxall() 은 명시적 statsby 또는 서브-쿼리를 사용할 필요 없이, 모든 입력 로우들에 걸쳐서 필드 또는 수식의 최대 값을 반환한다. 예를 들어, 재시작 횟수가 평균 값의 2 배 보다 많은 팟 (pod) 들을 찾기 위해, 다음을 시도한다: filter num_restarts > avgall(num_restarts)*2
일반적으로, 함수들은 인수들로서 수식들을 취할 수 있고, 수식들의 부분일 수 있다. max(num_hosts+3) 는 단지 max(num_hosts)+3 만큼 유효하다.
수식들
각각의 동사 및 함수 인수에 대해, OPAL 은 상당히 간단한 수식들의 세트를 수락한다. 예를 들어, 단순 산술은 +, -, /, 및 * 으로 수행된다. 예를 들어, 2 + 3 * 4 / 5 - 6. 비교들은 동일하게 간단하다: (예를 들어, num_errors > 3, name <= "hello", pi <> 3.14). 디폴트 입력 데이터세트에서의 필드들은 그들의 간단한 이름들을 사용하여 참조된다: (예를 들어, 레이블, @.label) (그 2 개의 참조들은 동일한 것 - 메인 입력 기록 내의 컬럼 "레이블" - 을 의미한다).
필드 참조들은 이와 같은 "베어 (bare) 단어들" 로서 사용될 때 케이스 인센서티브이다. 다음과 같이 케이스 센서티브인 JSON 객체들과 같은 필드들로 인덱싱하는 방식들이 있다: @.some_object.some_field["Another Key Name"]
(조인들에 사용되는 것과 같은) 별도의 입력 데이터세트에서의 필드 참조는 그 다른 데이터세트의 바운드 이름 (bound name) 에 의해 식별된다: lookup me = @you.value newcol:expression(@you.field)
이는 메인 기록으로부터 필드 me 를 사용하고, 필드 value 가 me 값에 매칭하는 데이터세트 you 에서 기록/들을 룩업할 것이다. 그 기록들의 각각에 대해, expression(field) 의 값이 계산되고, 최종적으로 출력 데이터세트에서 새로운 컬럼 newcol 으로서 반환될 것이다. 이는 데이터세트들을 추가적인 정보로 증대시키는 강력한 방식이다. 수식 형태 name:value 는 "컬럼 바인딩" 이라 불린다.
인수 리스트들
함수들은 괄호 안에 인수 리스트를 랩핑하고 그들을 콤마로 분리함으로써 호출된다 (C, JavaScript, Python, 및 많은 다른 언어들과 같음) (예를 들어, search(message, "some text")). 한편, 동사들은 그들의 인수들 주위에 괄호를 사용하지 않지만, 그들은 그들의 인수들을 콤마로 분리한다: (예를 들어, coldrop fields, extra).
데이터 타입들
기본 데이터 타입들은: 정수들, 부동 소수점, 스트링, 및 부울 (boolean) (예를 들어, "일 스트링 (a string)", '다른 스트링 (another string)', 123, 0x123, 4.5e-6, 거짓 (false)) 이다. 추가적으로, OPAL 은 "텍스트 검색 수식들" 및 "레귤러 수식들" (PCRE 가 아닌, ANSI SQL/Oracle 포맷 전용) 을 지원한다. 이들은 주어진 컬럼에 대해 테스트될 수 있다: (예를 들어, filter message ~ <text search> and message ~ /regular.*expression/). 또한 로우에서 모든 검색가능한 필드에 대해 텍스트 검색 수식을 적용할 수 있다: (예를 들어, filter <text search>). 이 특정 예는 임의의 검색가능한 텍스트가 주어진 검색 수식에 매칭하는 모든 기록을 거칠 것이다. 검색 수식들은 간단한 신택스를 갖는다: (예를 들어, filter <some words>, filter <some "words with spaces">, filter <some words or "other words">). 단어 or 는 검색 신택스에서 특별하고, "왼쪽에 있는 것, 또는 오른쪽에 있는 것" 을 의미함에 유의한다. 단어 or 를 검색하길 원하면, 그것을 따옴표로 묶는다: (예를 들어, filter <"or">).
코멘트들
코멘트들은 2 개의 슬래시들 // 로 시작하고 라인의 끝까지 확장한다. 언어에 공백을 넣을 수 있는 곳은 어디든 코멘트를 넣을 수 있다. 이는 스트링 리터럴 내부의 슬래시들이 코멘트를 시작하지 않음을 의미한다 (예를 들어, filter true // this lets through all rows, filter message = "// this is not a comment" // this lets through only matching values).
데이터세트들 및 시간
예시적인 실시형태는 모든 데이터 (시스템 및 애플리케이션 로그들, 메트릭들, 및 트레이싱 범위들) 를, 데이터세트들로 변환되는 옵저베이션들로 수집한다. 데이터세트들은 다른 데이터세트들로/로부터의 링크들 (관계들) 은 물론 시간들 또는 시간 인터벌들로 구성된다. 시스템의 상이한 부분들 사이에 이러한 링크들 (관계들) 을 갖는 것은, 데이터에 숨겨진 의미를 발견할 때 예시적인 실시형태에 막강한 힘을 부여하는 것이다.
데이터세트들
데이터세트는 명명된 프로젝트 내에 있으며, 차례로 이름을 갖는다. 프로젝트 이름들은 고객 내에서 고유해야 하며, 데이터세트 이름들은 그들의 프로젝트 내에서 고유해야 한다. 예시적인 실시형태에 로그인할 때, 고객 id 에 대해 존재하는 상이한 데이터세트들을 브라우징하게 하는 "탐색" 페이지가 보여진다. 데이터세트는 스키마 (명명된 컬럼들의 세트 및 그 컬럼들에 저장된 데이터의 타입) 및 타입을 갖는다: "테이블", "이벤트", 또는 "리소스". 타입은 얼마나 많은 시간-관련 정보가 데이터세트에 관해 이용가능한지에 의해 주로 결정된다.
테이블 데이터세트들
정보가 시간에 관련되지 않고 시간의 경과에 따른 변경들이 추적되지 않으면, 데이터세트는 "테이블" 이다. 이는 대부분의 시스템들에서 보통의 룩업 테이블과 같지만, 시간의 경과에 따른 변경들을 추적하는 것을 허용하지 않기 때문에 예시적인 실시형태에서 가장 적게 사용되는 종류이다.
이벤트 데이터세트들
어떤 일이 "한번에" 일어나고 잘 정의된 타임스탬프를 가지면, 데이터세트는 "이벤트 데이터세트" 이다. 이벤트들은 단일 시점을 갖고, 통상적으로 시스템의 하나 이상의 다른 테이블들에 링크한다 (관련된다). 예를 들어, "사용자 X 가 시간 Z 에 시스템 Y 에 로그인함" 은 이벤트이며, 이는 "사용자" 데이터세트 및 "시스템" 데이터세트에 또한 링크한다.
리소스 데이터세트들
최종적으로, 시간의 경과에 따라 영속성을 갖고, 상태들이 시간의 경과에 따라 변경되는 객체들은, "리소스 데이터세트들" 에 저장된다. 리소스의 임의의 필드 값은 유효성 시간 인터벌 - 시작 시작, 및 종료 시간 - 을 갖는다. 리소스의 경우, "시간 T 에 이름이 무엇이었나요?" 와 같은 질문들을 할 수 있다. 추가적으로, 리소스는 프라이머리 키에 의해 식별된다.
리소스 시간들
최근에 변경되었고 "추후 변경될 때까지" 유효할 값들에 대해, 종료 시간은 알려지지 않고 먼 미래로 있는 것으로 가정된다. 시작 시간에 승계된 값들에 대해, 시작 시간은 알려지지 않고, 시작 시간 이후 지속되는 것으로 가정된다.
리소스 프라이머리 키들
이는 리소스에 할당된 GUID, 일부 데이터베이스에서 할당된 사용자 ID, 또는 네트워크 인터페이스의 MAC 어드레스일 수도 있으며; 그 특정 리소스에 대해 의미가 있는 것은 무엇이든 상관없다. 프라이머리 키들은 복합일 수도 있으며 - 함께 취한 다수의 필드들로 구성된다. 예를 들어, 특정 디스크 디바이스에 대한 프라이머리 키는 디스크가 부착되는 호스트의 "호스트 ID", 및 host-3, /dev/sdc 와 같은 그 호스트 내의 "디스크 인덱스" 일 수도 있다.
템포럴 스플라이싱
정의
인터벌 템포럴 ("리소스" 라고도 알려짐) 데이터세트 X 에 대해, 여기서 시간 T 에 다른 인터벌 템포럴 데이터세트 Y 로 그것을 "스플라이싱" 하는 것이 무엇을 의미하는지를 정의한다. 하이 레벨에서, 연산은 "T 이전 X 로부터 상태들을 취하고 T 이후 Y 로부터 상태들을 취하여 그들을 함께 병합한다" 를 의미한다. 스트림 프로세싱은 시점을 넘어서 템포럴 데이터세트를 업데이트하는데 사용된다. 다음의 시각화된 예에서, 각각의 컬러링된 바 (bar) 는 하나의 로우를 나타내고 x 축 상의 바의 범위는 그것의 valid_from 및 valid_to 에 대응한다. 스플라이싱된 결과는 다음을 포함한다:
X 의 블루 바: valid_from < T 및 valid_to >= T 인 X 의 임의의 로우 그리고 valid_from <= T 및 valid_to > T 인 Y 에는 매칭하는 로우가 없다. 또한 valid_to 를 T 로 절단 (truncate) 한다.
이것은 시간 T 에 리소스에 대한 삭제 이벤트를 수신할 때 발생할 수 있다. 그러한 경우에, X 의 블루 바는 리소스의 원래의 지속기간이고, 최종 스플라이싱된 결과에서 시간 T 에 리소스를 절단해야 한다.
Y 의 퍼플 바: valid_from <= T 및 valid_to > T 인 Y 의 임의의 로우 그리고 valid_from < T 및 valid_to >= T 인 X 에는 매칭하는 로우가 없다. 또한 valid_from 를 T 로 업데이트한다.
보통, 퍼플 바는 valid_from = T 를 가질 것이다 (새로운 리소스는 T 에서 수신된 이벤트에 의해 생성된다). valid_from < T 인 경우는 매우 늦은 이벤트를 수신하고 이력의 "불변성" 을 강제하길 원할 때 발생할 수도 있다. 그러한 경우에 T = watermark 이고, 워터마크가 수정되기 전에 상태 없음을 확실히 하기 위해 리소스를 절단한다.
X 및 Y 양자 모두의 레드 바: valid_from < T 및 valid_to >= T 인 X 의 로우들은 valid_from <= T 및 valid_to > T 인 Y 의 로우들과 내부 내추럴 조인한다. 그 조인 결과에서 X 의 valid_from 및 Y 의 valid_to 를 채택한다.
일 예가 도 3 에 도시된다
예
병합-기반 구현
그 아이디어는 X 에 대해 고유 "row_id" 를 할당하고 is_changed 및 is_deleted 와 같은 필드들을 갖는 "병합 명령 테이블" 을 생성하여 병합이 로우별 기반으로 무엇을 해야 하는지 명령하는 것이다. 여기에 단순히 각각의 경우를 계산하고 그들을 합치는 것에 의한 네이티브 예가 있다. 합집합을 풀 외부 조인으로 대체함으로써 어쩌면 이것보다 더 나을 할 수 있다.
SQL 예가 이하에 도시된다.
이 예에서, 또한 후에 X 에 병합하는데 사용되는 "병합 명령 테이블" 을 생성하기 위해 X 를 사용해야 하기 때문에, snowflake 는 X 를 두번 스캔할 것이다. 다행스럽게도, 양자 모두의 스캔들은 valid_to 에 기초하여 프루닝되므로, 실제로 이 스캔은 몇몇 비순차 (out-of-order) 스캔들과 현재 진행중인 리소스들로 제한되어야 한다.
이것에 대한 하나의 주의 사항은 MERGE 가 타겟 측의 로우들을 중복하도록 허용하지 않는다는 것이다. 따라서 내부 조인 (merged_xy) 이 왼쪽에서 1 초과의 히트들을 생성하면, 비결정적 업데이트 문제에 이를 것이다. 다른 한편으로, 오버랩하는 템포럴 관계들을 갖는 것은 엄격히 금지되지 않지만, 그것은 실제로 자연스럽게 발생해서는 안된다. 사전에 템포럴 관계들을 중복제거함으로써 이 문제를 해결할 수 있기를 바란다.
템포럴 관계형 대수의 집계
템포럴 관계형 모델은 다중 차원들을 갖기 때문에, 어느 하나의 차원에 걸쳐서 집계가 발생할 수 있다 - 시간의 경과에 따라 집계할 수 있거나, 또는 아이덴티티에 대해 집계할 수 있거나, 또는 양자 모두에 대해 집계할 수 있다. 이것은 join 이 원하는 시맨틱들에 의존하여 상이한 유효한 구현들을 갖는 방법과 유사하다.
시간의 경과에 따른 집계를 구현하는 동사는 statsby 이며 시간을 통한 집계를 구현하는 동사는 timestats 이다. 예시하기 위해, 2 개의 리소스들, "foo" 및 "bar" 를 갖고 그들 각각이 그들에 할당된 IP 어드레스를 갖는 것을 가정해보자:
수식 statsby resource, count:countdistinct(ip) 는 다음을 반환할 것이다:
(이는 널 값들을 카운트하지 않는 countdistinct 의 플레이버 (flavor) 를 가정하고 있다). 유사하게, statsby count:countdistinct(ip) 는 count:3 을 갖는 테이블을 단순히 반환할 것이다. 이것은 리소스 또는 이벤트가 아니며; 시간 차원이 붕괴되기 때문에, 이것은 간단한 데이터 테이블이다. 수식 timestats true, count:countdistinct(ip) 은 다음을 반환할 것이다:
이것은 실제로 리소스인, 인스턴스 참 (true) 이 의미하는 싱글톤 리소스 "이 timestats 쿼리의 결과" 이다. timestats resource, count:countdistinct(ip) 를 표현할 수 있지만, 이것은, 상기 입력 데이터세트에서 값이 있는 셀들에 1 을, 그리고 값이 없는 셀들에 0 을 반환하는, 매우 간단한 쿼리일 것임에 유의한다. 그러나, 리소스들이 또한 "노드에서 실행되는 팟" 또는 "클러스터" 또는 그외의 비슷한 것과 같은 추가적인 속성들을 가질 때, 간단하지 않은 결과를 생성하기 위해 시간을 통해 속성들을 그룹화함으로써 집계들을 계산할 수 있으므로, 이것은 여전히 유용하다. statsby 는 또한 이벤트 데이터세트들 및 데이터테이블들에 대해 의미가 있다. 이벤트들 또는 데이터 테이블들에 대한 timestats 의 유용한 정의를 현재 알지 못한다.
지터리 에지들
많은 리소스들에 걸친 "시간 그리드" 의 "셀들" 사이의 에지들은 매우 지터리일 것이며, 일반적으로, 리소스들이 그들의 상태를 시간에 있어서 서로 가깝게, 그러나 정확히 동시는 아닌 시간에 변경될 수도 있기 때문이다. 판독하기 더 쉬운 결과를 생성하기 위해, 그리고 다양한 분석 함수들을 위해, "버킷팅 (bucketing)" 또는 "비닝 (binning)" 또는 "그리딩 (gridding)" 및 "정렬" 을 또한 지원해야 한다. 기본 align 함수는 입력 리소스 데이터세트 (또는 이벤트 세트) 를 취하고 그것을 레귤러 그리드에서 리-샘플링하는 리-샘플링 함수이며, 그 사이즈는 align 동사에 대한 인수이다. 리소스가 단일 버킷 내에 다중 값들을 가질 때, 중간 값들은 손실되고, 각각의 버킷 인터벌의 처음의 속성의 값은 출력 리소스 상태로 샘플링되는 것이다.
출력은 원래의 리소스와는 상이한 리소스 종류 ("입력 리소스의 시간-정렬된 리소스 버전") 인 것을 제외하고는 여전히 리소스이다 (그것은 유효성 인터벌들, 및 프라이머리 키들을 갖는다). 일 예가 입력 리소스 테이블에 대해 이하에 도시된다. 이전 리소스 예들에 대한 것과는 약간 상이한 테이블 형태에서, "속성" 은 "속성" 으로 명명된 속성의 값이다.
align 1 이후의 출력은 다음일 것이다:
시간 4 에서의 bar 에 대한 값은 쿼리의 시간 범위에 의존하여 포함될 수도 있거나 또는 포함되지 않을 수도 있다. align 의 실제 구현은 소정 지속기간이 걸리고 에포크 (epoch) 이후의 시간을 그 기간으로 버킷화하고 그 버킷들의 각각의 처음에 속성들의 값들을 샘플링하므로, 아마 align duration("1m") or align nanoseconds(1000000000) 와 같은 무언가를 볼 수 있을 것이다.
종래의 버킷팅
이벤트들 및 메트릭들의 버킷팅은 timestats 에 의해 또는 align 에 의해 잘 서빙되지 않는다 - timestats 은 입력에서 각각의 가능한 변경 시간에 대해 하나의 출력 로우를 생성하고, align 은 다운샘플링할 때 데이터를 손실한다 (예를 들어, 버킷 내의 "하나의 값" 이 아닌, 그 버킷 내의 "합계" 를 원할 수도 있다). 이것을 구현하는 가장 정확한 방식은 시간에 걸쳐 요약하는 세번째 방식이다; alignedstats 와 같은 것이지만, 이것은 사용자들에게 설명하기 어려울 수도 있다. _또는 어쩌면 UI 는 단지 무슨 일이 일어나는지를 알고 최적 방법 (right thing) 을 행하며, 사용자들은 설명할 필요가 없다.) alignedstats 는 샘플들을 폐기하지 않고 대신에 각각의 버킷에 대한 출력 값을 계산할 것을 제외하고는 align 및 timestats 의 조합과 같을 것이다. 또한, 그것은 변경되지 않는 그리드 셀들의 출력 값들의 상이한 거동을 가질 수도 있다 - "버킷에 이벤트가 없다면, 널을 얻는다" 및 "이벤트 값들은 게이지들이며, 다음 게이지, 또는 타임아웃이 발생할 때까지 유효하게 유지되어야 한다" 의 2 개의 상이한 용법들을 갖는다. 일급 데이터타입으로서 메트릭들을 도입할 때, 그것들로 변환하는 더 나은 방식을 또한 준비해야 할 수도 있고, 정확히 어떤 모습일지 아직 확실하지 않다.
종래의 버킷팅 구현 -
timechart
alignedstats 의 구현은 timechart 를 호출하는 것에 이르고 시간의 경과에 따라 버킷들을 교차하는 조직 키 (organizing key) 에 걸쳐 그리드를 생성하고, 그 후 임의의 특정 버킷과 인터섹트하는 모든 값들을 집계한다. count 또는 average 와 같은 종래의 집계 함수들은 사용자가 실제로 기대하는 결과를 제공하지 않을 수도 있고 - 그러한 집계들의 별도의 시간 가중된 버전이 필요함에 유의한다. 일 예가 시간당 버킷들의 count 이다. 전체 버킷에 걸쳐 있는 4 개의 아이템들, 및 버킷의 처음 10 분만 오버랩하는 2 개의 아이템들을 가지면, 버킷과 인터섹트하는 6 개의 아이템들을 갖는다고 할 수 있거나 (이것은 레귤러 count 임) 또는 버킷 내에 6 분의 4 및 6 분의 2 개의 아이템들을 갖는다고 할 수 있다 (이것은 시간 가중된 count 임).
템포럴 대수 및 객체 모델의 선택/필터링
입력 리소스를 고려한다. 이 픽처는 호스트 이름 ID, 타임 스탬프, 및 이 "호스트" 리소스에 대한 2 개의 속성들로서 정의된 "프라이머리 키" 를 갖는 리소스 테이블을 예시한다. 예시는 예시 목적들을 위해, 테이블 자체 뿐만 아니라 호스트 ID 및 시간에 의해 피벗된 CPU 를 보여준다.
"프라이머리 키", 및 "시간", 및 "술어 진실성" 의 차원들을 고려하면, 실제로 이 테이블에서 데이터를 선택하는 3 가지 상이한 방식들이 있다.
단일 로우들
지금까지 filter 라 불렀던 가장 단순한 것은 수식 filter CPU >= 0.6 에 대해 (피벗 예시에서 레드로 아웃라인된 셀들에 매칭하는) 레드로 아웃라인된 로우들을 반환한다. 산업 표준에 매칭하기 위한 노력으로, 필터를 : where 로 리네이밍할 것인데, 리소스들은 주어진 술어가 그 때에 그 리소스에 대해 매칭하는 리소스 로우들을 정확히 반환하기 때문이다. 결과가 "메모리" 값이 반환되지 않도록 colpick 되면, CPU 값 1.0 을 포함하는 host3 에 대한 반환 값들은 연속적인 변환 파이프라인에 의해 팩킹될 것임에 유의한다.
리소스 인스턴스들
또한, 일부 기준을 충족하는 리소스들의 세트에 대한 모든 데이터로 작업하길 원할 수도 있다. 그 기준은 "어떤 시점에 일부 술어에 매칭" 또는 "주어진 술어에 절대 매칭하지 않음" 중 어느 하나일 수 있다. 이러한 2 개의 기준은 함께 풀 세트 대수를 구성하는 것을 가능하게 만든다. "어떤 시점에 일부 술어에 매칭하지 않음" 은 필요한 빌딩 블록이 아님 (그리고 또한 "일부 술어에 절대 매칭하지 않음/항상 매칭함" 의 부재 시 충분하지 않음) 에 유의한다. "어떤 시점에 일부 술어에 매칭함" 의 기준의 경우, 다음의 동사들이 필요하다: ever 는 "어떤 시점에 술어에 매칭한 리소스들에 대한 모든 리소스 데이터" 를 구현하고, never 는 "어떤 시점에서도 술어에 매칭하지 않는 리소스들에 대한 모든 리소스 데이터" 를 구현하고, always 는 "항상 술어에 매칭한 리소스들에 대한 모든 리소스 데이터" 를 구현한다. 옵저베이션은 always 가 never not 의 별칭이지만 그것을 포함하면 코드를 판독하기가 더 쉬워진다는 것이다. 데이터 포인트들이 always 동사에 대해 누락될 때 무엇을 해야하는지에 대한 질문이 또한 있다 - always 와 never not 사이의 미묘한 차이는 전자가 데이터 갭들을 갖는 리소스들을 배제할 수 있다는 것일 수도 있다. 상기 제시된 테이블은 ever CPU >= 0.6 에 대해 반환된 셀들을 예시한다. 이들이 피벗 테이블 예시의 수직 컬럼들에 맵핑하는 시간/프라이머리 키 피벗에서 볼 수 있다. "메모리" 값이 반환되지 않도록 결과가 colpick 되면, CPU 값 1.0 을 포함하는 host3 에 대한 반환 값들은 연속적인 변한 파이프라인에 의해 팩킹될 것임에 유의한다.
시간 인터벌들
최종 차원은 시간이다. 일부 컨디션이 SOME 리소스에 대해 참으로 유지되는 모든 시간 윈도우들 (리소스들에 걸친 모든 데이터) 에서 작업하는 것이 유용할 수도 있다. 이는 CPU < 1.0 인 컨디션에 대해 상기 제시된 테이블에 예시된다. 동사 when 은 "술어가 일부 리소스에 대해 참으로 유지되는 모든 시간들에 대한 데이터" 를 구현한다. 이는 CPU < 1.0 인 컨디션에 대해 상기 제시된 테이블에 예시된다. 다시, 템포럴 팩킹은 리소스 데이터 로우들의 실제 정렬에 의존하여 반환된 로우들의 수를 수정 (및 슬라이싱) 할 수도 있다.
다른 데이터세트 종류들
리소스 대수는 베이스 템포럴 대수 위에 있는데, 그것은 항상 "프라이머리 키" 및 "시간" 의 2 차원 구성을 고려하기 때문이다. 베이스 템포럴 대수는 프라이머리 키의 어떠한 개념 없이도 정의된다. 상기 동작들에 대해 생각하는 하나의 방식은 그것들을 정의된 프라이머리 키를 갖는 템포럴 데이터세트들에서 작업하는 것으로 해석하는 것이며, 그들은 암시적으로 프라이머리 키를 그룹화/조인 선택자로서 추가할 것이다. 앞으로, 이러한 연산자들을 확장하여 일관된 방식으로 어떠한 프라이머리 키 (여기서 각각의 로우는 키이다) 도 없는 데이터세트들에서 작업할 수 있으며, 이 경우 그들은 근본적인 템포럴 대수 선택들로 감소한다.
번들들을 내보내는 것에 대한 노트들
고객은 번들들이 아닌 옵저베이션들을 전송한다. 종종, 그들은 이미 데이터를 펌핑 아웃하는 기존 통합을 가질 것이다. 이 데이터는 JSON blob 및 일부 추가 메타데이터로 구성될 수도 있다 (예를 들어, 허니콤은 줄바꿈으로 경계가 정해진 JSON blob들을 내보내지만, URL 경로 및 쿼리 파라미터들을 통해 일부 메타데이터를 전달한다). (예를 들어, elastic 은 고객 포맷을 가지며, 그것에 의해 데이터는 공통 메타데이터 프리앰블 (_index 및 _type 필드들) 에 의해 선행될 수 있다. 고객들은 옵저베이션들로 작업하는 것을 통해 예시적인 실시형태들과 상호작용한다. 그러나 수집 시, 이러한 옵저베이션들을 번들들로 팩킹하고: 오직 고객들의 제어 하의 번들 필드만이 옵저베이션 리스트이다. 이러한 번들들이 얼마나 커지는지를 제한할 필요가 있는데, 그들을 프로세싱 파이프라인 더 아래로 내보낼 때 제약들이 있기 때문이다 (예를 들어, kafka). 번들은 트랜스포트 (http, grpc, 원시 소켓, 수집 파이프라인의 상이한 스테이지들에서의 타임스탬프들, auth info) 에 밀접하게 링크되는 요청-범위 메타데이터를 함께 캐리한다. 옵저베이션들을 번들들에 패킹하는 것으로부터, 옵저베이션들로 고객 입력을 파싱할 책임을 가능한 한 많이 분리하길 원한다. 인바운드 (inbound) 프로세싱을 핸들링하기 위한 현재 제안된 인터페이스는 proto3/bundlepb 에서 정의된, Emitter 이다:
입력을 파싱할 책임이 있는 통합 핸들러는 일단 그것이 완료되면 Emit 함수를 단지 호출할 수 있다. 이것은 적어도 하나의 번들 (또는 에러) 을 생성할 것이다. 핸들러는 Emit 에 대한 호출들에 걸쳐서 옵저베이션들을 나눌 수 있기 때문에 번들링에 약간의 영향을 미친다. 번들을 팝퓰레이팅하는데 사용되는 정보는 요청 컨텍스트와 함께 캐리된다. 이것은 customer_id 를 인서트하기 위해 번들들을 카피해야 하는, msgq_ingestor.go 에서와 같은 상황들을 회피한다:
이제 함수 호출들을 통해 명시적으로 컨텍스트를 전달하므로, 대신에 채널로 또는 직접 kafka 로 전달할 때까지 번들의 구성을 지연시킬 수 있다. 컨텍스트를 조작하는 헬퍼들은 proto/bundlepb 에서 다음의 일반적인 패턴을 갖는다:
일단 번들을 생성하기 시작하면, FromContext 를 사용한다:
템포럴 선택
이 섹션은 템포럴 선택이라고 알려진 시간 차원에 대한 데이터 선택을 설명한다. 템포럴 선택은 포인트 선택 또는 인터벌 선택 중 어느 하나일 수 있다. 포인트 선택은 오직 특정 시점의 데이터만을 반환한다. 인터벌 선택은 시간의 인터벌 내의 데이터를 반환한다. 다음과 같이 기하학적으로 템포럴 선택을 해석할 수 있다. 입력 테이블 R 이 있음을 가정한다. R 의 각각의 로우에 대해, (무한대) 시간 축을 따라 포인트들 valid_from 으로부터 valid_to 까지 대응하는 라인 세그먼트를 그린다. R 이 포인트 테이블이면, 개별의 타임스탬프에 포인트를 그린다. 템포럴 선택 술어에 대응하는 포인트 또는 인터벌을 그린다. 그 포인트 또는 인터벌 t 를 호출한다. 최종적으로, t 와 오버랩하는 R 의 각각의 라인 세그먼트 r 에 대해, r 과 t 의 인터섹션을 그린다. 이렇게 하여 생성된 인터섹션들의 세트는 정확히 템포럴 선택의 결과이다 (기술적으로, 그것은 템포럴 선택과 동형이다). 템포럴 선택은 t 와 오버랩하는 R 의 모든 로우들을 단순히 반환하지 않음에 유의한다. 그것은 t 와 이러한 로우들의 인터섹션을 반환한다. 모든 반환된 로우들의 시간 포인트들 또는 인터벌들은 t 에 포함된다.
예들:
SQL 구현
where 절들은 Snowflak 가 정적 프루닝을 수행할 만큼 충분히 간단하다. greatest 및 least 함수들은 인터벌 인터섹션을 수행하는 정밀한 방식이다. 어떤 입력이 null 이면 greatest 및 least 는 null 을 반환하기 때문에 ifnull 의 사용에 유의한다. 그런 의미에서, 그들은 min 및 max 집계 함수들 (이는 null 입력을 무시함) 과는 상이하게 거동한다. 최종적으로, 등가물 ifnull(greatest( and ifnull(least( 대신에 greatest(ifnull( 및 least(ifnull( 의 사용에 유의한다. 마이크로벤치마크들에 따르면, 함수들의 이전 순서는 눈에 띄게 더 효율적이다. 왜냐하면, greatest 및 least 가 비-널가능한 입력에 대한 별도의, 보다 효율적인 구현을 갖기 때문이다. 비-null 제 2 인수를 갖는 ifnull 은 greatest 및 least 에 대한 입력을 비-널가능하게 만들기 때문에, Snowflake 컴파일러는 그 보다 효율적인 구현을 선택할 수 있다. 실제로, 오직 greatest 및 least 가 우려될 때만이 아니라, 항상 복합 수식에서 ifnull 을 최내부 함수 (innermost function) 로 만드는 것은 좋은 휴리스틱이다. Snowflake 의 대부분의 함수들 및 연산자들은 비-널가능한 입력에 대해 최적화된 구현들을 갖는다.
대수 최적화들
상기 예들이 보여짐에 따라, 인터벌 테이블 상의 포인트 선택은 포인트 테이블을 반환한다. 따라서 템포럴 선택은 테이블의 "템포럴 타입" 을 변경하는 하나의 방식이다. 더욱이, 포인트 선택에 의해 반환된 모든 로우들은 동일한 타임스탬프를 공유한다. 따라서 포인트 테이블은 사실 스냅샷 테이블이다. 스냅샷 테이블들의 지식은 예시적인 실시형태의 쿼리 컴파일러에 중요한데, 컴파일러가 스냅샷 테이블들을 프로세싱할 때 비-템포럴 연산자들 (레귤러 관계형 대수) 을 선택할 수도 있기 때문이다. 더욱이, 스냅샷 테이블들과의 조인들은 항상 스냅샷 테이블들을 반환한다. 포인트 선택들은 대수 최적화들의 중요한 소스이고 쿼리 계획에서 가능한 멀리 푸시 다운되어야 한다는 결론에 이르게 된다. 인터벌 선택들은 또한 최적화에 유용하다. 상기 설명된 바와 같이, 인터벌 선택에 의해 반환된 임의의 시간 인터벌은 선택 술어에 사용되는 인터벌에 의해 포함되어야 한다. 내부 조인들은 연관 및 교환적이며, 따라서 인터벌 인터섹션이다. 따라서, 템포럴 내부 조인들의 트리에 의해 반환된 임의의 시간 인터벌은 입력 테이블들 상의 선택 술어들에 사용되는 시간 인터벌들의 인터섹션에 의해 포함되어야 한다. 컴파일러는 컴파일-시간에 결합된 (인터섹트된) 선택 인터벌을 컴퓨팅하기 위해 이 대수적 사실을 사용하고, 그것을 정적 프루닝 및 더 낮은 실행 비용을 가능하게 하기 위해 조인 트리의 모든 브랜치로 푸시 다운할 수 있다. 스냅샷 테이블들 및 인터벌 테이블들의 조인 시맨틱들에 대한 더 많은 정보에 대해서는 데이터 모델을 참조한다. 최종적으로, 예들에서 또한 알 수 있는 바와 같이, 팩킹된 테이블 상의 템포럴 선택은 항상 팩킹된 테이블을 생성한다. 왜냐하면, 출력 로우들의 인터벌들이 입력 로우들의 인터벌들에 의해 포함되기 때문이다. 따라서 임의의 2 개의 인터벌들이 입력에서 충족 또는 오버랩하지 않으면, 그들은 또한 출력에서 충족 또는 오버랩할 수 없다. 팩킹의 정의에 대해서는 템포럴 중복제거 (DISTINCT) 를 참조한다.
템포럴 프로젝션
프로젝션은 Selection _Filter) 와 함께 가장 단순한 관계형 연산자이다. 그것은 주어진 테이블로부터의 컬럼들, 예를 들어, 속성들의 서브세트를 선택한다. 템포럴 프로젝션은 레귤러 관계형 프로젝션보다 제법 더 많이 흥미로운데, 팩킹된 인터벌 테이블에 대해 레귤러 관계형 프로젝션을 수행하는 것은 더 이상 팩킹되지 않은 출력 테이블을 초래할 수 있기 때문이다.
팩 (Pack)
그 파티션의 모든 로우에 대해, 오버랩하는 또는 인접한 유효성 인터벌을 갖는 다른, 비-구별 로우가 없으면 인터벌 테이블을 패킹된 것으로 정의한다. NULL 속성들의 가능성을 커버하기 위해 "동일한" 대신에 "비-구별 (non-distict)" 을 기입한다. NULL 은 NULL 과 구별되지 않는다 (NULL is not distinct from NULL) 는 SQL 에서 참으로 평가되는 한편, NULL = NULL 은 거짓으로 디케이하는 (decay) NULL 로 평가된다. 2 개의 로우들의 유효성 인터벌들은 하나의 로우의 valid_to 필드가 다른 로우의 valid_from 필드와 같으면 인접한다. 예로서, 다음의 테이블은 팩킹되지 않는데, 제 2 로우가 시간 5 에 제 3 로우에 인접하고, x 및 y 의 값들 양자 모두가 구별되지 않기 때문이다.
테이블은 제 2 및 제 3 로우를 병합함으로써 팩킹된다:
원래 및 팩킹된 테이블은 의미론적으로 등가임에 유의한다. 팩은 의미론적 의미에서 no-op 이다. 그럼에도 불구하고, 그것은 설명할 바와 같이 성능에 중요하다. 팩은 다음과 같이 SQL 에서 구현될 수 있다:
Snowflake 의 쿼리 계획은 도 4a 에 도시된다. 2 개의 WindowFunction 연산자들 (PartitionOrderBy) 및 SQL 의 구조를 정확히 미러링하는 최종 Aggregate 연산자 (GroupBy) 를 볼 수 있다. 상기 SQL 구현은 데이터에 템포럴 중복이 없다는 가정 하에 결정적이고; 즉, 유효성 인터벌들이 오버랩하는 비-구별의 로우들이 없다.
이하는 비-결정적 팩 연산의 예이다. 제 2 및 제 3 로우는 시간적으로 오버랩하므로, 제 1 로우는 제 2 로우 (왼쪽 하부 결과) 또는 제 3 로우 (오른쪽 하부 결과) 중 어느 하나와 병합될 수도 있다.
2 개의 가능한 결과들은 의미론적으로 등가이고, 정보가 손실되지 않는다. 따라서, 팩은 데이터의 템포럴 중복과 관계없이 잘 정의되고 안전한 연산이다.
템포럴 프로젝션
팩킹된 인터벌 테이블의 레귤러, 관계형 프로젝션이 더 이상 팩킹되지 않는 출력 테이블을 초래할 수 있다는 것을 예로 보여주는 것은 쉽다:
컬럼 y 를 프로젝팅하는 것은 결과 테이블을 더 이상 팩킹되지 않게 하였는데, 제 2 로우는 시간 6 에 제 3 로우에 인접하고, 로우들이 상이한 나머지 속성들이 없기 때문이다. 완전성을 위해, 여기에 팩킹된, 프로젝팅된 테이블이 있다:
일반적인 경우에, 팩킹이 후속되는 관계형 프로젝션은 많은 수의 입력 로우들이 단일 출력 로우에 병합되는 것을 초래할 수 있다. 그 통찰력은 인터벌-오버랩 술어들이 효율적으로 평가하기 어렵기 때문에 템포럴 조인들에 특히 유용하다 (템포럴 조인 참조). 따라서, 기본적으로, 조인에 대한 입력으로서 사용하기 전에 관계형 프로젝션의 결과를 팩킹하는 것이 바람직하다. 최적으로서, 팩킹은 컴파일러가 그것이 정확성에 필요하지 않고 그것을 생략하면 성능 이점이 제공된다고 결정하는 경우들에 있어서 생략될 수도 있다. 예를 들어, 불변의 리소스; 즉, 각각의 구별 키 (distinct key) 에 대해 리소스 테이블에 정확히 하나의 로우가 있도록 상태를 절대로 변경하지 않는 리소스로 처리하고 있다면; 팩은 효과가 없을 것이고 생략되어야 한다. 다른 예로서, 템포럴 조인 구현은 입력들이 팩킹되지 않더라도 정확한 결과를 생성한다. 따라서 컴파일러가 그 통계로부터 데이터가 (예를 들어, 구별 키들의 수 대 로우들의 수를 보는 것에 의해) "대부분" 팩킹된다고 결정할 수 있다면, 팩 연산을 조인 후 수행하거나, 또는 전혀 수행하지 않도록 선택할 수도 있다.
템포럴 조인 (Temporal Join)
템포럴 관계형 조인은 관계형 조인의 일반화이다. 레귤러 조인 술어 (즉, 일부 외래-키 제약에 기초한 일부 균등 술어) 에 더하여, 템포럴-관계형 조인의 조인 술어는 입력 로우들의 유효성 인터벌들에 걸쳐 암시적 "오버랩" 술어를 추가한다. 즉, 입력 테이블들 R 및 S 에 대해, 로우들 R 의 r, S 의 s 의 유효성 인터벌들은 출력에서 나타나도록 조인된 로우 rs 에 대해 "오버랩" 해야 한다. 그러한 조인을 다음과 같이 기하학적으로 해석할 수 있다. R 의 각각의 로우에 대해, (무한대) 시간 축을 따라, 포인트들 valid_from 으로부터 valid_to 까지 대응하는 라인 세그먼트를 그린다. S 에 대해 똑같이 한다. 각각의 오버랩하는 쌍의 라인 세그먼트들 R 의 r 및 S 의 s 에 대해, 이러한 입력 세그먼트들의 인터섹션을 그린다. 이렇게 생성된 인터섹션들의 세트는 정확히 템포럴 조인의 결과이다 (기술적으로, 그것은 템포럴 조인과 동형이다). 이제, R 및 S 가 각각 컬럼 k 를 포함하고, R.k = S.k 에 대한 템포럴 동등-조인 R join S 를 컴퓨팅하길 원한다고 가정한다. 그러한 템포럴 동등-조인은 k 로 양자의 테이블들을 파티셔닝한 후, 파티션들의 각각의 대응하는 쌍의 순수 템포럴 조인을 (상기 설명된 바와 같이) 수행하고, 최종적으로 이러한 개개의 조인 결과들의 union (all) 을 행함으로써 쉽게 컴퓨팅될 수 있다. 대안적으로, 처음에 R.k = S.k 에 대한 레귤러 동등-조인을 수행한 후, 중간 결과를 k 로 파티셔닝하고, 최종적으로 각각의 중간 로우에 대한 오버랩-술어 및 인터섹션 연산을 평가할 수 있다. 이러한 상이한 구현 옵션들의 이유는 템포럴 조인이 2 개의 차원들: 키 차원 (레귤러 조인 술어가 주어지면 무엇이든), 및 시간 차원을 갖는다는 것이다. 처음에 키 차원을 핸들링하거나, 또는 처음에 시간 차원을 핸들링하거나, 또는 심지어 일부 복잡한 방식으로 이러한 차원들을 인터리빙하도록 선택할 수 있다. 어느 솔루션이 가장 효율적인지는 각각의 차원에 대한 조인의 선택성에 의존한다. 모든 다른 것들이 동일하면, 항상 가장 선택적인 술어를 먼저 평가하길 원한다. 템포럴 내부 동등-조인의 예가 이하에 도시된다:
메인 구현 과제는 "오버랩 (overlaps)" 술어를 레귤러 RDBMS (여기서 Snowflake, 그러나 Snowflake 로 제한되지는 않음) 에 의해 효율적으로 평가될 수 있는 조인 술어로 트랜슬레이트하는 방법이다. 이와 관련하여 놀랄 만큼 어려운 서브-문제는 -inf 및 inf 를 표현하는 방법이다. "오버랩" 술어의 효율적인 평가는 "밴드 조인" 이라 불리는 특수 조인 연산자를 요구한다. Snowflake 는 네이티브 (그러나 다소 다루기 힘든) 밴드 조인 구현을 갖는다.
템포럴 중복제거 (DISTINCT)
템포럴 중복제거는 모든 가능한 순간에 관계형 중복제거를 수행한다. 다음의 예를 고려한다:
상기 테이블은 다수의 술어들을 포함한다. 제 2 로우는 시간 인터벌 C5, 7B 에서 제 3 로우와 오버랩한다. 제 3 로우는 시간 인터벌 C7, inf) 등에서 제 4 로우와 오버랩한다. 중복제거된 테이블은 다음과 같이 보인다:
템포럴 중복제거 (DISTINCT) 는 템포럴 프로젝션에서 설명된 팩 연산에 대략 관련된다. 팩은 시간에 있어서 인접한 비-구별 로우들을 병합한다. 중복제거는 시간에 있어서 오버랩하는 비-구별 로우들을 병합한다. 템포럴 중복제거는 이하에 도시된 바와 같이 구현될 수 있다.
실제 SQL 구현은 테이블을 시점들로 확장하지 않지만, 대신에 입력 로우들을 안티-조인 구현과 같이, "로우 시작" 및 "로우 종료" 이벤트들로 변환한다. 팩 구현은 템포럴 프로젝션으로부터 카피-페이스트될 수 있다. 여기에 풀 SQL 이 있다:
Snowflake 실행 계획은 도 4b 및 도 4c 에 도시된 바와 같이 보인다. 도 4b 및 도 4c 에 도시된 바와 같이, 리소스들을 이벤트들로 변환하는 WithClause - UnionAll 다이아몬드, 그 다음에 러닝 카운트 (WIN_SUM) 를 위한 WindowFunction, 그 다음에 팩 연산을 위한 2 개의 WindowFunction 및 최종 Aggregate 연산자가 후속된다. 따라서 그 계획은 SQL 쿼리의 구조를 정확히 미러링한다.
템포럴 GroupBy
템포럴 GroupBy 는 모든 가능한 시점에 원하는 그룹화된 집계들을 컴퓨팅하는 것을 제외하고는 마치 레귤러, 관계형 GroupBy 처럼 거동한다. 다음의 예를 고려한다:
여기에 array_agg(z) GROUP BY x,y 쿼리에 대한 예상된 결과가 있다:
x, y 쌍들의 모든 그룹에 대해, 구별의 array_agg(z) 집계 결과들의 팩킹된 이력을 얻는 방법에 유의한다. 특정 순간에 결과 테이블로부터 Select 하면, Select 의 결과는 정확히 그 순간 동안 원래 입력 테이블에 대해 Select 를 수행한 후, 그에 대한 레귤러, 관계형 GroupBy 를 컴퓨팅한 결과일 것이다.
구현
템포럴 GroupBy 를 컴퓨팅하는 것은 약간 고가인데, 모든 입력 로우가 그 자신의 윈도우를 정의하고, 많은 다른 로우들 및 윈도우들과 오버랩할 수도 있기 때문이다. 그것은 단지 연산의 본질일 뿐이다. 여기에 일반적인 아이디어가 있다:
키 (x,y) 를 그룹화함으로써 이벤트 로우들을 파티셔닝한다. 파티셔닝된 이벤트 로우들을 타임스탬프에 의해 소팅한다. 인접한 이벤트 로우들의 모든 (슬라이딩) 쌍은 윈도우를 정의한다.
SQL 은 다음과 같이 보인다:
상기 SQL 은 시간에 의해 순서화된 array_agg 의 결과를 행하기 위해 array_agg(z) within group (order by r_bounded.valid_from) 을 사용함에 유의한다. 그것은 단지 Snowflake 에 의해 지원된 순서화되지 않은 또는 순서화된 집계의 임의의 종류를 수행할 수 있음을 예시할 뿐이다.
조인의 최적화
윈도우된 그룹들 (r_window) 과 원래의 입력 (r_bounded) 사이의 조인은 주목할 만한데, 그것이 내부 조인에서 논의된 보통의 "interval overlaps" 조인과는 대조적으로 "interval within" 조인이기 때문이다. "interval overlaps" 조인이 물론 정확할 것이지만, 윈도우된 그룹들의 시간 인터벌들이 원래의 입력에서 매칭하는 로우들의 시간 인터벌 내에 속한다는 것을 알고 있다. 왜냐하면, 연속적인 이벤트들의 타임스탬프들로부터 윈도우된 그룹들을 구성하기 때문이다. 매칭하는 윈도우된 그룹을 완전히 커버하지 않은 임의의 입력 로우; 즉, 매칭하는 윈도우된 그룹 내부의 어딘가에 놓인 입력 로우의 valid_from 또는 valid_to 타임스탬프가 있었다면, 이러한 타임스탬프들은 더 작은 윈도우된 그룹을 초래할 것이다. 모순 증명법 (proof by contradiction). "interval within" 조인은 실제로 "interval overlaps" 조인보다 훨씬 더 효율적으로 실행될 수 있다. SQL 구현에서, 심지어 그것을 "point inside interval" 조인으로 재기입했고, 이는 Snowflake 에 특별한 구현을 갖는다 (그렇지만 그 구현은 현재 다른 균등 술어가 존재할 때 사용되지 않는다). 재기입은 r_window 로우의 valid_from 이 매칭하는 r_bounded 로우의 인터벌 내에 속하는 경우 그리고 그 경우에만, valid_to 는 또한 상기 추론된 바와 같이, 윈도우된 그룹들이 구성되는 방식에 의해, 인터벌 내에 속하기 때문에 유효하다.
실행 계획
예시적인 실시형태의 실행 계획은 도 5a 내지 도 5d 에 도시된다. neginf, posinf 를 위해 요구된 연산자들을 무시한다; 그 계획은 3 개의 WindowFunction PartitionOrderBy) 연산자들, 3 개의 Aggregate GroupBy) 연산자들, 및 하나의 Join 연산자로 구성된다. 첫번째 Aggregate 연산자는 이벤트들의 중복제거 (distinct) 를 수행한다. 그 후, WindownFunction 연산자는 lead 를 사용하여 이벤트들로부터 윈도우들을 컴퓨팅한다. 그 후 윈도우들과 입력 테이블 사이에 Join, 그 다음에 array_agg 를 컴퓨팅하는 Aggregate 연산자가 나온다. 옵션의 팩 연산은 그 후 2 개의 WindowFunction 및 하나의 Aggregate 연산자를 요구한다. 따라서 통틀어 Temporal GroupBy 단독에 대해 4 개의 "헤비 (heavy)" 연산자들, 그리고 Pack 에 대해 다른 3 개의 헤비 연산자들을 보고 있다. 이들은 고가의 연산들일 수 있다. 긍정적으로 생각해보면, 모든 이러한 연산자들은 x, y 에 의해 해싱하므로, 이 계획은 템포럴 조인들을 둘러싸는 보통의 이슈들을 제외하고는 정확히 병렬화 및 실행되어야 한다. NULL 값들이 윈도우들을 생성하지만 대부분의 집계 함수들의 결과를 변경시키지 않기 때문에, 입력이 많은 NULL 값들을 포함하는 것으로 알려질 때마다 팩킹이 바람직하다. 팩킹은 이러한 인접한 윈도우들을 동일한 집계 결과와 병합한다. 입력으로부터 NULL 값들을 단순히 필터링하는 것은 잘못된 결과들로 이어질 수 있음에 유의한다. 상기 예에서, 그룹 x = 2, y = 3 은 z 에 대한 NULL 값들만을 포함한다. 이러한 입력 로우들을 필터링하면 결과로부터 로우 x = 2, y = 3, arr_z = NULL 이 제거될 것이다.
윈도우된 집계
윈도잉은 템포럴 테이블을 시간의 윈도우들, 즉 시간 인터벌들로 슬라이싱하는 액트를 지칭한다. 레귤러 집계 (group by) 에 대하여, 윈도우된 집계는 그룹화의 추가 차원: 시간 윈도우들을 추가하는 것으로 이해될 수 있다. 그러나 조금 더 많은 것이 있다. 레귤러 그룹화와는 대조적으로, 윈도우들은 오버랩할 수 있다. 그들은 디스조인트할 필요가 없다 (그렇지만 그것은 중요한 특수 경우이다). 또한, 윈도우된 집계 함수들은 종종 아이템들 간의 (시간-)순서화를 수반한다. 예를 들어, 사용자는 이동 평균 또는 러닝 합을 요청할 수도 있다. 따라서 윈도우된 집계는 추가적인 시간 차원을 갖는 단순 레귤러 집계가 아니다. 3 개의 가장 통상적으로 사용되는 타입들의 윈도우들은 다음이다:
슬라이딩: 텀블링 윈도우들과 같이, 슬라이딩 윈도우들은 시간을 균일한 폭의 윈도우들로 분할한다. 그러나 텀블링 윈도우들과 달리, 슬라이딩 윈도우들은 오버랩한다. 예를 들어, 1 시간 윈도우 사이즈 및 10 분 슬라이드 기간으로 슬라이딩 윈도우를 정의할 수 있다. 각각 1 시간 윈도우는 그 후 10, 20, 30, 40, 50 분 오프셋들에서 시작하여, 5 개의 다른 1 시간 윈도우들과 오버랩할 것이다.
세션: 세션 윈도우들은 입력 데이터로부터 도출된 시간 인터벌들에 걸쳐 정의된다. 예를 들어, 사용자는 각각의 웹 세션 동안 웹서버에서의 가비지 수집기 런들의 수에 관심이 있을 수도 있다.
윈도우된 집계는 4-단계 프로세스로서 개념적으로 설명될 수 있다 (그렇지만 구현은 상이한 접근법을 선택할 수도 있다):
1. 윈도우 할당: 각각의 입력 로우에 대해, 그것을 그 로우가 속하는 모든 윈도우에 할당 (카피) 한다. 텀블링 윈도우들의 경우에, 그것은 오직 하나의 윈도우일 것이고; 슬라이딩 또는 세션 윈도우들의 경우에, 그것은 다중 윈도우들일 것이다.
2. 그룹: 각각의 윈도우에 대해, 그룹화 키에 의해 그 데이터를 그룹화한다. 그룹화 키는 비어 있을 수도 있고, 그 경우에 그룹은 전체 윈도우이다.
3. 소팅: 각각의 그룹을 시간에 의해 소팅한다 (기술적으로, 시간 뿐만 아니라 임의의 순서화 술어가 가능하지만, 시간은 디폴트이다). 집계 함수들이 순서-애그노스틱 (order-agnostic) 이면 (예를 들어, 카운트), 이 단계는 스킵될 수 있다.
4. 집계: 집계 함수를 각각의 소팅된 그룹에 적용한다.
출력 테이블은 윈도우 및 그 윈도우 내의 그룹 당 하나의 로우를 포함한다.
윈도우 할당
윈도우 할당은 개념적으로 입력 테이블과 윈도우 테이블 사이의 템포럴 내부 조인이다. 각각의 입력 로우는 그것이 오버랩하는 모든 윈도우에 할당된다. 이 정의는 세션 윈도우들을 처리할 때 특히 자연스럽고 유용하다. 세션은 리소스로서 모델링될 수 있다. 각각의 리소스 인스턴스의 유효성 인터벌 (valid_from, valid_to) 은 윈도우를 구성한다. 예 "각각의 웹 세션 동안 웹서버에서의 가비지 수집기 런들의 수" 로 돌아가면, 이벤트 (또는 원한다면 리소스) 로서 "가비지 수집기 런" 을, 그리고 리소스로서 "웹 세션" 을 모델링할 수 있다. 윈도우 할당은 그러면 "가비지 수집기 런" 테이블과 "웹 세션" 테이블 사이의 템포럴 내부 조인과 등가이다. SQL 에서 템포럴 내부 조인들을 표현하는 방법은 여기에 상세히 논의된다:
윈도우 구성
텀블링 윈도우들 및 슬라이딩 윈도우들은, 그 윈도우들이 애플리케이션 데이터세트로부터 나오지 않고, 실시간으로 (on-the-fly) 생성된다는 것을 제외하고는, 동일한 방식으로 처리될 수 있다. 예를 들어, 텀블링 윈도우 테이블은 table(generator()) 테이블 함수를 사용하여 쉽게 생성되거나, 또는 심지어 values 절로 확장될 수 있다.
예, 지난 7 일 동안 1 일 텀블링 윈도우 (현재 시간에 정렬됨):
슬라이딩 윈도우는 텀블링 윈도우와 오프셋들의 테이블의 데카르트 곱과 같은, 텀블링 윈도우들 또는 더 기발한 것의 union all 로서 표현될 수 있다.
예, 지난 7 일, 1 일 슬라이딩 윈도우, 1 시간 슬라이드 기간 (현재 시간에 정렬됨):
텀블링 윈도우들에 대한 이벤트들의 최적화된 할당
템포럴 내부 조인은 슬라이딩 윈도우들 및 세션 윈도우들에 대해 불가피할 수 있는데, 윈도우들이 오버랩하여, 단일 입력 로우가 다중 윈도우들에 나타나게 할 수도 있기 때문이다. 조인은 입력 로우를 가변적인, 언바운드 수의 출력 로우들에 중복하는 유일한 방식이다. 조인은 그러나 텀블링 윈도우들에 이벤트들을 할당하기에 과도하다. 텀블링 윈도우들은 오버랩하지 않으므로, 각각의 이벤트는 많아야 1 윈도우에 속할 수도 있다 (윈도우들의 세트가 유한한 경우 0 윈도우들에 속할 수도 있다). 윈도우 할당의 훨씬 더 효율적인 구현은 width_bucket() 함수이다:
여기에 지난 7 일의 이벤트 타임스탬프들의 1-일 윈도우를 컴퓨팅하는, 예시적인 SQL 스니핏 (snippet) 이 있다:
경고: width_bucket() 은 그 제 2 인수 (<min_value>) 보다 작거나 또는 그 제 3 인수 (<max_value>)) 보다 크거나 같은 모든 event_time 타임스탬프들을 각각 여기서 특수 언더플로우 및 오버플로우 버킷들 0 및 8 에 넣을 것이다. 따라서 데이터는 놀라운 결과들을 회피하기 위해 모든 타임스탬프들이 <min_value>, <max_value> 에 속하는 것을 보장하도록 필터링되어야 한다. width_bucket() 은 또한 텀블링 윈도우들에 리소스들을 할당하는데 사용될 수 있지만, 그것은 오직 바운드된 유효성 인터벌들; 즉, 알려진 최대 사이즈를 갖는 유효성 인터벌들에 대해서만 작동한다. 예를 들어, 각각의 리소스의 유효성 인터벌이 윈도우 기간보다 길 수 없음을 알고 있다면, 각각의 리소스는 많아야 2 윈도우들과 오버랩할 수 있다. 따라서 width_bucket() 함수만 2 번 호출한 후 union all 및 distinct 를 사용하여 복제물들을 없앨 수 있다. 그러나 일반적인 경우에, 각각의 리소스의 유효성 인터벌은 언바운드된 수의 윈도우들과 오버랩할 수도 있다. 따라서, 텀블링 윈도우들에 리소스들을 할당하는 일반적인 경우에, 템포럴 내부 조인이 필요하다.
그룹
윈도우들 내의 그룹화는 간단하다. 사용자가 입력 데이터를 컬럼 k 에 의해 그룹화하길 원한다고 가정한다. 각각의 윈도우 내에서 그룹화하기 위해, 윈도우 키에 의해 그룹화 키를 확장한다. 윈도우 키는 단순히 윈도우의 타임스탬프들의 valid_from, valid_to 쌍이다. 즉, group by k 는 group by valid_from, valid_to, k 가 된다.
소팅 및 집계
SQL 은 적어도 멘탈 모델의 명령적 형태가 아닌, 별도의 "소팅" 및 "집계" 단계들을 갖지 않는다. 대신에, 함수의 패밀리에 의존하여, 입력 순서를 특정하기 위한 상이한 서술적 신택스를 갖는, 상이한 패밀리들의 집계 함수들을 갖는다. 3 개의 패밀리들의 집계 함수들이 있다:
일부 함수들은 오버로드되고 다중 패밀리들에 속함에 유의한다. 예를 들어, sum 함수는 순서-애그노스틱 구현 뿐만 아니라 분석 구현 (이동 합) 양자 모두를 갖는다. 어느 구현이 호출되는지는 over 절이 특정되는지 여부에 의존하며, 이하에 분석 함수들 신택스를 참조한다.
순서-애그노스틱 집계 함수들
순서-애그노스틱 집계 함수들은 가장 단순한 패밀리의 함수들이다. 예들:
예시적인 쿼리:
이는 이전에 설명된 바와 같이, 윈도우 키가 group by 절의 부분인 집계이다.
순서-센서티브 집계 함수들
순서-센서티브 집계 함수들은, 함수가 그 입력을 보는 순서가 그 출력을 변경한다는 것을 제외하고, 레귤러 집계 함수들과 매우 유사하게 거동한다. 순서를 특정하기 위해, 호출자들은 함수 호출 뒤에 within group (order by ...) 절을 추가할 수도 있다. within group 이 특정되지 않으면, 순서는 정의되지 않지만, 쿼리는 여전히 작동할 것이다.
순서-센서티브 집계 함수들의 예들:
예: 각각의 로우가 컬럼들 c 및 d 를 갖는다고 가정한다. array_agg(c) 는, 사용자가 입력 로우들의 각각의 그룹 내에서 d 에 대하여 array_agg(c) 의 컨텐츠들을 소팅하길 원했다면 array_agg(c) within group (order by d) 이 될 것이다.
분석 함수들
분석 함수들은 매우 상이하다. 그들은 그룹 당 하나의 출력 로우를 반환하지 않는다. 대신에, 그들은 모든 입력 로우에 대해 하나의 출력 로우를 반환한다. 개념적으로, 그들이 집계, 그 다음에 그 집계의 결과를 다시 입력 테이블로 추후-플래트닝 (조인) 을 수행하는 것으로 볼 수 있다 (사실, 그것은 정확히 그들 대부분이 Snowflake 에서 구현되는 방법이다).
분석 함수들의 예들:
예를 들어, lag(c) over (partition by k order by d) 는 k 에 따라 현재 로우가 속하는 그룹 내에서 데이터를 d 에 의해 소팅함으로써 확립된 순서에 대하여 c 의 이전 값을 반환한다. 그러나 많은 경우들에서, 실제로 입력 테이블로 다시 플래트닝된 집계 값이 아닌 집계 값을 원한다. 예를 들어, 종종 "d 가 최대치인 c" 와 같은 것을 원한다. SQL 에서 이것을 표현하는 2 가지 방식들이 있다.
1. 원래의 입력 테이블과 집계된 입력 테이블 사이의 조인으로서, 명시적으로 min 또는 max 을 사용하거나, 또는 any 또는 all 을 사용함
2. 분석 함수를 사용함
어떤 솔루션이 더 빠른지는 예측하기 어렵다. 원하는 시맨틱들이 min 및 max 를 사용하여 표현될 수 있으면, 솔루션 (1) 이 보통 더 빠르다. Snowflake 는 소팅보다 해싱에 더 나으며, 따라서 groupt-by 및 조인은 분석 함수보다 더 빠를 가능성이 매우 높다. 그럼에도 불구하고, 먼저 솔루션 (2) 를 보는데, 그것이 이 섹션의 주요 주제이기 때문이다. within group 은 단순히 first_value 에 대한 유효한 신택스가 아니기 때문에, first_value(c) within group (order by d) group by k 를 기입할 수 없다. 그것은 순서-센서티브 집계 함수가 아닌 분석 함수이다. SQL 은 distinct 또는 any_value() 및 group by 를 사용하여 모든 리던던트 데이터를 명시적으로 폐기함으로써 플래트닝을 "실행취소 (undo)" 하도록 요구한다. "최소 d 에 대한 c" 를 컴퓨팅하는 예시적인 쿼리:
대안적으로는:
제 2 버전은 그 시맨틱들에 있어서 약간 더 명시적이고 그룹화 키에 first_value_c 를 추가하지 않기 때문에 약간 더 효율적이다 (valid_from, valid_to, k 로부터 first_value_c 로의 기능적 종속성이 있으므로, distinct 에 의해 실행된 바와 같이 그것을 그룹화 키에 추가하는 것은 리던던트이다). 부정적인 측면으로, 그것은 조금 더 장황하다. 양자의 버전들은 좋다. 양자의 쿼리들에 대한 쿼리 계획은 도 6 에 도시된다.
분석 함수들에 대한 대안: ALL 또는 MIN/MAX
여기에 first_value 없이, 단지 group-by 및 join 연산자들을 사용하는, 상기 쿼리 ("최소 d 에 대한 c") 를 표현하는 방법이 있다:
상기 쿼리는 all 키워드를 사용한다. 그것은 그 이름이 암시하는 것을 정확히 수행한다. 주어진 컨디션이 네스팅된 쿼리에 의해 반환된 "모든" 로우들에 대해 유지되면 참으로 변한다. 컴파일러는 where 절을 조인 술어로서 쉽게 인식하므로 (서브-쿼리는 컴파일러-식 표현에서 "상관됨"), 그것은 서브-쿼리를 조인으로 바꾼다. 메인 쿼리에서 any_value(c) 호출 및 group by valid_from, valid_to, k 가 차단됨에 유의한다. 그 부분을 생략할 수 있지만, 그러면 동일한 값 d (동점) 를 갖는 하나의 그룹에 2 개의 로우들이 있는 경우들에서 그룹 당 1 초과의 출력 로우를 보게 될 것이다. 동점들의 경우 이 중복은 원하거나 또는 원하지 않을 수도 있다. 쿼리 계획은 도 7 에 도시된다.
이 계획은 다소 놀랍다. Snowflake 는 서브-쿼리에서 d 의 최소치를 컴퓨팅하기 위해 그룹화된 집계를 수행하지 않는다. 대신에, 세컨더리 조인 술어로서 W1.D > W2.D 를 사용하여 보다 간단한 안티-조인을 수행한다. 그것은 최적의 계획일 수 있지만, 위험하다. 그룹들이 매우 크다면 (최악의 경우: 하나의 그룹을 갖는 하나의 윈도우), 조인은 세컨더리 조인 술어를 갖는 데카르트 곱이 된다. 점근적 비용: windowed_event 에서 m 개의 로우들의 경우 O(m^2). 최종적으로, 여기에 집계 및 셀프-조인을 수동으로 수행하는 이전 SQL2 방식이 있다:
쿼리 계획은 도 8 에 도시된다. 이 계획은 all 키워드에 대한 계획보다 약간 큰데, 안티-조인 대신 서브-쿼리를 갖는 내부 조인 및 group-by (Aggregate) 를 사용하기 때문이다. 그러나 그것은 큰 그룹들에 훨씬 더 강건하다. 내부 조인은 그룹의 다중 로우들이 동일한 최소 값 d 를 갖는 경우를 제외하고 효율적인 -1:1 해시-조인이다. 따라서 이 쿼리는 이전 쿼리의 안티-조인이 O(m^2) 에서 실행되지 않을 것을 보증하는 windowed_event 에 대해 신뢰가능한 통계를 갖지 않는 한 우세한 솔루션이다. 확신이 안 서면, 최악의 경우의 성능은 계획을 선택할 때 최상의 경우의 성능을 트럼핑한다. 다시, 마지막에 있는 group by valid_from, valid_to, k 부분은 원한다면 생략될 수 있다.
템포럴 데이터세트들의 스트림 프로세싱
이 문헌에서는, (데이터 모델에서 정의된 바와 같이) 이벤트들 및 리소스들과 같은 템포럴 데이터세트들에 대해 스트림 프로세싱을 수행하는 방법을 논의한다. 스트림 프로세싱은 (템포럴 관계형 연산들이라고도 알려진 APAL 에 의해 정의된) 변환의 입력 데이터세트(들)가 잠재적으로 언바운드될 수 있음을 의미한다. 이 문헌에서, 언바운드된 데이터세트를 단순히 데이터세트로서 지칭한다. (새로운 옵저베이션들을 계속해서 수집하는) 시스템의 본질 때문에, 모든 데이터세트들은 언바운드된 정의에 의한다. 윈도우-기반 스트림 프로세싱 (Google Dataflow) 은 이벤트들을 윈도우들에 맵핑하고 그 윈도우들에 대해 집계 연산들을 수행하기 위해 프레임워크를 정의한다. 모델은 매우 일반적이고 이하에 제안된 것은 그러한 프레임워크의 특수 경우로 볼 수 있다: 세미-오픈 윈도우 (우리의 시스템에서의 이벤트의 영향이 잠재적으로 무한히 지속될 수 있기 때문임) 및 윈도우에서 새롭게 컴퓨팅된 템포럴 데이터를 기존 데이터와 "스플라이싱" 하는 방식. 용어에 관한 노트: 이 문헌에서 용어 "데이터세트" 는 데이터세트의 논리적 정의 및 데이터세트의 가능한 구체화 양자 모두를 표시하기 위해 자유롭게 사용된다.
템포럴 업데이트들
스트림 프로세싱은 데이터세트에 대한 업데이트들을 주로 처리하고, 즉, 입력 데이터세트가 업데이트될 때, 스트리밍 프로세서는 변환 로직에 기초하여 그 출력들을 업데이트하는 방법을 알아낼 것이다. 입력 업데이트들을 출력 업데이트들에 맵핑 및 전파하는 방법을 결정하는 것은 스트리밍 프로세스의 효율성에 결정적이다. 종래에, 관계에 대한 업데이트들은 종종 로우들의 DML 동작들로서 설명된다 (예를 들어, 이 업데이트 내에서, 로우들 R1 및 R2 를 인서트했고, 로우 R3 을 삭제했고, 로우 R4 를 업데이트했다). 그러나, 템포럴 관계들 (예를 들어, 리소스들) 에 대한 업데이트들을 설명하기 위해 그러한 언어를 사용하는 것은 곤란하다. 예를 들어, "시간 t1 과 t2 사이에 리소스 R 의 상태 X 를 S 로 변경하는 것" 의 하이 레벨 업데이트는 로우 R1 의 valid_to 를 t1 로 수정하고, 로우 R2 의 valid_from 을 t2 로 수정하고, X=S 이고 valid from=t1 이고 valid_to=t2 인 새로운 로우를 인서트" 로서 설명될 것이다. 따라서, 템포럴 데이터세트에 대한 업데이트를 설명하는 새로운 방식이 필요하다. "시간 T 이후 (since time T)" 라고 불리는 단순한 것으로 시작한다: 시간 T 이후 업데이트는 모든 템포럴 관계들이 시간 T 전에 동일하게 유지되고 시간 T 이후 잠재적으로 변경되는 것을 의미한다. 다시 말해서, 시간 T 전의 모든 템포럴 상태들은 이 업데이트에 의해 영향을 받지 않는다. "이벤트" 데이터세트의 경우, "시간 T 이후" 업데이트는 timestamp < T 가 변경되지 않고 유지되는 모든 이벤트들을 단순히 의미한다. "리소스" 데이터세트는 각각의 로우가 일정 기간 동안의 상태를 설명하기 때문에 상이하다. 다음과 같이 리소스들에 대한 "시간 T 이후" 를 정의할 수 있다: 각각의 로우의 valid_to 를 그 valid_to > T 인 경우 (또는 널임) T 로 설정하면, 결과의 데이터세트는 변경되지 않고 유지된다. valid_to 를 많아야 T 인 것으로 설정하는 그러한 연산은 템포럴 절단으로 지칭될 수 있다. 리소스들에 대한 "시간 T 이후" 의 대안적인 정의는 각각의 로우를 이벤트로 취급하는 것이고 valid_from < T 인 모든 이벤트들은 변경되지 않고 유지됨에 유의한다. 그러한 정의는 업데이트의 영향을 과대평가할 수 있다. 예를 들어, 시간 10 에서 시작하는 컨테이너는 시간 1000 에서 다른 이벤트에 의해 업데이트된다. 개념적으로, 컨테이너의 상태는 시간 10 과 시간 1000 사이에 변경되지 않고 유지되지만, 상기 정의에 기초하여 업데이트 시간을 10 으로 설정해야 할 것이다 (그 이유는 로우가 기술적으로 1000 으로 설정된 valid_to 로 업데이트되기 때문이다). 결과적으로, 이 컨테이너에 의존하는 모든 다운스트림 변환들은 범위 [10, 1000) 에 대해 (불필요하게) 재컴퓨팅될 것이다.
템포럴 데이터세트들에 대한 "시간 T 이후" 업데이트의 상기 정의의 좋은 특성은 업데이트 임계치 T 가 대부분 관심을 갖는 변환들에 대해 계산 및 전파하기 매우 쉽다는 것이다. 이는 현재 파이프라인에서의 대부분의 변환들에 대해, T 전의 임의의 입력 상태 업데이트가 T 에서의 또는 그 후의 출력 상태에 단지 영향을 미칠 것이기 때문이다 (즉, "과거" 는 "미래" 에 의존하지 않는다). 결과적으로, 입력의 업데이트 임계치를 출력으로 직접 전파할 수 있다 (또는 다중 입력들이 있으면, 그들 임계치들 중 최소값을 선택한다). "과거" 가 "미래" 에 의존하게 만들기를 원하는 (예를 들어, 슬라이딩 윈도우 집계를 컴퓨팅하지만 윈도우의 시작 시간을 집계 결과에 대한 타임스탬프로서 사용하길 원하는) 경우들에서, 그것을 포워드로 전파할 때 임계치 T 로부터 시간 시프트를 뺄 수 있다. 사이드 노트: 업데이트 임계치와 워터마크 사이에 일부 관계가 있다. 변환의 워터마크는 본질적으로 그 입력 데이터세트들의 임의의 업데이트 임계치의 최종결과인데, 워터마크 전의 상태가 무엇이든 "실링된 (sealed)" 것으로 간주되고 더 이상 업데이트될 수 없기 때문이다.
템포럴 업데이트들의 스트림 프로세싱
"시간 T 이후" 업데이트들의 정의에 기초하여, 템포럴 데이터세트들의 스트림 프로세싱은 비교적 간단해진다. 하이 레벨에서, 우리의 스트림 프로세서 (스케줄러) 는 변환의 각각의 입력에 대한 업데이트들을 검출할 것이다. 업데이트가 검출될 때, 입력 데이터세트의 컨텐츠들 뿐만 아니라 그 업데이트 임계치를 사용하여 그 출력 데이터세트들을 업데이트할 뿐만 아니라 다운스트림 변환들에 대한 업데이트 임계치들을 생성할 것이다. 그러한 실행의 각각의 "라운드" 는 다음의 단계들을 수반할 것이다:
T_O 를 넘어선 출력 데이터세트들을 절단. 그러한 절단은 실제 로우들 대신에 템포럴 상태에 대해 동작한다는 의미에서 "템포럴 절단" 임에 유의한다. 예를 들어, 시간 T 를 넘어선 템포럴 절단은 valid_from=t1 (t1 < T) 및 valid_to=+Inf 인 로우를 valid_from=t1 및 valid_to=T 로 업데이트할 것이다.
T_O 이후 업데이트 데이터세트들에 대한 상태를 재컴퓨팅. 이 단계는 기본적으로 단지 입력 데이터세트들에 대해 APAL-컴파일링된 SQL들을 실행하는 것과 동일하다. 하나의 까다로운 양태는 T_O 에 기초하여 각각의 입력 데이터세트에 대한 그 판독 윈도우를 결정해야 한다는 것이다. 일부 되돌아봄 (look back) 윈도우는 "resourceify" 와 같은 변환의 템포럴 집계-타입을 위해 필요하다.
새롭게 재컴퓨팅된 상태를 절단된 상태와 병합. 이것은 템포럴 합집합 (레귤러 합집합 및 팩) 일 것이다. 합집합의 2 개의 부분들은 항상 시간 T_O 에 병합되기 때문에, 일부 최적화를 적용하고 어쩌면 특수 템포럴 "스플라이스" 연산을 가질 수 있다.
다양한 변환 타입들에 대해 이것이 작동하는 것을 쉽게 알 수 있다. 기본 이벤트 → 이벤트 변환: 업데이트에서 가장 이른 이벤트에 기초하여 출력을 절단하고 그 이후의 모든 이벤트들을 재컴퓨팅할 것이다. 이것은 이 타입의 변환에 가장 효율적인 프로세싱이 아닌데, 고유 row_id 를 쉽게 사용하여 개개의 로우 변경들을 추적하고 오직 변경된 것들만 프로세싱할 수 있기 때문이다. 이벤트 → 리소스로 룩업 → 이벤트 변환: 이것은 리소스로 이벤트를 "풍부하게 하길" 원할 때 일반적이다. 이를 통해, 업데이트된 시간 범위에 속하는 모든 이벤트들에 대해 조인을 재실행할 것이다. 이벤트 → "resourcify" → 리소스 변환: 비순차 이벤트 도달 없이, 이것은 새로운 리소스들을 재컴퓨팅하고 그들을 다시 기존 리소스들에 합한다. 비순차 도달로, 비순차가 발생한 이후의 모든 리소스들을 무효로 하고 앞으로 재컴퓨팅할 것이다. 리소스 → 다른 리소스로 룩업 → 리소스 변환: 이는 상기 제 2 경우와 유사하다.
백필링 및 비동기 프로세싱
상기 스트림 프로세싱 모델은 모든 변환들이 동시에 시작되므로 그들의 상태들이 항상 동기화됨을 가정한다. 고객이 변환들을 동적으로 추가/삭제하길 원하는 우리의 시스템의 경우와 마찬가지로, 이것은 분명히 비실용적이다. 따라서, 새롭게 추가된 변환들을 합리적인 방식으로 처리할 필요가 있다. 백필링 임계치로서 변환의 워터마크를 사용할 수 있는데, 워터마크는 사실상 "이 시점 전의 어떠한 업데이트도 신경쓰지 않음" 을 의미하기 때문이다. 따라서 백필링 임계치를 사용하여 변환의 워터마크를 부트스트랩할 수 있다. 다른 질문은, 변환이 추가될 때 어떻게 그 출력들의 상태를 부트스트립하고 그 입력들을 "따라잡게" 만드는지이다. 네이티브 방식은 업데이트 임계치를 시작 시간으로 설정하여 입력 당 "초기화 업데이트" 를 생성하는 것이다. 그 후, 제 1 실행 동안, 변환은 한번에 시작부터 모든 것을 재컴퓨팅할 것이다. 접근법의 불리한 면은 초기 실행이 매우 오래 걸릴 수도 있다는 것이다. 장기 실행 쿼리는 그 자체로 문제가 아니지만, 그 진행을 쉽게 확인할 수 없기 때문에, 사고들, 새로운 배치들, 기본적으로 스케줄러가 그러한 쿼리들의 상태를 손실하게 할 수도 있는 무언가에 취약할 수 있다. 다른 문제는 록킹이다. 이 변환이 실행되는 동안 업스트림 테이블을 록킹하는 것은 합리적이지 않지만, 동시에 (다중 SQL 문들을 포함할 수 있는) 변환을 통해 테이블의 일관된 뷰를 보장해야 한다. 그 솔루션은 변환이 (하한과 상한 양자 모두를 가진) 유한한 시간 범위 내에만 데이터를 프로세싱하도록 허용하는 것이다. 이런 방식으로 백필링 프로세스를 입력 데이터의 "청크" 를 각각 프로세싱하는 다중 변환 실행들로 분할하고 출력들이 서서히 입력들을 따라잡게 할 수 있다. 여기서 문제는 최종 일관성을 달성하기 위하여 업스트림 업데이트들 및 다운스트림 변환 실행들을 조정하는 것이다. 여기에 이를 달성하는 하나의 프로세스 (시간 범위 컬러링) 가 있다:
입력 데이터세트에 대한 컬러링 타임라인 및 버전 번호를 유지할 것이다. 컬러링 타임라인은 컬러링되든 아니든 (투명) 비-오버랩하는 범위들을 포함한다. 컬러링된 범위는 또한 특정 버전 번호와 연관되어야 한다.
업스트림이 데이터세트를 업데이트할 때, 먼저 데이터세트에 대한 버전 번호를 올린 후, 업데이트된 범위를 새로운 버전 번호로 컬러링할 것이다. 또한, 업데이트된 범위를 넘어서는 임의의 컬러링을 지울 것이다.
변환이 실행할 준비가 되면, 먼저 그 워터마크를 넘어서 가장 이른 컬러링된 영역을 로케이트할 것이다. 그 후 컬러링된 영역의 시작을 그 시작 시간으로 사용하고, 전체 블루 영역, 또는 그것의 부분을 실행한다. 영역은 상이한 버전들을 포함할 수도 있음에 유의한다. 데이터세트의 현재 버전 번호는 물론 영역을 기록할 것이다.
변환이 완료되면, 기록된 영역의 모든 또는 부분의 컬러링을 지울 것이다. 규칙은 1B 가 여전히 컬러링되고 2B 가 기록된 버전과 동일하거나 그보다 낮은 버전을 갖는 부분의 컬러만을 지울 것이라는 것이다.
이제 도 9a 내지 도 9e 를 참조하면, 예들은 작동 중인 프로세스를 도시한다. 특히 도 9a 를 참조하면, 먼저 업스트림은 시간 t0 과 t1 사이의 데이터세트를 업데이트했고, 그러한 시간 범위를 버전 1 로 마킹할 것이다.
이제 도 9b 를 참조하면, 업스트림은 시간 t2 와 t3 사이의 데이터세트를 다시 업데이트했다. 일부 비순차 도달 때문에, t2 < t1 이다. 그 후 시간 범위 [t2, t3) 를 더 새로운 버전 2 로 마킹할 것이다.
이제 도 9c 를 참조하면, 스케줄러는 변환 실행을 시작한다. 그것은 가장 이른 마킹된 시간 범위이기 때문에 프로세싱할 시간 범위의 시작 포인트로서 t0 을 선택한다. 그것은 그 후 t3 까지 내내 프로세싱하는 것은 너무 오래 걸릴 수도 있고 t4 까지만 프로세싱하기로 결정했기 때문에 종료 포인트로서 t4 ( t2 < t4 < t3) 를 선택한다. 실행 전에, 스케줄러는 또한 범위 [t0, t4) 및 현재 버전 (2) 를 기록한다.
이제 도 9d 를 참조하면, 변환이 실행되는 동안, 업스트림은 다시 범위 [t5, t6) 에 대한 데이터세트를 업데이트한다.
이제 도 9e 를 참조하면, 이제 변환이 완료된다. 변환이 영역 [t0, t4) 에 대해 실행중이었더라도, 스케줄러는 그것이 (버전 3 을 가진) 최근 업데이트된 데이터를 보지 못했기 때문에, 마킹된 영역 [t0, t5) 만을 지울 것이다.
입력 데이터세트에서 임의의 새롭게 업데이트된 범위가 가장 높은 버전 번호를 포함할 것이고 다운스트림 변환이 결국 그것을 프로세싱할 것이기 때문에 프로세스가 작동한다.
워터마크
워터마크는 매우 늦은 도달 데이터로부터 파이프라인을 보호하는 방식이다. 각각의 변환 (데이터세트가 아님) 은 그 워터마크 레벨을 추적해야 하고 업스트림으로부터의 임의의 업데이트 범위는 워터마크에 의해 왼쪽-트리밍되어야 (left-trimmed) 한다. 워터마크를 설정 및 업데이트하는 완벽한 방식은 없다. 합리적인 휴리스틱은 변환이 행해진 진행에 기초하여 워터마크를 설정하는 것이다. 예를 들어, 변환이 단지 t1 과 t2 사이의 범위를 업데이트하는 것을 완료했다면, 워터마크를 t2 - delta 로 설정할 수 있으며, 여기서 delta 는 비순차 도달의 허용오차이다.
시간 도메인
상기 프로세스는 어느 시간 도메인을 사용할지 (프로세싱 또는 이벤트) 에 관한 어떠한 가정도 행하지 않는다. 시간 도메인이 파이프라인을 통해 일관되는 한, 스트림 프로세싱 프로세스가 작동한다. 그러나, 고객이 파이프라인의 중간에 시간 도메인을 변경하는 것은 불합리하다. 예를 들어, 고객은 그 이벤트의 JSON 또는 텍스트 데이터 내부에서 더 정확한 시간 필드를 발견하고 이벤트 시간을 그것으로 대체하기로 결정할 수도 있다. UI 가 이것을 처리할 방식은 불분명하지만, 스트림 프로세싱 프로세스는 각각의 변환이 하나의 일관된 시간 도메인에 있는 한 이것을 처리할 수 있다. 2 개의 인접한 변환들이 상이한 시간 도메인들을 갖는 것은 괜찮다. 트릭은 업데이트 범위가 2 개의 변환들 사이에 전파될 때 시간 도메인들 사이의 업데이트 범위들을 변환하는 것이다. 변환은 추가적인 비용을 발생할 것이므로 (적어도 업데이트된 범위에 대해 테이블을 스캔해야 할 가능성이 가장 높기 때문), 시간 도메인 변경들을 위해 그 경우를 제한하는 것이 더 나을 수도 있다.
최적화들
리소스별 업데이트 임계치들.
논의
윈도우-기반 스트림 프로세싱 (예를 들어, Dataflow) 과 어떤 관계인가? 윈도우-기반 스트림 프로세싱은 하나의 특정 타입의 스트림 프로세싱, 즉 템포럴 집계를 처리한다. 그 가정은 이벤트의 영향이 하나 이상의 유한한 시간 윈도우들 내에서 제한된다는 것이다. 우리의 가정은 이벤트의 영향이 유한한 윈도우들 내에서 제한되지 않을 수도 있지만 이벤트의 시간 이후 모든 상태에 잠재적으로 영향을 미칠 수 있다는 것이다. 결과적으로, 우리의 프로세스는 더 일반적이지만, 템포럴 집계를 처리하면 윈도우된 프로세스에 비해 덜 효율적일 것이다. 이벤트의 영향이 유한하다고 가정하면 프로세스를 추가로 최적화할 수 있는 방법은 미결 문제이다. 증분적으로 후방 백필링? 슬프게도 이 모델의 경우 후방 백필링이 불가능하다. 시간 범위의 앞에 추가된 임의의 새로운 데이터는 모든 이전에 컴퓨팅된 상태를 무효화할 것이다. 좋은 소식은, 비동기 프로세싱으로 백필링 목표가 각각 상이한 동일한 데이터세트에 대해 다중 테이블들을 구체화할 수 있다는 것이다. 비-템포럴 데이터세트 업데이트들? 비-템포럴 데이터세트는 유효성 기간 (-Inf, +Inf) 을 갖는 템포럴 데이터세트와 등가이며, 따라서 그 변경은 그 범위 (-Inf, +Inf) 의 업데이트를 트리거링할 것이다. 각각의 변환은 그 후 그 워터마크로부터 시작하는 그 출력을 재컴퓨팅할 것이며, 업데이트 범위가 [Watermark, +Inf) 로 왼쪽-트리밍되기 때문이다.
템포럴 관계형 대수로부터의 엔티티 모델 분리에 기초한 구현 결정들
"인터벌 시간 테이블" 의 개념이 "리소스 테이블" 의 개념보다 약한 것을 고려하면, 양자 모두를 구현하는데 있어서 예시적인 실시형태의 플랫폼의 피스들의 역할이 무엇인지를 명확하게 해야 한다. 실제로, 예시적인 실시형태의 적용을 구현할지에 대한 견고한 이론적 기반으로서 템포럴 관계형 대수를 구축한다. 이 때문에, 사용자 인터페이스, 및 사용자들이 예시적인 실시형태와 상호작용하는 방식은 엔티티 모델 위에 놓인 워크플로우들에 대해 주로 최적화되어야 한다. 그것은 또한 사용자들이 그들 스스로 정규 형태가 아닌 중간 결과들을 매우 잘 알게 될 수도 있는 경우이며, UI 및 툴들은 이러한 경우들에 (근본적인 이론에 의해 알려진) 합리적인 뭔가를 해야 한다. 이를 구축하기 위해 2 개의 가능한 접근법들이 있다. 그들을 빠르게 비교하기 위해, 접근법 A 는 "엄격한 계층화" 모델이고, 접근법 B 는 "통합된 계층들" 모델이다.
엄격한 계층들
이제 도 10 을 참조하면, 이것은 기존 템포럴 관계형 데이터베이스 위에 예시적인 실시형태를 구축했다면 취해질 접근법이다. 엔티티 모델은 템포럴 대수의 관점에서 정의되고, 템포럴 대수는 차례로 SQL 의 설정된 관계형 대수 위에 구현된다. 사용자들은 결국 정규 형태가 아닌 일부 데이터세트들을 가지게 될 것이기 때문에, 엔티티 모델은 근본적인 관계형 대수의 능력들을 포괄해야 한다.
통합된 계층들
이제 도 11 을 참조하면, 이 모델은 엔티티 모델이 템포럴 관계형 대수를 포괄하고, 또한 정규 형태에 따르는 데이터세트들로 작동할 때 추가적인 기능을 제공한다는 것을 인식한다. 따라서, 예시적인 실시형태는 템포럴 관계형 모델을 서브세트로서 포함하는 플랫폼 모델을 구현하는 단일의 단일화된 계층을 구축한다.
인수들
엄격한 계층들 모델은 다량의 리던던트 컴퓨테이션을 요구한다. 엔티티 모델이 템포럴 관계형 대수의 관점에서 정의되기 때문에, "엔티티들" 계층은 모든 템포럴 대수 도출을 행하여, 출력들의 형태를 이해하는 것을 보장한 후, 방향을 바꾸어 다시 모두 동일한 것들을 행할 "템포럴 대수" 계층에 통신해야 할 것이다. 추가적으로, 예시적인 실시형태의 계층이 모든 방식을 SQL (관계형) 계층에 이르기까지 통신하게 되면 보다 효과적으로 표현될 수 있는 정규 형태들에 대한 최적화들이 있다. 좋은 비유는 SQL 언어의 깔대기를 통해 우리의 의도를 표현할 필요 없이, 그들의 근본적인 쿼리 실행 계획에 액세스했다면 Snowflake 위에서 더 잘 할 수 있음을 이미 알고 있는 경우들이다. 또한, 템포럴 계층이 예시적인 실시형태의 계층에 의해 완전히 숨겨져 있다고 말하면 문제가 있다; 사용자는 반드시 정규 형태는 아닌 템포럴 형태를 갖는 데이터세트들을 가지게 될 것이며, UI 는 그것들로 합리적인 뭔가를 해야 하며, 이는 예시적인 실시형태의 계층이 템포럴 계층의 풀 수퍼세트가 될 것임을 표시한다. 엔티티 모델을 지원하기 위해, OPAL 동사 구현들은 그들이 그들의 업스트림 입력들을 그들의 다운스트림 출력들로 변환하고 매칭하도록 데이터 변환에 따르는 스키마를 변환하는 방법을 알고 있다. 스키마는 "정의된 외래 키들" 과 같은 것들을 포함하기 때문에, 동사들은 엔티티 모델의 더 큰 컨텍스트에서 그들의 변환들이 무엇을 의미하는지 알아야 한다. 이러한 인수들은 함께, 통합된 계층들 접근법이 예시적인 실시형태에 대한 더 나은 결과로 이어진다는 것을 표시한다 - 본질적으로, 예시적인 실시형태 UI 및 플랫폼은 엔티티 모델을 구현하고, 이는 템포럴 관계형 모델의 수퍼세트이다.
구현
OPAL 동사 구현들은 데이터세트들의 사용자 데이터를 프로세싱하기 위한 SQL 을 구현하는 것에 더하여 그들의 데이터세트들의 메타데이터를 프로세싱할 것이다. 이는 "조인" 과 같은 명목상 "순수 템포럴 대수" 동사가 조인된 데이터세트에 대한 예시적인 실시형태의 스키마를 업데이트하는 방법을 알아야 할 것이지만, 내재적으로는 단지 더 낮은 레벨의 대수 구축 블록일 뿐임을 의미한다. 이것은 견고한 이론 토대를 갖기 위해 여전히 기본 템포럴 대수 구축 블록들을 구축하게 하면서, 전체 플랫폼이 그 목적을 서빙하게 만드는데 필요한 타협이다. 이것은 "단지" 순수 템포럴 관계형 대수 구축 블록이더라도, 임의의 OPAL 동사의 사양의 필요한 부분이 프로세싱된 데이터세트(들)의 엔티티 모델 스키마에 영향을 미치는 방법의 사양임을 의미한다. 소정의 OPAL 동사들은 그들이 정규 형태 입력들로 프리젠팅될 때 최선으로, 또는 유일하게 작동할 것이다. 이러한 동사들은 적절한 정규 형태에 있는 것으로 알려지지 않은 입력에 사용되도록 시도되었다면 에러를 생성할 것이다. 이것은 사용자 인터페이스 및 "하이 레벨" 커맨드 라인/API 액세스에 쉽고 편리한 레일들 내에 머무르게 하는데 필요한 타협이다. 기본적인 템포럴 대수의 기본 연산자들을 구현하는 것을 고려하면, 그들이 실제로 가드 레일들 밖에 머물길 원한다면, 사용자가 의도한 것을 달성하는 다른 방식들이 있다; 엔티티 모델 특정 동사들은 편리한 매크로들로 생각되어야 한다. 데이터의 바람직한 물리적 형태들을 재도출하는 연산들이 필요할 것이다. 연산들은 "팩킹", 및 "인터벌 정규 형태 집계", 및 다른 유사한 형태들을 포함할 수도 있다. 완전히 형성되지 않은 데이터로부터 이러한 형태들을 도출하는 것은 일반적으로 고가의 연산일 것이므로, 업스트림 입력들로부터 형태들의 준수 정도에 관한 메타데이터를 캐리하는 것은 구현을 상당히 최적화하도록 허용할 수도 있다. 추가적으로, 그들이 "실제로 필요할" 때까지 소정의 연산들 (팩킹과 같음) 을 연기하도록 선택할 수 있는 충분히 풍부한 메타데이터를 캐리하는 것은 또한, 생성된 쿼리를 최적화하도록 허용할 것이다.
시간 윈도우들
모든 쿼리는 일부 "시간 윈도우" 의 컨텍스트에서 실행된다. 이 "시간 윈도우" 는 쿼리의 출력의 관심 시간 범위를 결정한다 - 그것은 SQL 에서 offset 및 limit 의 템포럴 형태와 같다. 시간에 있어서 선형인 함수들의 경우, 함수가 판독하는 시간 윈도우, 및 함수가 기입하는 시간 윈도우는 등가이다. 따라서, 입력 측에 select 를 통해 출력 윈도우를 필터에 카피함으로써 많은 데이터 소싱 연산자들을 최적화할 수 있다 (이는 with t_0 as select * from some_table where ifnull(valid_from, left) < right and ifnull(valid_to, right) > left 와 같이 보임). 시간 개념을 시프트하는 함수들 - "1 주일 전과 비교" - 의 경우, 필요로 하는 데이터를 얻을 수 있도록 판독한 윈도우의 사이즈를 확장해야 한다. 윈도우 시프트가 고정된 시간량이면, 윈도우를 그 정도까지 확장 (그리고 어쩌면 그 경우에 오른쪽 에지도 이동) 할 수 있다. 로우들의 수를 시프트하는 함수들의 경우, 필요한 수의 로우들을 캡처하는데 얼마나 많은 시간이 필요한지 알지 못하기 때문에, 이것은 더 어렵다. 리소스들에 대한 보수적인 추정치는 "리소스 수명 타임아웃, 곱하기 요청된 로우들의 수" 이다. 추가적으로, 시간을 시프트하는 함수들의 구현들은 관심 윈도우 외부의 로우들에 기초하여 생성되는 출력 로우들을 필터링해야 한다. 일 예가 이하에 도시된다.
이러한 "일일 수익" 의 입력 데이터를 갖고, 테이블이 일일 수익 컬럼에 대해 하나의 값을 갖는 리소스 테이블임을 가정한다:
이 테이블에 기초하면, 08_14 과 08_20 사이 ("이번주") 의 수익을 볼 수 있다. 예는 도 12 및 이하에 도시된다.
또한 08_07 과 08_13 사이의 지난 주 동안의 수익을 볼 수 있다. 예는 도 13 및 이하에 도시된다.
최종적으로, 이번주 수익을 지난 주 수익과 비교할 수 있다. 예는 도 14 및 이하에 도시된다.
결론
이 예로부터 다음이 분명해야 한다;
1. (GraphQL 에서 QueryParams 로 변하는) GUI 의 시간 윈도우는 "관심 시간" 이며 따라서 맨 아래의 시간 스탬프 값들을 결정한다.
2. 쿼리는, 1_주일_전 (one_week_ago) 대 수익의 비교를 정확히 출력하기 위해, QueryParams 시간 윈도우 외부의 데이터를 판독해야 한다.
3. 1_주일_전 시리즈에 대한 데이터 포인트들에 대한 타임 스탬프는 현재 주의 것들이다 - 샘플 포인트들은 "이 날짜 (이를 테면 20 일) 에, 1 주일 전 값은 150 이었음" 을 표시한다. 이것은 "13 일에, 그 값은 150 이었음" 을 알 수 있는 이전 그래프와 미묘하게 상이하다.
로우 기반 오프셋들
소정의 값들의 경우, "로우 기반 오프셋" 은 "시간 기반 오프셋" 보다 더 의미있을 수도 있다. 하나의 예는 누적 카운터를 레이트로 변환하는 것이다 - 각각의 새로운 데이터 포인트의 경우, 이전 데이터 포인트의 값을 빼고 이전 데이터 포인트 이후의 시간으로 나눈다. 이것의 문제는, 특정 시간 범위와의 대화형 쿼리들, 및 반드시 증분적인 변환 프로세싱 양자 모두에 대해 문제가 되는 "이전 값" 을 찾기 위해 어디까지 되돌아보아야 하는지 알지 못한다는 것이다. 우리가 잠재적으로 시작 시간을 되돌아보는 것을 마다하지 않는 한, 이 문제를 처리할 3 개의 가능한 방식들이 있다:
1. 각각의 이벤트에 대해, 이전 이벤트의 시간을 동일한 키로 출력한다. 먼저 프로세싱된 이벤트 세트에서 가장 이른 "이전-이벤트 시간" 을 선택한 후 모든 필요한 데이터가 포함된 제 2 선택을 실행하게 한다. 이것은 추가 이벤트들에서 출력할 수 있도록 어딘가에 "키에 의한 이전 시간" 을 저장해야 한다는 문제, 및 그 데이터에 대해 2 번의 패스들을 실행해야 한다는 문제를 갖는다.
2. 각각의 쿼리에 대해, 입력 윈도우에 의해 필터링하고, 이전 로우를 갖지 않기 때문에 제 1 출력 이벤트가 레이트에 대해 "null" 을 가질 것임을 수락한다. 하루 또는 일주일을 커버하는 대화형 쿼리의 경우, 이것이 괜찮을 수도 있다. 변환 쿼리의 경우에는, 이것이 더 문제가 된다.
3. 각각의 쿼리에 대해, 사용자는 그들이 어디까지 되돌아보길 원하는지를 특정하게 한다. 이것은 lag() 연산자 - lag("1 day", 1, the_value) - 내부에 있을 수 있거나, 또는 그것은 리소스 타입들에 대한 정의된 "타임아웃 수명" 과 같은, 쿼리되는 데이터 세트의 내재적 특성일 수 있다. 이것은 정확한 값을 전달해야 할 때에 대한 레이트가 "리셋" 으로 예상될 때에 대한 코히어런트 규칙들을 사용자가 확립하게 한다. 결점은 "하루" 의 되돌아봄은 10-20 초의 증분적 ETL 프로세싱 윈도우에 비해 매우 길 수도 있으므로, 최소한도로, 되돌아봄의 크기에 대한 일부 가이던스가 필요하다는 것이다.
메트릭 데이터 - 동기
예시적인 실시형태는 데이터의 상이한 형상들 주위에 하드 경계들을 그리지 않는다. 이벤트들, 리소스들, 메트릭들, 트레이스들 등은 모두 포인트 테이블들 및 인터벌 테이블들로 요약되며, OPAL 및 템포럴-관계형 대수를 사용하여 자유롭게 결합될 수 있다. 그럼에도 불구하고, 플랫폼 레벨에서 액세스 패턴들로 트랜슬레이트하는 상이한 클래스들의 데이터 및 그들의 사용 경우들을 식별하는 것은 사용자 경험 및 성능 해킹 최적화들에 유용하다. 기존 시스템들 및 문헌에서, 메트릭 데이터는 종래에 다음으로 구성된다:
알 수 있는 바와 같이, 그러한 데이터는 단지 이벤트들의 특수 경우일 뿐이다. 종래의 메트릭 데이터는 PROMETHEUS_EVENT 데이터세트에 의해 입증된 바와 같이, 이벤트 데이터세트들에 쉽게 저장될 수 있다. 기존 OPAL 신택스 및 데이터 모델은 이벤트 데이터세트들의 임의 필터링, 그룹화, 집계를 이미 지원한다. 플랫폼에 대한 변경들 또는 확장들을 요구하는 메트릭 데이터에 관한 것은 전혀 없다. 따라서, 이벤트 데이터를 더 제한적인 포맷으로 강제할 필요가 없고, 단독으로 사용자들이 그러한 포맷으로 그들의 데이터를 사전 모델링하도록 강제하게 한다. 그것은 우리의 제품 스토리에 아주 좋다. 그런데도, 메트릭 데이터는 통상적으로 불륨이 높고, 사용자들은 최적화된 스토리지 및 프로세싱을 요구할 수도 있는 프레쉬니스 및 레이턴시 예상들을 갖는다.
메트릭들 대 리소스들
리소스들에 대하여, 메트릭 데이터의 2 개의 클래스들을 식별할 수 있다:
1. 단일 리소스들에 관한 메트릭들: 머신의 메모리 사용량, 머신의 CPU 사용량, 네트워크 인터페이스에 의해 전송된 네트워크 바이트들 등
2. 리소스들의 세트들에 관한 메트릭들: 클러스터의 노드들의 수, 동시 트랜잭션들의 수, 배치의 평균 메모리 사용량 등
데이터의 제 2 클래스는 분명히 데이터의 제 1 클래스의 집계이다. 즉, 데이터의 제 1 클래스는 종종 센서들에서의 샘플링 및 보간 아티팩트들 (어쨌든 "현재" CPU 사용량) 로 인해 물론 집계 형태로만 이용가능하다. 데이터의 제 2 클래스를 컴퓨팅 및 변환하는 것은 표현적인 쿼리 언어 및 능란한 UI 를 제공하는 문제이다. 사용자들이 가장 관심을 가지는 컴퓨테이션들에 대한 변환들을 선언 가능할 경로에 있으며, UI, OPAL, 및 Snowflake 의 분석 능력들의 조합은 적어도 최신 기술의 경험을 제공해야 한다. 데이터의 제 1 클래스는 최신 기술을 넘어 혁신할 기회가 있는 곳이다. 우리가 일찍이 행한 하나의 옵저베이션은 그러한 데이터가 리소스의 고속 상태로서 뷰잉될 수 있다는 것이다. 메트릭들은 보통의 필드들이 된다. 예를 들어, NODE 리소스는 MEMORY_USAGE 필드를 갖는다. 메트릭 필드들은 그 후 마치 임의의 다른 필드와 같이 쿼리될 수 있다. 프리젠테이션을 위해, 그들은 리소스 랜딩 페이지들에서 내장된 시간 시리즈들로 롤업된다. 미래에, 그들은 더 많은 매력적인 위젯들로 분류될 수도 있지만, 근본적인 통합된 데이터 모델은 매우 유용하고 유지되어야 한다. 그것은 예시적인 실시형태의 비전의 핵심인 로그들, 메트릭들, 트레이싱 (모니터링) 및 리소스들 (비즈니스 엔티티) 데이터의 통합을 주도한다 (강력하고 편리하지만, 이 접근법은 다수의 성능 문제들을 생성하였다). 약간의 쉽게 해결할 수 있는 방법이 남겨져 있지만, 많은 최적화들은 전적으로 리소스 테이블들과 메트릭 테이블들의 물리적 분리에 달려 있다. 우리의 Snowflake 데이터 모델의 보통의 필드들로서 메트릭 필드들을 처리하는 대신, 메트릭 필드들은 별도의 테이블들에 유지되고 요구에 따라 그들의 관련 리소스 테이블들과 조인되어야 한다.
많은 메트릭들의 처리
실제로, 단일 리소스는 그와 연관된 많은 수의 메트릭들을 가질 수도 있다. 예를 들어, 일부 분산된 애플리케이션의 Node 리소스는 memory_usage 와 같은 인프라구조-레벨 메트릭들로부터 transaction_count 및 commit_retry_count 와 같은 애플리케이션레벨 메트릭들까지 모두 가질 수도 있다. 리소스를 볼 때마다 모든 이러한 메트릭들을 쿼리 및 시각화하는 것은 비실용적이고 비현실적이다. 그 이유만으로, 적어도 옵션으로서, 리소스 데이터와 메트릭 데이터의 물리적 분리가 필요하다. 아직 기존 데이터세트들에서는 "많은 메트릭들" 이슈에 이르지 않았지만, 오늘날 메트릭 제품들이 사용되는 방식에 분명히 존재한다. 따라서 임의의 메트릭 솔루션은 그것을 고려해야 한다.
메트릭 정규화 및 스토리지
정규화 (normalization) 는 여기서 아티팩트-프리 및 관련 데이터 (리소스들) 와의 효율적인 조인들의 목적들을 위해 메트릭 데이터를 시스템적인 방식으로 파티셔닝 및 변환하는 액트를 지칭한다. 메트릭 데이터는 통상적으로 PROMETHEUS_EVENT 또는 ZIPKIN_SPAN 과 같은 "런드리 바스켓 (laundry basket)" 에서 비롯된다. 이러한 데이터세트들의 개개의 로우들은 많은 상이한 메트릭들을 포함할 수도 있으며, 그 각각은 변형 필드들 AJSONB 내부에 네스팅된 외래 키들을 통해 식별되는 다중 리소스들과 관련될 수도 있다. 사용자들이 런드리 바스켓 데이터세트들 내부에서 이러한 메트릭들을 발견한 후, 그들을 기존 리소스에 추가 (또는 필요하다면 먼저 리소스를 생성) 하는 "resourcify" UI 플로우를 가정한다. 그러면 질문은 리소스의 메트릭 필드를 구체화하는 방법이 된다. 여러 옵션들이 떠오른다.
1. 임의의 다른 상태 필드와 같이 메트릭 필드들을 처리. 즉, 리소스 테이블에 상태 컬럼을 생성하고 일부 변환의 부분으로서 모든 관련 메트릭 이벤트에 대한 리소스 로우를 생성한다.
2. 아무것도 구체화하지 않음. 필요할 때마다 런드리 바스켓 이벤트 테이블을 단순히 쿼리한다.
3. 각각의 리소스의 각각의 메트릭 필드에 대해 하나의 메트릭 테이블을 구체화 (최대 정규화).
4. 각각의 리소스에 대해 하나의 메트릭 테이블을 구체화, 리소스의 메트릭 필드들 간에 테이블을 공유.
1. 임의의 다른 상태 필드와 같이 메트릭 필드들을 처리
솔루션 (1) 은 오늘날 우리가 있는 곳이다. 저속 내지 중속 메트릭들에 대해서는 정상적으로 작동하지만, 실제로 고속 메트릭들에 대한 리소스 테이블들을 블로우 업하여, 높은 스토리지 오버헤드들 및 실행 오버헤드들을 초래한다. 스토리지 오버헤드는 (한다 하더라도 훨씬 더 낮은 레이트로 변경되는) 나머지 리소스 필드들을 반복하는 것에서 비롯된다. 실행 오버헤드는 런타임 시에 이 리던던 데이터를 힘들게 읽고 팩킹해야 하는 것에서 비롯된다. 특히, 이 접근법은, 순전히 개개의 메트릭들의 제품에 의해 생성된 원자 상태들의 수 때문에, "많은 메트릭들" 경우에 실패할 것이다. 실제로 리소스 테이블들이 작아서, 빠르게 페치, 조인, 및 팩킹하길 원한다.
2. 아무것도 구체하지 않음
솔루션 (2) 는 매우 수동적인 형태이지만, 오늘날 이용가능하다. 이미 리소스들을 관련 이벤트들과 조인한 후 원하는 대로 이러한 이벤트들을 집계 및 시각화할 수 있다. 아직 할 일은 리소스 정의에서 이러한 조인들을 기억하고 그들을 원할 때 자동으로 그리고 투명하게 수행하는 것이다. 솔루션 (2) 에는 2 가지 이슈들이 있다:
판독 증폭 (read amplification). 런드리 바스켓 테이블은 통상적으로 많은 미관련 데이터를 포함한다. PROMETHEUS_EVENT 는 극단적인 예이다. 다양한 런드리 바스켓 로우들은 그들을 또한 압축하기 어렵게 만들어, 판독 증폭 문제가 복잡해진다.
쿼리 복잡성. 리소스-투-이벤트 조인을 수행할 뿐만 아니라 (정규화된 데이터의 경우 그만큼은 피할 수 없다), 메트릭 추출 그 자체는 약간 복잡한 쿼리일 수도 있어서, 메트릭 필드가 컴퓨팅될 때마다 컴파일 시간 및 실행 시간을 끌어올릴 수도 있다.
3. 메트릭 필드 당 하나의 메트릭 테이블을 구체화
솔루션 스펙트럼의 다른 극단에서, 리소스의 각각의 메트릭 필드에 대해 별도의 Snowflake 테이블을 생성할 수도 있다. 결과의 메트릭 테이블들은 고도로 정규화된다. 각각의 로우는 다음을 포함한다:
그러한 메트릭 테이블의 압축률을 원래의 "런드리 바스켓" 이벤트 테이블과 비교해 본다. 상수 필드들 (이를 테면 메트릭 이름) 은 압축되지 않거나 또는 완전히 드롭될 수 있다. 타임스탬프들은 더 잘 압축하고 더 나은 상관 (클러스터링) 을 보여야 하는데, 동일한 메트릭의 데이터 포인트들이 상이한 메트릭들의 데이터 포인트들보다 도달 시간이 더 상관될 가능성이 높기 때문이다. 외래 키들은 모두 동일한 리소스 테이블을 지칭하므로, JSON 대신에 플레인 SQL 타입들을 사용할 수 있다. 따라서 외래 키들은 더 압축가능해지고 프루닝 및 조인하기 더 쉬워진다. 값들은 더 잘 압축되는데, 동일한 메트릭의 값들은 동일한 도메인 및 범위에 속하는 경향이 있기 때문이다. 태그들은 유사하게 거동한다. 따라서 전반적으로, 그러한 메트릭 테이블은 원래의 런드리 바스켓 테이블보다 훨씬 더 잘 압축하고 더 효율적으로 실행되어야 한다. 솔루션 (3) 은, 원하는 메트릭 데이터세트로의 런드리 바스켓 데이터세트의 변환을 수동으로 선언함으로써, 솔루션 (2) 를 통해 에뮬레이팅될 수 있음에 유의한다. 따라서, 어떤 의미에서, 이 전체 논의는 사용자가 메트릭 필드를 리소스에 추가하길 원할 때 자동으로 그리고 내부적으로 (under the hood) 무엇을 행할지에 관한 것이다.
4. 리소스 당 하나의 메트릭 테이블을 구체화
최종적으로, 솔루션 (2) 와 솔루션 (3) 사이의 절충안을 선택할 수 있다. 메트릭 테이블은 다중 메트릭 필드들 (효과적으로 솔루션 (2) 테이블들의 합집합) 을 포함할 수도 있다. 결과적으로, 이들은 판독 증폭 (쿼리들이 항상 모든 메트릭 필드들을 필요로 하는 것은 아니다) 및 압축률의 희생으로 관리할 테이블들이 더 적을 것이다. 판독 증폭 및 압축률은 별도로 하고, Snowflake 는 스캔들의 공유에 별로 좋지 않다. 즉, 입력 테이블이 단일 쿼리에서 다중 회 사용될 때, 일반적으로 그 테이블을 다중 회 - 쿼리중인 메트릭 당 한번씩 스캔할 것이다. Snowflake 가 단지 단일 스캔을 수행하기로 결정한 경우에도, 스캔의 다중 출력들은 계획 중 어느 때에 스플리팅 및 버퍼링되어야 할 것이고, 이는 메모리 및 CPU 오버헤드를 추가한다. 따라서, 실행 비용의 관점에서, 각각의 메트릭을 그 자신의 테이블에 유지하는 것은 항상 바람직하며, 따라서 각각의 스캔은 필요한 데이터를 정확히 판독할 것이다. 솔루션 (3) 은 실행 비용에 있어서 단연 우수하다. 솔루션 (4) 는 Snowflake 컴파일러가 더 적은 메타데이터를 필요로 하기 때문에, 컴파일 비용의 관점에서 이점들을 가질 수도 있다. 그러나 메트릭 데이터에 대한 볼륨 문제를 고려할 때, 실행 비용을 최적화하는 것이 더 신중한 선택이다. 솔루션 (3) 은 대부분의 경우들에서 솔루션 (4) 보다 우수해야 한다. 즉, 솔루션 (4) 는, 드물게 사용되는 메트릭들의 "롱 테일 (long tail)" 이 있는, "많은 메트릭들" 경우에서 실행가능한 최적화일 수도 있다. 그 메트릭들의 각각에 대해 별도의 테이블을 생성 및 유지하는 대신, 그 메트릭들을 단일 테이블로 통합함으로써 변환 오버헤드를 줄일 수도 있다. 솔루션 (3) 과 마찬가지로, 솔루션 (4) 는 솔루션 (2) 를 통해 에뮬레이팅될 수 있음에 유의한다.
리소스들과의 메트릭들의 조인
메인 리소스 테이블 밖으로 그리고 별도의 메트릭 테이블들 안으로 메트릭 필드들을 이동시키는 것은 쿼리 시간에 이러한 테이블들을 조인할 필요성을 생성한다. 조인 술어는 다음으로 구성된다:
불행히도, 어느 술어도 그것만으로 모든 경우들에 고도로 선택적인 것으로 보장되지 않는다. 리소스가 빈번한 상태 변경들을 가지면, 임의의 단일 리소스 키에 대한 리소스 테이블에 많은 로우들이 있을 수도 있다. 반대로, 리소스가 오래 지속되고 상태 변경들을 갖지 않으면, 많은 (모든) 메트릭 로우들은 동일한 리소스 로우에 매칭할 수도 있다. 강건한 조인 성능을 위해, Snowflake 가 (세컨더리가 아닌) 프라이머리 균등 술어로 밴드-조인을 수행하는 것이 필수적이다. Snowflake 컴파일러는 현재 그렇게 하지 않는다 (균등 술어가 있으면 point-in-range 술어를 무시한다). 현재 (메트릭들 외에) 상태 변경들이 많은 리소스들을 갖지 않으므로, 우선은 그 문제를 무시하고 Snowflake 측의 개선들을 대기하도록 선택할 수도 있다.
조인의 회피
많은 경우들에서, 훨씬 더 단순한 조인을 수행함으로써, 또는 실제로 조인을 전혀 수행하지 않음으로써 상기 설명된 문제를 회피할 수 있다. 리소스 랜딩 페이지를 가져온다. 메트릭 필드들은 레귤러 필드들과 함께 디스플레이되지만, 사용자들은 메트릭 데이터 포인트가 어느 특정 리소스 상태에 속하는지에 관심이 없다. 특정 리소스 인스턴스와 함께 메트릭들을 디스플레이하기 위해, 리소스 키 상의 메트릭 테이블을 조인 (그리고 쿼리 시간 범위에 이르기까지 조인 입력을 필터링) 하는 것으로 충분하다. 실제로, 단지 스크린 상에 있는 리소스 인스턴스들의 메트릭 로우들만을 판독 및 집계하는 것으로 충분하다. 스크린 상의 리소스 키들의 세트가 상수로서 메트릭 쿼리로 전달되면, 실제 조인은 전혀 필요하지 않다. 조인은 내부적으로 레귤러 조인과 유사한 해시 테이블을 사용하는 IN 술어가 되지만, 컴파일 및 실행이 훨씬 더 간단해진다. 단지 사용자가 메트릭들을 레귤러 필드로 취급하길 원하거나, 또는 리소스 테이블에서 확인되는 레귤러 필드들에 의해 메트릭 데이터를 그룹화 및 집계하길 원하는 경우에만, 플랫폼은 적절한 템포럴 조인을 수행할 필요가 있다.
다중 리소스들에 대한 메트릭들
메트릭들과 리소스들 사이의 관계는 항상 그렇게 분명하지는 않다. 예를 들어, transaction_count 메트릭은 애플리케이션 Node, 물리적 Host, Customer, 또는 인프라구조 또는 애플리케이션의 임의의 다른 세그먼트와 관련될 수도 있다. 이것은, 이벤트 또는 메트릭 포인트가 그와 연관된 많은 태그들 및 차원들을 가질 수도 있는, "카디널리티 문제 (cardinality problem)" 와 관련된다. 태그와 리소스 사이에 분명한 구별이 없으며, 태그들 및 리소스들은 임의의 온톨로지들을 형성할 수도 있다. 요약하면, 메트릭은 1 초과의 리소스와 관련될 수도 있다는 것이다. 그것은 그러한 메트릭들이 어떻게 저장되어야 하는지에 대한 질문을 제기한다. 관련 리소스 당 하나의 테이블을 구체화하면 높은 리던던시가 초래될 수도 있다. 더 나은 솔루션은 다양한 관련 리소스들에 대한 다중 외래 키들을 갖는 단일 메트릭 테이블을 갖는 것일 것이다. 그러한 테이블은 그러나 레귤러 이벤트 테이블과 매우 유사해 보인다. 레귤러 이벤트 테이블과의 유일한 차이는 메트릭 테이블이 지정된 값 컬럼을 갖는다는 것이다. 따라서 그것은 모두 모델링에 이른다. 이벤트를 메트릭으로 승격시키기 위한 사용자 상호작용은 무엇인가? 메트릭 테이블을 구체화할지 여부를 누가 결정하는가? 메트릭들이 일급 데이터세트들을 형성하는가? 그렇지 않으면, 어떻게 단일 메트릭이 다중 리소스들과 연관될 수 있는가?
데이터세트 통계 - 작은 구체화된 집계들
동기
임의의 종류의 비용 기반 옵티마이저 (optimizer) 는 데이터에 대한 통계에 의존한다. 통계는 술어 선택성 추정, 조인 카디널리티 추정, 및 많은 다른 중요한 비용 팩터들의 근거이다. 쿼리들 (효율적인 SQL 계획을 선택) 및 변환들 (다른 것들 중에서도 옳은 실행 빈도를 선택) 양자 모두에 대한 비용 기반 최적화가 필요하다.
요약
예시적인 실시형태는 Snowflake 의 예를 따르고 작은 구체화된 집계들 (SMA들) 을 구현할 수 있다. Netezza 가 개척한 동등한 마케팅 용어는 Zone Maps 이다. 그 아이디어는 다음과 같다. 베이스 데이터를 버킷화하고 각각의 버킷에 대한 min 및 max 와 같은 집계들을 컴퓨팅한다. 사용자 쿼리에 직면할 때, 베이스 데이터 대신에 구체화된 집계들을 참고한다. 더 나은 스케일러빌리티를 위해, 시계열 데이터베이스들이 시간의 경과에 따라 메트릭 데이터를 롤업하는 방법과 유사하게, 집계들은 시간의 경과에 따라 추가로 롤업될 수 있다. SMA들은, Snowflake 가 그들을 효율적으로 컴퓨팅하는데 필요한 모든 기능: 정적 프루닝, 매우 빠른 group by, 모든 관련 집계 함수들, 증분적 컴퓨테이션을 위한 merge into 를 이미 제공하기 때문에 예시적인 실시형태에 이상적이다.
버킷 사이즈
작은 구체화된 집계들에 대한 중요한 설계 선택은 버킷 사이즈이다. 그것은 대부분의 쿼리들에 대해 정확한 통계를 제공할 만큼 충분히 작아야 하지만, 베이스 데이터에 직접 액세스하는 것보다 실질적인 성능 이익을 제공할 만큼 충분히 커야 한다. Snowflake 에서, SMA들은 파티션별로, 즉, S3 파일 기반으로 컴퓨팅되며, 그 각각은 16 MB 의 타겟 사이즈를 갖는다. Snowflake 의 SMA들에 직접 액세스할 수 없으므로, Snowflake 에 대해 레귤러 SQL 쿼리들을 공식화하는 것 외에 다른 선택이 없다. 그러나 어쨌든 파티션별 SMA들에는 관심이 없다. 모든 쿼리들은 시간 범위 술어를 캐리한다. 따라서 실제로 시간 범위들에 걸친 SMA들에 관심이 있다. 질문은 따라서, 버킷들을 형성하는데 적절한 시간 인터벌은 무엇인가이다. 직관적으로, 그것은 최적화하려는 가장 작은 쿼리만큼 작아야 한다. 그것은 아마 5 분의 버킷 사이즈를 제안한다. 그것은 데이터에 대한 보유 한도를 두지 않으려는 시스템에 대해 아주 작기 때문에, 일부 형태의 멀티-레벨 롤업 스킴이 필요할 것이다. 결국에는 달성해 낼 것이지만, 1 시간의 버킷 사이즈를 갖는 단일 레벨 스킴으로 시작해 본다. 1 시간은 랜딩 페이지들 및 대부분의 쿼리들을 커버할 만큼 충분히 작지만, 잠시 동안 스토리지 비용들 및 유지보수 오버헤들에 대해 걱정하지 않아도 될 만큼 충분히 크다.
사용 경우들
구체화하기 위해 올바른 집계들의 세트를 선택하기 위해, 예측가능한 사용 경우들을 고려해야 한다:
카디널리티들에 더하여, 평균 로우 사이즈를 아는 것이 또한 유용하다. 해당 연산에 의존하여, 카디널리티 또는 데이터 볼륨 (카디널리티 * 평균 로우 사이즈) 중 어느 하나는 우세한 비용 팩터일 수도 있다. 전체 테이블의 평균 로우 사이즈는 Snowflake 의 테이블 통계에서 직접 판독될 수 있다. 버킷화된 (시간-파티셔닝된) 또는 프로젝팅된 데이터의 평균 로우 사이즈는 그러나 베이스 데이터의 실제 sum(length()) 또는 avg(length()) 집계를 요구한다.
이벤트들 및 리소스들 커버 페이지
커버 페이지는, 각각의 이벤트 또는 리소스에 대해, 각각 이벤트들의 수 (count(*)) 의 히스토그램 또는 구별 리소스 키들의 수 (HLL) 의 히스토그램을 보여준다. 추가적으로, 구별 외래 키들의 수 (다시 HLL) 를 보여주는 스파크라인들이 있다. 이들의 시간별 SMA들을 생성함으로써, 베이스 데이터를 쿼리하는 것을 회피할 수 있다. 커버 페이지는 SMA들로부터 완전히 로딩될 수 있고, 이는 심지어 Snowflake 외부에 캐시될 수도 있다. 미래에, select 필드들에 적절한 top-k 와 같은 추가적인 통계를 추가할 수도 있다.
술어 선택성 추정
술어 선택성 추정은 쿼리 최적화에서 구식이다. 단연코 가장 흔한 술어들은 = 및 IS (NOT) NULL 이고 그 다음이 범위 술어들 (>, <) 이다. 등식 및 NULL 술어들의 선택성은 다음의 SMA들이 주어지면 간단하다:
범위 술어들은 더 까다롭다. 많은 스킴들이 문헌에서 제안되었다. 현실적으로, 가까운 장래에 min 및 max 에 기초한 미가공의 공식들 및 단순한 휴리스틱들 외에 어떤 것도 제공할 수 없다. 대부분의 쿼리들은 다중 선택 술어들을 갖고, 술어들은 상관될 수도 있음에 유의한다. 쿼리 옵티마이저들은 통상적으로 술어들이 독립적이라고 가정하므로, 결합 (conjunctive) 술어의 추정된 선택성은 단순히 그 자식 술어들의 개개의 선택성들의 곱이다. 분명히, 추정치는 실제로 극도로 부정확할 수도 있다. 즉, 여기서 할 수 있는 멀티-속성 통계와 다름 없다. 하나의 주목할 만한 예외인 키들을 제외하고 그들 모두를 철저하게 구체화하기 위한 속성들의 가능한 조합들이 너무 많다.
조인 카디널리티 추정
조인 카디널리티 추정치는 조인 재순서화의 기초이다. 조인 카디널리티 추정은 따라서 틀림없이 쿼리 비용 추정의 가장 중요한 부분이다. 불행히도, 정확한 카디널리티 추정치를 얻기는 매우 어려운데, 조인의 출력 카디널리티가 조인 키들의 상관에 아주 많이 의존하기 때문이다. m 및 n 로우들의 조인의 출력 카디널리티는 0 과 m*n 사이의 어떤 것일 수도 있다. 전체 비용 추정 에러는 따라서 쿼리의 조인들의 수에 따라 지수함수적으로 증가한다. 이전의 데이터 시스템들은 조인 키들의 상관을 추정하는데 심각한 시도를 하지 않았다. 대신에, 시스템들은 입력 테이블 사이즈 및 외래 키 관계들의 지식에 기초하여 간단한 휴리스틱들을 사용할 것이다. 예를 들어, 먼저 작은 테이블들을 조인하고, 모든 외래 키 조인들을 1:1 조인이 될 것으로 예상한다. 더 진보된 시스템들은 히스토그램들 및 샘플링을 사용한다. 이 모든 것들도 물론 수행할 수 있다. 그러나 Snowflake 에는 또한 세트 유사성에 사용될 수 있는 편리한 minhash 구현이 따라 나온다. 2 개의 조인 키 세트들의 Jaccard 인덱스를 (HLL 을 사용하는) 이들 세트들의 카디널리티의 추정치와 결합함으로써, 동등-조인의 출력 카디널리티의 추정치를 컴퓨팅할 수 있다. 대부분의 조인들은 템포럴 조인들이다. 시간 인터벌들을 고려하지 않고 조인 키 컬럼들의 통계를 간단히 보면, 매우 오해의 소지가 있을 수 있다. 밴드 조인들 또는 템포럴 조인들의 카디널리티 추정에 대한 학술 기사의 간략한 검색은 샘플링된 데이터에 대해 조인들을 실행하는 것에 기초한 블랙-박스 접근법들을 넘어서는 0 히트들을 산출하였다. 어떤 접근법들이 우리의 사용 경우들에 가장 알맞게 작동하는지를 알기 위해 열심히 생각하고 실험해야 한다. 그때까지는, 카운트 및 HLL 에 기초하는 기본 휴리스틱들에 의존해야 한다. 다른 목적들 (외래 키 제약 권고들) 을 위해 키들의 minhash 를 이미 수집하므로, 우리는 물론 그것들을 여러모로 활용할 수도 있다. t-digest 에 기초한 히스토그램들과 같은 것들은 흥미로운 미래 방향들이다.
그룹화 키 카디널리티 추정
그룹화 키 (group-by) 카디널리티 추정은 group-by 연산자들이 파이프라인 중간에 나타나거나, 또는 컴파일러가 파이프라인 위 또는 아래에 group-by 를 푸시할 수 있는 경우 중요하다. group-by 최적화는 쿼리 최적화에 있어서 매우 진보된 주제이다. 그룹화 키 카디널리티 추정은 그 자체로 구별 카디널리티 추정; 즉, HLL 의 간단한 특수 경우이다. 그러나, 템포럴 group-by 의 경우, 시간 인터벌들도 또한 고려해야 할 것이다. 그 주제에 대한 문헌은 알려져 있지 않다. group-by 최적화가 옵티마이저에서 곧 다루지 않을 진보된 주제임을 고려하면, 이 시점에 그것에 대한 특별한 통계에 투자할 필요가 없다.
변환 카디널리티 추정
여기서 질문은 "데이터의 다음 배치의 크기는 얼마나 될까요?" 이다. 그 질문은 count(*) 및 시간 술어들, 또는 Snowflake 시간 이동 및 테이블 통계를 사용하여 대답하기 쉽다.
점진적 실행
점진적 실행을 위해, 일부 출력 로우들을 생성할 좋은 기회를 여전히 가지면서 각각의 서브-범위 (특히 첫번째) 가 매우 빠르게 (즉, 2 초) 실행되도록, 입력 시간 범위를 더 작은 서브범위들로 분할하길 원한다 (그렇지 않으면, 슬라이싱 노력은 낭비되었다). 첫번째는, 타겟 레이턴시 내에 스캔될 수 있는 것보다 큰 슬라이스를 절대 선택해서는 안되기 때문에, 입력 카디널리티의 추정을 요구한다. 두번째는, 모두 여기에 논의된 다른 것들에 의존하는, 출력 카디널리티의 추정을 요구한다. 입력 카디널리티는 count(*) 를 사용하여 도출될 수 있다. 출력 카디널리티는 일반적인 경우에 예측하기 어렵지만, (점진적 실행이 가장 중요한 경우) 이벤트 데이터에 대한 간단한 검색 쿼리들에 대해 비교적 잘 예측될 수 있다. 또한, min, max, 및 비-NULL 카디널리티 (count) 에 기초한 간단한 술어 선택성 추정을 사용하여 출력 카디널리티의 적절한 추정치를 얻을 수 있다.
구체화할 집계들의 리스트
상기 논의된 사용 경우들이 주어지면, 다음의 SMA들은 버킷 마다 컴퓨팅되어야 한다.
각각의 컬럼에 대해:
각각의 키 (복합 키들을 포함함) 에 대해:
각각의 외래 키 (복합 외래 키들을 포함함) 에 대해:
SMA 스토리지
SMA들의 프라이머리 카피는, 그것이 데이터가 컴퓨팅되고 언바운드된 스토리지 용량을 갖는 경우이기 때문에, Snowfalke 이어야 한다. FDB 와 같은 저-레이턴시 키-값 스토어는 더 낮은 레이턴시를 제공할 것이지만, 그렇다 하더라도 메모리에 SMA들을 캐싱할 필요성이 남아 있다. Snowflake 쿼리 컴파일러를 구축하는 것에서 무엇을 배웠는지로부터 너무 많은 것이 분명하다: 모든 SMA 액세스를 위해 원격 스토리지 서비스에 네이티브로 쿼리할 여유가 없다.
Snowflake 의 SMA 스토리지
스토리지 설계의 기본 원칙은 "함께 액세스되는 데이터는 함께 저장되어야 한다" 이다. 이러한 베이스 테이블들이 항상 함께 사용되지 않는 한, 다중 베이스 테이블들의 SMA들을 함께 묶는 것은 이익이 없다. 그렇다고 하더라도, Snowflake 가 컬럼 스토어이기 때문에 이익들은 적다. 따라서 베이스 테이블들 간에 SMA 테이블들을 공유하지 말자. 주목할 만한 예외는 외래 키 관계 권고에 의한 사용을 위한 minhash 데이터이다. 이 사용 경우에, 데이터베이스의 모든 호환가능한 프라이머리 키들에 대하여 서브세트 스코어를 컴퓨팅해야 한다. 그 사용 경우는 보다 전문화된 스토리지 스킴을 보증할 수도 있다. 그것은 여전히 베이스 테이블 당 하나의 SMA 테이블이 있어야 하는지, 또는 베이스 테이블 당 다중 SMA 테이블들이 있어야 하는지, 어쩌면 베이스 테이블 컬럼, 키, 또는 외래 키 당 하나씩 있어야 하는지에 대한 질문을 여전히 남긴다. 양자 모두의 솔루션들은 합리적이지만, 베이스 테이블 당 하나의 SMA 테이블이 더 나은 솔루션이다. 첫째로, 베이스 데이터에 대한 단일 패스에서 (다중 집계 함수들을 갖는 단일 GROUP BY 를 사용하여) 모든 SMA들을 컴퓨팅할 수 있다. 멀티-테이블 인서트들, 일시적 테이블들, 및/또는 다중 MERGE INTO 문들을 처리해야 하는 것보다 단일 MERGE INTO 문을 사용하여 모든 SMA들을 단지 고쳐쓰는 것이 더 쉽고 더 저렴하다. 둘째로, Snowflake 는 컬럼 스토어이므로, 넓은 테이블로부터 적은 수의 컬럼들을 판독하는 것은 좁은 테이블로부터 적은 수의 컬럼들을 판독하는 것보다 전혀 느리지 않다. 다른 질문은 다양한 SMA 컬럼들을 어떻게 표현하는지이다. 2 가지 기본 옵션들은 다음이다:
양자의 솔루션들은 동일하게 잘 압축하여야 하며 object 컬럼들을 컬럼화하는 Snowflake 의 능력 때문에 쿼리하는 것이 동일하게 저렴해야 한다. 여전히, 제 1 솔루션이 더 나은데, 업데이트하기에 더 쉽고 더 저렴하기 때문이다. flatten 및 objectagg 할 필요가 없다. 나중에 SMA들을 추가 또는 제거한다면, ALTER TABLE 문들을 사용하여 대응하는 컬럼들을 추가 또는 제거할 수 있다. 다른 SMA들을 재컴퓨팅할 필요가 없다. 다음의 구체적인 예를 고려한다. 프라이머리 키 (a,b) 를 갖는 컬럼들 a, b, c 의 테이블 T. SMA 테이블은 다음의 컬럼들을 가질 것이다:
SMA 캐싱
SMA 테이블을 Go 구조로 바꾸고 그들을 위해 LRU 캐시를 구축하는 것이 솔루션일 수도 있다. 그 캐시가 얼마나 프레쉬 또는 일관성이 있어야 하는지에 대한 열린 질문이 있다. 변환들은 논스톱으로 실행되므로, 캐싱된 SMA들은 빠르게 부정확해질 수도 있다. 특히, 최근 시간 (latest hour) 의 데이터의 캐싱된, 불완전한 SMA 는 매우 오해의 소지가 있을 수도 있다. 적어도 최근 SMA들을 캐싱하는 것이 타당한지 여부와 그 방법에 대해 생각을 좀 해야 한다. 예를 들어, 최근 시간 SMA 를 전혀 고려 및 따라서 캐싱하지 않고, 대신에 이전 시간의 SMA 를 사용하도록 선택할 수도 있다. 데이터가 극도로 늦게 도달하지 않고 통계적으로 말하면 합리적으로 잘 거동된다는 일부 시간 기반 또는 변환기 개시 만료 및 가정과 함께, 캐싱된 SMA들은 우리의 목적들을 위해 충분히 정확할 수도 있다. 캐시 미스 시, SMA 는 Snowflake 로부터 페치되어야 한다. 그것은 Snowflake 가 프루닝하는데 문제가 없는 단일 버킷 ID 또는 버킷 ID들의 인접한 범위에 대한 간단한 필터 쿼리이다. 실행하는데 여전히 수백 밀리초가 걸릴 수도 있음을 고려할 때, 제 2 레벨의 외부 캐싱, 즉 FDB 또는 memcached 는 미래에 가치있는 최적화가 될 것이다.
SMA 컴퓨테이션
SMA 변환들
데이터세트들, 즉 베이스 테이블들은 새로운 옵저베이션들 및 변환 실행에 응답하여 시간의 경과에 따라 변경된다. SMA 테이블들은 그들의 대응하는 베이스 테이블들에 대하여 최신 상태로 유지되어야 한다. 첨부-전용 포인트 테이블들의 SMA 컴퓨테이션은 매우 간단한 스트리밍 집계이다. 각각의 버킷이 한 시간 동안 커버하고 여러 집계들을 포함하고, 그 각각은 개별의 버킷에 대해 새로운 데이터가 도달할 때마다 업데이트되어야 한다. 각각의 새로운 데이터 포인트는 타임스탬프의 간단한 정수 나눗셈을 사용하여 버킷에 할당된다. 컴퓨팅될 SMA들은 모두 요약가능하며, 어떤 이벤트를 두번 판독할 필요는 없다. 인터벌 테이블들 및 비-첨부-전용 포인트 테이블들의 SMA 컴퓨테이션은 더 복잡하고 고가이다. 그러한 베이스 테이블들의 데이터는 업데이트 또는 삭제될 수도 있으므로, 대응하는 버킷들의 SMA들은 맨 처음부터 재컴퓨팅되어야 한다. 어느 버킷들을 재컴퓨팅할지를 결정하기 위해, 변환 워터마크들은 보수적인 추정치로서 서빙할 수 있다. 대안적으로, Snowflake 스트림들은 이전 SMA 변환에 대한 베이스 테이블의 정확한 델타를 얻는데 사용될 수 있다. (이론적으로 가능한) 실제로 변경되지 않은 SMA 버킷들을 업데이트하는 것을 회피하기 위해, 모든 SMA들에 대해 해시 핑거프린트를 컴퓨팅하고 오직 핑거프린트가 매칭하지 않으면 로우를 업데이트할 수 있다. 인터벌 로우들을 버킷들에 맵핑하는 것은 unpack 또는 re-window 연산을 구성한다. 버킷, 즉 시간 경계들을 가로지르는 로우들은 이들 버킷들로 언팩킹 또는 리윈도우되어야 한다. 언팩의 구현은 베이스 테이블 로우 인터벌들과 버킷 인터벌들 사이의 템포럴 조인이다.
SMA 프레쉬니스
SMA 변환은 집계 및 병합을 요구하기 때문에 멀티-테이블 인서트로 표현될 수 없다. SMA들은 별도의 변환에서 컴퓨팅되어야 한다. 그것은 그 변환을 실행할 때 질문을 제기한다. 간단한 접근법은 베이스 테이블이 변경될 때마다 SMA들을 재-컴퓨팅하는 것이다. 그러나 자주 변경되는 베이스 테이블들, 특히, SMA 컴퓨테이션이 템포럴 조인을 요구하는 인터벌 테이블들의 경우 그것은 매우 고가이다. SMA 변환은 베이스 테이블 변환보다 쉽게 더 고가일 수도 있다. 따라서, 대신에, SMA들은 더 낮은 빈도로, 즉 15 분 당 한번 또는 심지어 시간 당 한번 컴퓨팅되어야 한다. 프레쉬니스는 큰 문제가 아닌데, 최근 버킷, 즉 시간의 데이터는 어쨌든 사용하기 어렵고, SMA 캐싱 하의 논의를 참조한다.
SMA 조합 및 보간
이벤트 및 리소스 커버 페이지들을 제외하고, 쿼리 시간 인터벌들은 보통 1 시간 경계들과 정확히 정렬되지 않는다. 여러 시간들의 데이터를 판독하는 쿼리의 경우, 대응하는 SMA들은 따라서 병합되어야 한다. count, min, max, sum 의 경우에, 병합은 사소하다. 그러나 HLL 및 minhash 의 경우, Snowflake 로의 라운드-트립을 회피하기 위해 대응하는 _combine 및 _estimate 함수들의 Go 구현들을 기입해야 한다. 다행히, Snowflake 는 HLL 및 minhash 상태를 JSON 으로서 엑스포트하도록 허용하고, 근본적인 프로세스가 공개되었다. 따라서, Go 에서 _combine 및 _estimate 함수들을 기입하고, 캐싱된 JSON 상태에 기초하여 HLL 및 minhash 를 컴퓨팅하는 것이 절대적으로 가능하다. 1 시간 미만의 범위들 (즉, 15 분) 의 경우, count 및 sum 을 적절히 보간 (즉, 4B 로 나눔) 하도록 선택할 수도 있다. 다른 집계들은 데이터의 템포럴 분포에 대한 불안정한 가정들 없이 보간될 수 없다.
linkify 프리젠테이션, 링크 데이터타입, 및 외래 키들의 처리
특정 실시형태에서, 다음과 같이 덜 고가의 컬럼 값들을 생성할 수 있다:
이전의 논의
GUI 에서, 유용한 방식으로 리소스 인스턴스들의 리스트를 프리젠팅하길 원한다. APAL 쿼리 언어에서 이것에 필요한 2 가지 함수들이 있다. 첫번째는 다른 곳에서 처리하는 리소스 특성들에 대한 시간에 걸친 어레이 집계이다. 두번째는 사용자에게 합리적으로 프리젠팅할 수 있는 방식으로 다른 리소스들에 대한 "링크들" 로서 외래 키들을 해결하는 것이다. 원하는 프리젠테이션은, 다른 리소스들/이벤트들에 대한 외래 키들을 갖는 각각의 리소스 인스턴스에 대해, 베이스 외래 키 값의 위에 장식으로서 사용자-판독가능-이름을 갖는 클릭가능-링크를 프리젠팅하는 것이다. 결국에는, 이름 Shopping Cart Service 는 GUID cd3198a1-1e22-498b-aa7d-e22d5bdd3abc 보다 사용자에게 의미가 있을 것이다. 일단 이름 컬럼을 프리젠팅하면, 사용자는 그것에 대해 소팅 및 필터와 같은 연산들을 수행 가능할 것으로 예상하고 그 소팅 또는 필터의 "논리적" 결과를 가질 것이다. 따라서, 이 친숙한 프리젠테이션의 바람직한 특성은 그것이 유효한 일급 "컬럼" 이기도 하다는 것이다. 이에 대한 문제는 일부 외래 키들이 1 초과의 컬럼 (복합 키들) 으로 구성되고 일부 컬럼들이 1 초과의 외래 키의 부분이고, 따라서 1 초과의 종류의 링크로서 프리젠팅될 수 있다는 것이다. 추가적으로, 클라이언트는 쿼리 결과를 볼 때까지 가능한 외래 키들을 알지 못하므로, 사전에 적절한 조인을 쉽게 공식화할 수 없다. 한편, 서버는 데이터의 형상을 이미 알고 있고, 단일-쿼리 프리젠테이션에 도움이 되는 형태로 데이터를 프리젠팅하기 위해 적절한 데이터 셰이핑을 적용할 수 있어, 사용자에게 가시적인 레이턴시를 감소시킬 수 있다. 많은 가능한 설계들을 논의한 후, 현재 바람직한 선택은 linkify 라 불리는 프리젠테이션 옵션이다. 외래 키 컬럼들 자체에 링크 주석들을 스퀴즈하려고 시도하는 대신에, linkify 는 리소스 인스턴스에서 외래 키 당 하나의 컬럼 씩 새로운 컬럼들을 생성하는 옵션이다. 이 컬럼의 데이터 타입은 특수 데이터 타입 link 일 것이다. link 는 구문론적으로 object 처럼 보이지만, lined-to 리소스 인스턴스의 사용자-판독가능 레이블을 포함하는 잘 알려진 필드 _c_label 을 갖는다. 추가적으로, 필드 이름들로서 타겟 테이블 컬럼 이름들로 명명된, 링크 타겟을 식별하는 외래 키들의 키 값들을 반복한다. 최종적으로, link 는 파라미터가 타겟 데이터세트 id 인 파라메트릭 데이터타입 (마치 array-of-X 또는 object-with-schema-Y 와 같음) 이다. 예로서, 다음 3 개의 데이터세트들이 주어진다 (우선은 시간을 무시하고, 디스크 및 네트워크를 하나의 로우에 스퀴시하는 (squishing) 정지 (halting) 모델링을 무시하자):
예시적인 디스크/네트워크 전송 dsid 1515
예시적인 디스크/네트워크 전송에 대한 스키마는 다음과 같다:
예시적인 디스크 리소스 dsid 5330
예시적인 디스크 리소스에 대한 스키마는 다음과 같다:
예시적인 인터페이스 리소스 dsid 18227
예시적인 인터페이스 리소스에 대한 스키마는 다음과 같다:
쿼리가 예시적인 DiskNetwork 전송 데이터세트를 소싱하고, 그것을 linkify 옵션을 통해 실행하면, 반환된 데이터세트는 다음과 같다:
반환된 쿼리 결과에 대한 스키마는 다음과 같다:
일부 중요한 호출들:
링크 필드들의 'name' 은 타겟 데이터세트로 구성되지만, 2 개의 상이한 외래 키들이 동일한 데이터세트 ID 에 링크되면, 그들 중 하나는 그 이름에 _2 가 덧붙게 될 것이다. 데이터세트의 실제 레이블은 컬럼의 레이블에 제공된다 (그 레이블들은 고유하지 않을 수도 있다).
자동 메타데이터 추론
데이터세트의 로우-레벨 타입 스키마는 종래의 관계형 데이터베이스 테이블 스키마와 많이 비슷하다: 이름들을 갖고 데이터타입들을 갖는 속성들 (컬럼들) 이 있다. 관계형 대수 및 템포럴 대수로부터 알려진 추가적인 메커니즘들은 투플 (로우) 의 템포럴 관련성을 위한 포인트 시간 데이터 또는 인터벌 시간 데이터를 저장하는 것, 프라이머리 및 후보 키들을 필드 값들의 합집합으로서 선언하여 리소스 인스턴스들을 고유하게 식별하는 것 (그렇지만, 데이터베이스에는, 특정 리소스 인스턴스가 시간의 경과에 따라 리소스 상태를 커버하게 하는 많은 로우들이 있을 것이다), 및 외래 키들을 선언하여 데이터세트들을 다른 데이터세트들에 기능적으로 링크하는 것을 포함한다. 데이터세트에 관한 메타데이터는 이해가능한 프리젠테이션에서, 객체들과, 객체들에 관련된, 시간의 경과에 따라 발생하는 이벤트들 사이에 관계들을 맺기 위해 예시적인 실시형태의 객체 모델을 구축하도록 허용하는 정보이다. OPAL 구현은 출력 데이터세트들에 대한 메타데이터를 명시적으로 특정하는 메커니즘들을 포함한다. 이것은 그들이 추구하는 것이 무엇인지 정확히 아는 사용자들에게 유용하다.
이러한 메타데이터 메커니즘들의 예들은 다음을 포함한다:
setpk 는 어느 특정 필드들이 데이터세트의 프라이머리 키를 함께 구성하는지를 특정한다. 리소스 데이터세트는 프라이머리 키를 가져야 한다. 관계형 대수에서 종래에 사용한 것과는 달리 "프라이머리 키" 를 사용하는 것에 유의한다.
addkey 는 데이터세트에 대한 후보 키를 선언한다 - 후보 키는 값들이 해당 엔티티에 대한 고유 식별자를 함께 구성하는 필드들 (하나 이상) 의 조합이다. 임의의 후보 키는 잠재적으로 프라이머리 키일 수 있으며, 임의의 외래 키는 임의의 후보 키를 가리킬 수 있지만, 하나의 후보 키는 프리젠테이션 목적들을 위해 일부 디폴트를 필요로 하기 때문에 "프라이머리 키" 의 역할로 "승격된" 다.
추가적으로, "관련 키들 (related keys)" 의 개념을 갖는다. "관련 키들" 은 데이터세트들 사이의 고유하지 않은 링크들이다. 예를 들어, "데이터센터 (datacenter)" 를 나타내는 데이터세트는 그 데이터센터의 모든 호스트들에 대해, "호스트들 (hosts)" 을 나타내는 데이터세트에 대한 "관련 키" 를 가질 수도 있다. 또는, "컨테이너들 (containers)" 을 나타내는 데이터세트는 그 특정 컨테이너에 대해 "로그 이벤트들 (log events)" 을 나타내는 데이터세트에 대한 관련 키를 가질 수도 있다.
스마트들에 대한 경우
사용자가 일부 데이터세트로 시작하고, 파이프라인들의 스테이지들의 워크시트를 통해 새로운 형상으로 리파이닝할 때, 종종 시스템에 존재하는 어떤 지식이든 메타데이터에 보존하는 작업을 잘 수행할 수 있다. 예를 들어, 입력 데이터세트가 "valid from" 으로서 마킹된 타임스탬프 컬럼을 가지면, 이 컬럼에 대한 어떠한 사소한 연산 (rename, 또는 일부 키 관계에 있어서 inclusion) 도 그 메타데이터를 무효화하지 않을 것이며, 메타데이터는 출력 데이터세트에 적용하기 위해 워크시트를 통해 캐리된다. 유사하게, 키 관계들을 구성하는 컬럼들이 호환가능하지 않은 방식들로 제거 또는 변형되지 않는 한, 그 키 관계들은 보존될 수 있다. 이것이 OPAL 컴파일러에서 구현되는 방식은, 각각의 동사가 메타데이터를 변형시킬 수도 있는 방법에 관한 지식을 갖고, 컴파일의 부분으로서, 동사 구현이 구현의 제약들이 주어지면, 대수적으로 가능한 한 많은 메타데이터를 보존 및 캐리 포워드할 책임이 있다는 것이다. 흔히, 이를 통해 사용자는 시스템에 이미 알려진 메타데이터 관계들을 중복으로 선언할 필요가 없다.
이제 도 15 를 참조하면, 프로세싱 플로우 다이어그램은 본 명세서에서 설명된 바와 같이 시스템에 의해 구현된 방법의 예시적인 실시형태를 예시한다. 예시적인 실시형태의 방법 (1000) 은: 수집 에이전트들을 사용하여 데이터를 캡처 및 포워딩하는 단계 (프로세싱 블록 1010); 캡처된 데이터를 데이터 웨어하우스로 버퍼링 및 로딩하는 단계 (프로세싱 블록 1020); 데이터를 템포럴 대수 쿼리 언어에 의해 특정된 것으로 변환하는 단계 (프로세싱 블록 1030); 템포럴 대수 쿼리 언어를 사용하여 변환된 데이터의 쿼리를 가능하게 하는 단계로서, 그 쿼리는 템포럴 데이터 관계들을 포함하는, 상기 쿼리를 가능하게 하는 단계 (프로세싱 블록 1040); 및 쿼리들의 결과들을 사용자 인터페이스를 통해 사용자에게 프리젠팅하는 단계 (프로세싱 블록 1050) 를 포함한다.
본 개시의 초록은 독자들로 하여금 기술적 개시의 본질을 신속히 확인하게 하도록 제공된다. 이는 청구항들의 범위 또는 의미를 해석 또는 한정하도록 사용되지 않을 것이라는 이해를 갖고 제출된다. 또한, 전술한 상세한 설명에서, 다양한 피처들은 본 개시를 간소화할 목적으로 단일 실시형태에서 함께 그룹화됨을 알 수 있다. 본 개시의 이러한 방법은, 청구된 실시형태들이 각각의 청구항에서 명시적으로 기재된 것보다 더 많은 피처들을 요구한다는 의도를 반영하는 것으로서 해석되지 않아야 한다. 대신, 다음의 청구항들이 반영하는 바와 같이, 본 발명의 청구물은 단일의 개시된 실시형태의 모두보다는 적은 피처들에 있다. 따라서, 이하의 청구항은 상세한 설명에 통합되며, 각각의 청구항은 별도의 실시형태로서 독자적으로 기재된다.
Claims (20)
- 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템으로서,
데이터 프로세서; 및
상기 데이터 프로세서에 의해 실행가능한, 데이터 캡처 및 시각화 시스템을 포함하고, 상기 데이터 캡처 및 시각화 시스템은,
수집 에이전트들을 사용하여 데이터를 캡처 및 포워딩하고;
캡처된 상기 데이터를 데이터 웨어하우스로 버퍼링 및 로딩하고;
템포럴 대수 쿼리 언어에 의해 특정된 바와 같이 상기 데이터를 변환하고;
상기 템포럴 대수 쿼리 언어를 사용하여 변환된 상기 데이터의 쿼리를 가능하게 하는 것으로서, 상기 쿼리는 템포럴 데이터 관계들을 포함하는, 상기 쿼리를 가능하게 하고; 그리고
쿼리들의 결과들을 사용자 인터페이스를 통해 사용자에게 프리젠팅하도록 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 템포럴 대수 쿼리 언어는 입력들, 동사들, 함수들, 및 출력들을 포함하는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은, 데이터를, 데이터세트들로 변환되는 옵저베이션 (observation) 들로 수집하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 3 항에 있어서,
상기 데이터세트들은 테이블 데이터세트들, 이벤트 데이터세트들, 또는 리소스 데이터세트들인, 데이터 캡처 및 시각화 시스템. - 제 4 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 리소스 데이터세트들의 템포럴 스플라이싱을 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 시간 또는 아이덴티티에 대한 집계를 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 대수를 사용하여 선택 또는 필터링을 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 7 항에 있어서,
상기 템포럴 대수는 시간 윈도우들 또는 시간 인터벌들에 대한 동사들을 포함하는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 프로젝션을 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 조인들을 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 중복제거를 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 groupby 를 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 데이터세트들에 대해 스트림 프로세싱을 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 제 1 항에 있어서,
상기 데이터 캡처 및 시각화 시스템은 템포럴 데이터세트들에 대해 백필링 및 비동기 프로세싱을 수행하도록 추가로 구성되는, 데이터 캡처 및 시각화 시스템. - 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화를 위한 방법으로서,
수집 에이전트들을 사용하여 데이터를 캡처 및 포워딩하는 단계;
캡처된 상기 데이터를 데이터 웨어하우스로 버퍼링 및 로딩하는 단계;
템포럴 대수 쿼리 언어에 의해 특정된 바와 같이 상기 데이터를 변환하는 단계;
상기 템포럴 대수 쿼리 언어를 사용하여 변환된 상기 데이터의 쿼리를 가능하게 하는 단계로서, 상기 쿼리는 템포럴 데이터 관계들을 포함하는, 상기 쿼리를 가능하게 하는 단계; 및
쿼리들의 결과들을 사용자 인터페이스를 통해 사용자에게 프리젠팅하는 단계를 포함하는, 데이터 캡처 및 시각화를 위한 방법. - 제 15 항에 있어서,
상기 템포럴 대수 쿼리 언어는 입력들, 동사들, 함수들, 및 출력들을 포함하는, 데이터 캡처 및 시각화를 위한 방법. - 제 15 항에 있어서,
데이터를, 데이터세트들로 변환되는 옵저베이션들로 수집하는 단계를 포함하는, 데이터 캡처 및 시각화를 위한 방법. - 제 15 항에 있어서,
시간 또는 아이덴티티에 대한 집계를 수행하는 단계를 포함하는, 데이터 캡처 및 시각화를 위한 방법. - 제 15 항에 있어서,
템포럴 대수를 사용하여 선택 또는 필터링을 수행하는 단계를 포함하는, 데이터 캡처 및 시각화를 위한 방법. - 제 15 항에 있어서,
템포럴 groupby 를 수행하는 단계를 포함하는, 데이터 캡처 및 시각화를 위한 방법.
Applications Claiming Priority (4)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US202063054679P | 2020-07-21 | 2020-07-21 | |
US63/054,679 | 2020-07-21 | ||
US17/358,427 | 2021-06-25 | ||
US17/358,427 US20220027379A1 (en) | 2020-07-21 | 2021-06-25 | Data capture and visualization system providing temporal data relationships |
Publications (1)
Publication Number | Publication Date |
---|---|
KR20220011595A true KR20220011595A (ko) | 2022-01-28 |
Family
ID=76845097
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
KR1020210095135A KR20220011595A (ko) | 2020-07-21 | 2021-07-20 | 템포럴 데이터 관계들을 제공하는 데이터 캡처 및 시각화 시스템 |
Country Status (4)
Country | Link |
---|---|
US (1) | US20220027379A1 (ko) |
EP (1) | EP3944092A1 (ko) |
JP (1) | JP2022021343A (ko) |
KR (1) | KR20220011595A (ko) |
Families Citing this family (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US12095794B1 (en) * | 2017-11-27 | 2024-09-17 | Lacework, Inc. | Universal cloud data ingestion for stream processing |
CN110825485A (zh) * | 2018-08-07 | 2020-02-21 | 华为技术有限公司 | 数据处理的方法、设备和服务器 |
US10977198B2 (en) * | 2018-09-12 | 2021-04-13 | Micron Technology, Inc. | Hybrid memory system interface |
US11416507B2 (en) * | 2020-10-26 | 2022-08-16 | Sap Se | Integration of timeseries data and time dependent semantic data |
US20220171622A1 (en) * | 2020-11-27 | 2022-06-02 | Electronics And Telecommunications Research Institute | Multi-dimension dma controller and computer system including the same |
US11494363B1 (en) * | 2021-03-11 | 2022-11-08 | Amdocs Development Limited | System, method, and computer program for identifying foreign keys between distinct tables |
US11609924B2 (en) * | 2021-04-14 | 2023-03-21 | Citrix Systems, Inc. | Database query execution on multiple databases |
US11995082B2 (en) * | 2021-11-05 | 2024-05-28 | Microstrategy Incorporated | Systems and methods for providing faster data access using lookup and relationship tables |
US12081521B2 (en) * | 2021-12-21 | 2024-09-03 | Mcafee, Llc | Website classification via containment queries |
US11729081B2 (en) | 2022-01-20 | 2023-08-15 | International Business Machines Corporation | Enhancing software application hosting in a cloud environment |
CN115941546B (zh) * | 2022-11-29 | 2024-06-14 | 重庆长安汽车股份有限公司 | 系统接口的监控方法、装置、电子设备及存储介质 |
Family Cites Families (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7580920B2 (en) * | 2004-07-22 | 2009-08-25 | Microsoft Corporation | System and method for graceful degradation of a database query |
US8688622B2 (en) * | 2008-06-02 | 2014-04-01 | The Boeing Company | Methods and systems for loading data into a temporal data warehouse |
US9501585B1 (en) * | 2013-06-13 | 2016-11-22 | DataRPM Corporation | Methods and system for providing real-time business intelligence using search-based analytics engine |
US11379494B2 (en) * | 2014-08-06 | 2022-07-05 | Sap Se | Timeline index for partitioned temporal database tables |
US9836623B2 (en) * | 2015-01-30 | 2017-12-05 | Splunk Inc. | Anonymizing machine data events |
US11003645B1 (en) * | 2019-10-04 | 2021-05-11 | Palantir Technologies Inc. | Column lineage for resource dependency system and graphical user interface |
-
2021
- 2021-06-25 US US17/358,427 patent/US20220027379A1/en active Pending
- 2021-07-08 EP EP21184533.4A patent/EP3944092A1/en active Pending
- 2021-07-20 JP JP2021119966A patent/JP2022021343A/ja active Pending
- 2021-07-20 KR KR1020210095135A patent/KR20220011595A/ko active Search and Examination
Also Published As
Publication number | Publication date |
---|---|
JP2022021343A (ja) | 2022-02-02 |
EP3944092A1 (en) | 2022-01-26 |
US20220027379A1 (en) | 2022-01-27 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US20220027379A1 (en) | Data capture and visualization system providing temporal data relationships | |
JP6617117B2 (ja) | 半構造データのためのスケーラブルな分析プラットフォーム | |
US11036735B2 (en) | Dimension context propagation techniques for optimizing SQL query plans | |
US10990590B2 (en) | Aggregation framework system architecture and method | |
JP6416194B2 (ja) | 半構造データのためのスケーラブルな分析プラットフォーム | |
US10031956B2 (en) | Aggregation framework system architecture and method | |
Begoli et al. | One SQL to rule them all-an efficient and syntactically idiomatic approach to management of streams and tables | |
EP2660736B1 (en) | Partial merge in a multi-level storage architecture | |
EP2660732B1 (en) | Unified table query processing | |
US20150220597A1 (en) | Decorrelation of user-defined function invocations in queries | |
US20200311082A1 (en) | Transforming directed acyclic graph shaped sub plans to enable late materialization | |
US10621152B2 (en) | Methods and systems for mapping object oriented/functional languages to database languages | |
May et al. | SAP HANA-From Relational OLAP Database to Big Data Infrastructure. | |
Sinthong et al. | AFrame: Extending DataFrames for large-scale modern data analysis (Extended Version) | |
Kvet et al. | Enhancing Analytical Select Statements Using Reference Aliases | |
Sarkar | Learning Spark SQL | |
Ailamaki et al. | Information management in the cloud (dagstuhl seminar 11321) | |
Urbano | DOZER: a scalable and fault-tolerant streaming engine for Seraph queries evaluation | |
Armbrust | Scale-Independent Relational Query Processing | |
Zhao et al. | Big Data Processing Systems | |
Haque | A MapReduce Approach to NoSQL RDF Databases | |
Barquero et al. | Comparison and Performance Evaluation of Processing Platforms–Technical Report | |
Zhou | Parallel Real-Time OLAP on Cloud Platforms | |
Özsu et al. | Current Issues: Streaming Data and Cloud Computing |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
A201 | Request for examination |