InfluxDB의 구조 및 설계를 위해 필요한 정보들을 정리한 글입니다.
1. InfluxDBv2의 데이터 구조
Get started with InfluxDB | InfluxDB OSS v2 Documentation
Thank you for your feedback! Let us know what we can do better:
docs.influxdata.com
InfluxDBv2에서는 시계열 데이터를 bucket과 mesurements라는 큰 구조를 사용하고 있습니다.
하나의 bucket에는 여러 개의 measurements가 구성될 수 있고 , 하나의 measurements에는 여러 개의 태그와 필드로 구성될 수 있습니다.
- Bucket: 시계열 데이터가 저장되는 위치로, 이전 버전과 비교했을 때 Database가 여기에 속하는 것 같습니다.
- Measurement: 시계열 데이터를 태그와 필드를 통해서 논리적으로 구조화합니다. 이전버전과 동일한 것 같습니다.
- Tags: 서로 다르지만, 자주 변경되지 않는 값을 포함하는 키-쌍으로, 이를 통해 메타데이터를 생성하고 인덱싱이 수행되는 것으로 알고 있어서 잘 정의하는 것이 중요합니다.
- Fields: 실제 수치 값 ( 진동 값, 온도 .. ) 등이 저장되는 키-쌍입니다.
- Timestamp: 디스크에 저장하고 쿼리하는 경우 이를 통해서 수행됩니다.
- Measurement: 시계열 데이터를 태그와 필드를 통해서 논리적으로 구조화합니다. 이전버전과 동일한 것 같습니다.
Important definitions
InfluxDBv2에서는 아래와 같이 데이터를 정의합니다.
- Point: field key, timestamp.로 구성되어 식별되는 단일 데이터 레코드
- Series: measurement, tag keys, tag values.이 동일한 포인트들의 그룹
인플럭스 V2의 데이터 요소
도큐와 같이 위의 데이터 예시를 통해서 데이터 요소를 확인합니다.
1. TimeStamp
InfluxDB의 저장된 모든 데이터는 _time 이라는 타임스탬프를 저장하는 열이 필수적으로 구성됩니다.
디스크에서 타임스탬프는 에포크 나노초 형식으로 저장됩니다. 또한 이전과 마찬가지로 RFC3339 UTC를 기본으로 사용하여 시간을 포맷팅하여 출력합니다.
TimeStamp의 precision은 데이터를 쓸 때 중요하게 동작합니다.
- 기본적으로 데이터 포인트의 TimeStamp는 Unix TimeStamp 형식으로 저장됩니다.
- InfluxDB는 포인트 당 하나의 TimeStamp를 허용하고, 제공되지 않는다면 시스템 시간 (UTC) 를 사용합니다.
2. Measurements
_measurements 는 태그, 필드 및 타임스탬프를 감싸는 테두리 역할을 하는데 데이터를 설명하는 이름으로 설정하는 것이 권장됩니다.
3. Filed
필드에 사용되는 데이터는 인덱싱에 사용되지 않습니다. 필드 값을 필터링하는 쿼리는 모든 필드 값을 쿼리 조건과 일치하도록 스캔해야 합니다. ( 정리 : 필터를 통한 검색은 모든 파일에 대한 검색이 수행됩니다 !! )
따라서 태그에 대한 쿼리가 필드에 대한 쿼리보다 성능이 월등히 우수하기 때문에 좋은 데이터 저장 구조에 대한 디자인이 필요합니다.
( InfluxDB에서 필드는 필수 사항으로 꼭 들어가야 합니다 ! )
census bees=23i,ants=30i 1566086400000000000
census bees=28i,ants=32i 1566086760000000000
-----------------
Field set
- Filed Key ( type: 문자열 ): 필드 이름을 나타내는 "문자열 형식"입니다.
- Filed Value ( type : Float | Integer | UInteger | String | Boolean ) : 필드 값은 필드 키에 대한 데이터를 나타냅니다.
- 문자열 필드 값은 " "를 통해서 항상 묶어줘야 합니다.
- Filed Set : 타임 스탬프와 연결된 필드 key-value 쌍의 컬랙션으로 샘플 데이터에서는 다음의 필드 세트가 포함되어 있습니다.
4. Tag
태그는 문자열과 메타데이터로 저장되는 키와 값의 쌍입니다.
InlfuxDB는 태그를 인덱싱하므로 쿼리 엔진에서는 모든 데이터를 조회하지 않기 때문에 검색 성능이 월등히 향상됩니다.
( InfluxDB에서 태그는 필수 사항은 아니지만 인덱싱 성능을 위해 필요합니 ! )
제한 사항
measurements 이름, 태그 키 및 필드 키는 밑줄로 시작할 수 없습니다.
_. 네임 _스페이스는 InfluxDB 시스템 사용을 위해 예약되어 있습니다.
4-1 태그를 사용해서 쿼리 성능 향상
- 저장되는 값을 통해서 데이터를 합리적으로 인덱싱할 수 있는 경우 태그로 저장합니다.
- 저장되는 데이터가 filter() 또는 group() 함수에서 사용되는 경우 값을 태그 값으로 저장합니다.
- 저장되는 데이터가 여러 데이터 포인트, 즉 필드에 대한 메타데이터에서 공유되는 경우 값을 태그 값으로 저장합니다.
4-2 쿼리를 통해 검색하는 예시
1. userId라는 필드를 통해서 "abcde" 와 일치하는 값을 찾는다면, 모든 데이터를 조회해야 합니다.
from(bucket: "example-bucket")
|> range(start: -7d)
|> filter(fn: (r) => r._field == "userId" and r._value == "abcde")
2. 태그는 색인을 지원하므로, company라는 태그를 기준으로 필터링하여서 검색 시, 처리해야할 데이터를 줄이고 검색 성능을 올릴 수 있습니다.
from(bucket: "example-bucket")
|> range(start: -7d)
|> filter(fn: (r) => r.company == "Acme")
|> filter(fn: (r) => r._field == "userId" and r._value == "abcde")
5. Series
"series key" 는 measurments와 tag set의 유니크한 조합입니다.
예를 들어, 이전에 언급한 sample data에서는 두 개의 unique series keys를 포함하고 있습니다.
- census - location=klamath,scientist=anderson
- census - location=portland,scientist=mullen
InfluxDB에서 좋은 스키마를 설계하고 데이터를 사용할 때 시리즈의 개념을 이해하는 것은 필수적입니다.
# series key
census,location=klamath,scientist=anderson
# series
2019-08-18T00:00:00Z 23
2019-08-18T00:06:00Z 28
5. Point
포인트는 series key, a field value, timestamp 의 구성으로 이루어집니다.
예시 데이터에서 single 포인트는 다음과 같습니다.
> 2019-08-18T00:00:00Z census ants 30 portland mullen
- 중복된 데이터 처리
A는 측정 이름, 태그 집합, 타임스탬프로 고유하게 식별됩니다. 측정, 태그 집합, 타임스탬프는 동일하지만 필드 집합이 다른 라인 프로토콜을 제출하면 필드 집합은 이전 필드 집합과 새 필드 집합의 결합이 되며 충돌이 발생하면 새 필드 집합을 선호합니다.
6. Bucket
모든 influxDB 데이터는 버킷안에 저장됩니다. 버킷은 이전 influxDBv1에서 나온 retention period( RP) 와 database의 결합입니다. 하나의 버킷은 oragnization에 속하게 됩니다.
모든 버킷에는 각 데이터 포인트가 유지되는 보존 기간(RP)이 있고, 버킷의 보존 기간보다 오래된 타임스탬프가 있는 모든 포인트를 삭제합니다.
7. Oragnization
InfluxDB의 조직은 사용자 그룹을 위한 작업 공간입니다. 대시보드, 작업, 버킷 및 사용자는 조직에 속하게 됩니다.
2 .InfluxDB 데이터 모델의 빌딩 블록
Building Blocks of the InfluxDB Data Model | Additional resources | InfluxData Documentation
Thank you for your feedback! Let us know what we can do better:
docs.influxdata.com
InfluxDB 데이터 모델은 측정, 태그 및 필드로 구성됩니다. 이 모델은 InfluxDB가 데이터에서 기대하는 형태를 구성합니다. 여기에서 Jacob Marble은 각 구성 요소가 무엇인지, InfluxDB와 함께 사용하는 방법에 대해 설명합니다.
데이터 모델읋 이해하는 것은 influxDB를 사용하는 애플리케이션을 효율적으로 배포하기 위해 필수적이다.
influxd는 시계열 중심의 시리즈 데이터베이스라서 관계형 데이터베이스와 약간 다른 형식으로 데이터를 구성합니다.
- measurement에 데이터를 저장함 ( ex, weather, cpu, api .. )
- measurements는 bucket 단위로 그룹화 된다.( bucket = infrastructure )
- 버킷은 RP 단위로 데이터를 관리함
- 각 버킷을 서비스 단위 또는 저장 기간 별로 잘 분리하는 것이 중요합니다.
InfluxDB schema design | InfluxDB OSS v2 Documentation
Thank you for your feedback! Let us know what we can do better:
docs.influxdata.com
좋은 스키마 디자인은 높은 시리즈 카디널리티를 방지하여 쿼리 성능을 향상 시킬 수 있습니다.
1. 쿼리 디자인
위의 스키마 디자인은 쿼리하기 쉬운 measurements, tag keys, filed key를 나타냅니다.
airSensor와 waterQualitySensor 스키마는 아래의 가이드라인을 따르고 있습니다.
- 각 measurments는 스키마를 설명할 수 있는 간단한 이름이여야 한다.
- Keys는 스키마 내에서 반복 선언하지 않는다.
- Keys는 예약된 키워드나 특별한 문자열을 사용해선 안된다.
- Tags는 여러 데이터 포인트에 공통적으로 적용되는 메타 데이터를 저장한다.
- 필드는 숫자 데이터를 저장한다 ( 유니크하거나 매우 가변적인 데이터 저장 )
- 측정값과 키에는 데이터가 포함시키지 말고, 태그 값과 필드 값에 데이터를 저장한다.
측정값과 키를 단순하게 유지하는 것이 효율적이다.
태그 키, 필드 키, measruements 이름에 데이터를 저장하는 것이 아닌, 태크 값 또는 필드 값에 데이터를 저장시키는 것을 권장한다.
또한 데이터를 쓸 때 measurments와 key값들을 새로 생성해내지 않는 것이 카디널리티를 낮게 유지시킨다.
키를 단순하게 유지하는 것이 좋다.
아래의 지침을 따라서 키를 더 쉽게 쿼리하고 잘 관리할 수 있다.
[1] 키에 키워드와 특수 문자를 사용하지 마라.
- 쿼리 작성을 단순화하기 위해선 태그&필드 키를 예약된 키워드나 특수 문자 포함된 값으로 사용하지 안흔 것이 좋다.
( 키에 flux 키워드를 사용하면 큰 따움표로 묶엉 하고, 영숫자가 아닌 문자를 사용하는 경우 대괄호 표기법을 사용해야 한다. )
[2] 태그와 필드의 이름이 중복되지 않도록 해라.
- 동일한 스키마 내 태그 키와 필드 키가 동일한 경우 쿼리 결과 예측이 이루어지지 않는다.
디자인 예시
Recommended: the following schema stores metadata in separate crop, plot, and region tags. The temp field contains variable numeric data.
Good Measurements schema - Data encoded in tags (recommended)
-------------
weather_sensor,crop=blueberries,plot=1,region=north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,plot=2,region=midwest temp=49.8 1472515200000000000
Not recommended: the following schema stores multiple attributes (crop, plot and region) concatenated (blueberries.plot-1.north) within the measurement, similar to Graphite metrics.
Bad Measurements schema - Data encoded in the measurement (not recommended)
-------------
blueberries.plot-1.north temp=50.1 1472515200000000000
blueberries.plot-2.midwest temp=49.8 1472515200000000000
Not recommended: the following schema stores multiple attributes (crop, plot and region) concatenated (blueberries.plot-1.north) within the field key.
Bad Keys schema - Data encoded in field keys (not recommended)
-------------
weather_sensor blueberries.plot-1.north.temp=50.1 1472515200000000000
weather_sensor blueberries.plot-2.midwest.temp=49.8 1472515200000000000
2. 태그 및 필드 사용
- 유니크 값이나 숫자 데이터에 필드를 사용한다.
- 고유 하거나 자주 변경되는 값은 필드 값으로 저장한다.
- 숫자 값을 필드 값으로 저장한다 ( 태그는 문자열만 저장한다. )
- 태그를 사용하여 쿼리 향상
- 인덱싱에 사용되는 값인 경우 태그 값으로 저장한다.
- 값이 filter() 또는 group 함수에 사용되는 경우 태그 값으로 저장한다.
- 값이 여러 데이터 포인트에서 공유되는 경우 값을 태그로 저장한다.
- 태그를 통해 검색되는 포인트 수를 줄이면서 검색 성능을 향상 시킬 수 있다.
- 태그를 단순하게 유지해라
- 각 데이터 속성에 대해 하나의 태그를 사용하는 것이 좋다
- 하나의 파라미터에 여러 데이터 속성을 포함한다면 속성을 태그로 분할해라
- 태그가 데이터 속성 하나를 나타낼 떄, 쿼리에서 정규 표현식 사용량을 줄일 수 있다.
- 정규 표현식이 없는 쿼리가 가독성도 좋고 성능도 뛰어나다.
디자인 예시
Recommended: the following schema splits location data into plot and region tags.
Good Tags schema - Data encoded in multiple tags
-------------
weather_sensor,crop=blueberries,plot=1,region=north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,plot=2,region=midwest temp=49.8 1472515200000000000
Not recommended: the following schema stores multiple attributes (plot and region) concatenated within the location tag value (plot-1.north).
Bad Tags schema - Multiple data encoded in a single tag
-------------
weather_sensor,crop=blueberries,location=plot-1.north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,location=plot-2.midwest temp=49.8 1472515200000000000
Compare queries
Compare queries of the Good Tags and Bad Tags schemas. The Flux queries calculate the average temp for blueberries in the north region.
Easy to query: Good Tags data is easily filtered by region tag values, as in the following example.
// Query *Good Tags* schema, data encoded in multiple tags
from(bucket:"example-bucket")
|> range(start:2016-08-30T00:00:00Z)
|> filter(fn: (r) => r._measurement == "weather_sensor" and r.region == "north" and r._field == "temp")
|> mean()
Difficult to query: Bad Tags requires regular expressions to parse the complex location values, as in the following example.
// Query *Bad Tags* schema, multiple data encoded in a single tag
from(bucket:"example-bucket")
|> range(start:2016-08-30T00:00:00Z)
|> filter(fn: (r) => r._measurement == "weather_sensor" and r.location =~ /\.north$/ and r._field == "temp")
|> mean()
높은 시리즈 카디널리티 해결
Resolve high series cardinality | InfluxDB OSS v2 Documentation
Thank you for your feedback! Let us know what we can do better:
docs.influxdata.com
데이터 읽기 및 쓰기 속도가 느려지는 것을 발견하면, 카디널리티의 최적화를 고려하는 것이 좋습니다.
1. 높은 시리즈 카디널리티의 원인 요소
InfluxDB는 읽기 속도를 높이기 위해 측정, 태그, 필드 키 등을 인덱싱합니다.
가변적인 정보가 포함된 태그는 높은 시리즈 카디널리티라고 알려진 많은 시리즈 수를 생산하는 문제를 야기합니다.
즉, 높은 시리즈 카디널리티는 많은 시리즈로 인해 메모리 사용량이 증가하고 쓰기 실패 등의 문제를 일으킬 수 있습니다.
2. 버킷의 시리즈 카디널리티 확인
아래의 명령어를 사용하여 버킷의 시리즈 카디널리티를 확인 할 수 있습니다.
- influxdb.cardinality() : 데이터의 유니크한 시리즈 키의 값을 반환하는 Flux 함수입니다.
- SHOW SERIES CARDINALITY : InfluxQL 명령어로 위와 같습니다.
3. 높은 카디널리티 해결
1. 태그를 검토
각 태그에 대부분의 항목에 대한 고유 값이 있는지 확인합니다.
일반적인 태그 문제를 스캔하고, 로그 메시지나 타임스탬프 등으로 인해 높은 태그 값이 발생하는 문제를 확인합니다.
일반적으로 태그에 로그 메시지를 쓰거나, 타임스탬프를 쓰거나 시간이 지남에 따라 증가하는 태그 키 값들로 문제가 발생합니다.
2. 스키마 개선
도큐에서는 향후 카디널리티를 최소화하기 위해 효율적인 스키마를 설계를 검토하라고 안내합니다.
3. 높은 카디널리티를 줄이기 위한 데이터 삭제
필요 없는 높은 카디널리티를 유발하는 데이터가 있다면 삭제 고려, 전체 버킷 삭제 또는 데이터 범위 삭제를 고려하라고 제안합니다.
이러한 단계들을 통해 시리즈 카디널리티를 관리하고 성능 문제를 해결할 수 있습니다.