마크베이스 사용방법


마크베이스(Machbase)를 Grafana와 연동하기(심화편 1)

작성자
machbase
작성일
2019-03-14 15:30
조회
113

Machbase와 Grafana를 연동하는 기본적인 방법은 다른 글에서 이미 설명했다. (마크베이스(Machbase)를 Grafana와 연동하기)
하지만 가장 기본적인 사항들만 설명되었기 때문에 이 글에서는 좀더 자세한 기능에 대해서 설명한다.


1. Query 최적화


Grafana Dashboard에 사용되는 Graph는 하나의 series로만 그래프를 그리는 경우는 드물다. 대부분의 경우, 하나의 Graph에는 여러 개의 series가 존재한다. 따라서 각 Dashboard에는 많은 series가 존재하게 된다.
Graph를 그리기 위해서는 DB에서 data를 얻어야하기 때문에 series가 많다는 것은 그만큼 DB에 부담을 많이 준다는 뜻이 된다. 더구나 Grafana Dashboard는 주기적으로 refresh가 되기 때문에 그때마다 다시 data를 얻어 온다. 여기에 더해서 복수의 사용자가 같은 Dashboard에 접속하게 되면 각각의 사용자마다 DB에 주는 부담이 배가 된다.
하나의 Query로 여러 개의 series의 결과를 얻을 수 있다면 DB에 주어지는 부담을 많이 줄일 수 있다. Machbase는 이 문제를 밑에서 설명하는 Same as라는 option을 통해서 해결하고 있다.


아래의 Dashboard의 경우 대략 60개(6+(5*9)+8=59) 정도의 series로 구성되어 있으며 10초 주기로 refresh하도록 설정되어 있다. 이 Dash board에 5명이 접속해 있다면 매 10초마다 DB에서 300개 정도의 series data를 읽어야 한다.

Grafana는 서버에서 Graph를 만들어서 Client로 화면을 보내는 것이 아니라 각각의 단말에서 데이터를 읽어서 Graph를 그리는 것이기 때문에 사용자가 많을 수록 DB에 많은 부담을 주게된다.


Grafana와 DB간에 통신을 하도록 해주는 plugin이 Datasource인데 아래와 같이 DB와 data를 주고 받는다. 



Grafana request object format


Grafana는 Datasource로 아래와 같은 형식의 json data를 전달한다.(아래의 format은 가장 기본적인 sample이다) 여기서 targets 의 내용은 Graph plugin 설정의 metric tab에서 사용자가 입력하는 내용이 추가되어 있다. 이 object의 내용은 metric tab의 입력에도 사용되는 것이기 때문에 불필요하거나 중복되는 부분도 많을 수 밖에 없다.


Request object passed to datasource

{
"range": { "from": "2015-12-22T03:06:13.851Z", "to": "2015-12-22T06:48:24.137Z" },
"interval": "5s",
"targets": [
{ "refId": "B", "target": "upper_75" },
{ "refId": "A", "target": "upper_90" }
],
"format": "json",
"maxDataPoints": 2495
}

Datasource plugin은 전달받은 내용을 Database에서 Query를 생성하기 편하도록 가공해서 Database에 전달한다.(정확히는 Database에서 data를 얻어오는 URL을 호출)
여기서 중요한 것은 targets array로 series를 구성하는 정보를 담겨있다. 이 array의 순서에 정확히 대응되도록 결과가 return되어야 한다.
Machbase Datasource가 MWA로 전달하는 정보는 다음과 같다.


Request object passed to Machbase(MWA)

{
  "targets": [
    {
      "colinput": "select",
      "column": "COLLECTOR_CHECKSUM1",
      "downsampling": "AVG",
      "sampling": { "value": 0, "unit": "", "input": "" },
      "filters": [],
      "groupfield": "(NONE)",
      "hide": false,
      "limits": "",
      "metric": "MACHBASE_TABLE",
      "name": "",
      "query": "",
      "rawQuery": false,
      "refId": "A",
      "sameAs": "",
      "timefield": "_arrival_time",
      "orderby": "",
      "xinput": "time",
      "useduration": "Y",
      "duration": ""
    },
    {
      "colinput": "select",
      "column": "COLLECTOR_CHECKSUM1",
      "downsampling": "MIN",
      "sampling": { "value": 0, "unit": "", "input": "" },
      "filters": [],
      "groupfield": "(NONE)",
      "hide": false,
      "limits": "",
      "metric": "MACHBASE_TABLE",
      "name": "",
      "query": "",
      "rawQuery": false,
      "refId": "B",
      "sameAs": "A",
      "timefield": "_arrival_time",
      "orderby": "",
      "xinput": "time",
      "useduration": "Y",
      "duration": ""
    },
    {
      "colinput": "text",
      "column": "count(*)",
      "downsampling": "COUNT",
      "sampling": { "value": 0, "unit": "", "input": "" },
      "filters": [],
      "groupfield": "(NONE)",
      "hide": false,
      "limits": "",
      "metric": "MACHBASE_TABLE",
      "name": "",
      "query": "",
      "rawQuery": false,
      "refId": "C",
      "sameAs": "A",
      "timefield": "_arrival_time",
      "orderby": "",
      "xinput": "time",
      "useduration": "Y",
      "duration": ""
    }
  ],
  "range": { "from": "2019-03-06T20:35:53.221Z", "to": "2019-03-07T02:35:53.221Z", "raw": { "from": "now-6h", "to": "now" } },
  "start_absolute": 1551904553221,
  "end_absolute": 1551926153221,
  "interval": { "value": "15", "unit": "second", "input": "15s" },
  "limits": 1487,
  "panelId": 1,
  "pluginid": "graph",
  "timeColumn": "",
  "timeStamp": 0
}

Grafana로 return되는 Time series response는 기본적으로 아래와 같이 구성된다. (graph의 경우를 예로 든 것이고 table plugin은 다르다.)


[
{
"target":"upper_75",
"datapoints":[
[622, 1450754160000],
[365, 1450754220000]
]
},
{
"target":"upper_90",
"datapoints":[
[861, 1450754160000],
[767, 1450754220000] // value, timestamp
]
}
]

이 return 되는 값이 Request object의 targets와 정확히 대응이 되어야 정상적으로 Graph가 그려지게 된다.


Same as option


위에 설명한 data format을 보면 결국 series하나에 한번의 query를 수행하게 되는 것이 일반적이다. 따라서 위에서 예를 든 Dashboard의 경우 한번 refresh할 때마다 60여번의 Query를 수행하게 된다. 접속자 수가 많다면 그만큼 더 많은 Query가 수행되게 된다.
DB 서버의 성능이 아주 좋아서 엄청나게 많은 Query를 동시에 수행해도 아무 문제가 없다면 모르겠지만 서버의 자원은 한정적이기 때문에 가능한 부담을 덜어주는 것이 좋다.
Table의 구조가 Time + Key + Value의 구조라면 별 수 없이 각각의 series마다 Query를 수행해야 하겠지만, Time + Key + Value1 + Value2 + .... 의 구조라면 하나의 Query로 여러 개의 Series를 얻을 수 있다. 또는 같은 Key 값의 average, sum, count 등을 하나의 Graph로 그릴 때도 마찬가지로 한번의 Query로 구현이 가능하다.


Machbase는 하나의 Query로 여러개의 series의 data를 얻을 수 있는 기능을 Same as라는 option을 통하여 지원한다.



  • Same as option은 첫번째 series에는 지정할 수 없으며 2번째 series부터 지정이 가능하다.

  • 기능은 단순히 지정한 series와 모든 것이 같고 column과 series title만 다르다는 의미이다.

  • 이것을 지정하면 지정된 series와 통합되어 Query가 실행되어서 Query 수행 횟수를 줄일 수 있다.


위의 그림과 같이 B와 C의 Same as가 모두 A로 설정된 경우 Machbase DB의 return 값을 살펴보면 아래와 같다. Machbase의 response에는 사용자의 편의를 위해 몇가지 값이 추가로 포함되어 있다.


[
{
"refId": "A",
"query": "SELECT UNIX_TIMESTAMP(DATE_TRUNC('second', _arrival_time, 15)) AS _TIME_, AVG(COLLECTOR_CHECKSUM1), MIN(COLLECTOR_CHECKSUM1), count(*) FROM MACHBASE_TABLE GROUP BY _TIME_ ORDER BY 1 ASC LIMIT 1487 DURATION FROM 1551904553221000000 TO 1551926153221000000",
"timecolumn": "UNIX_TIMESTAMP(DATE_TRUNC('second', _arrival_time, 15))",
"target": "MACHBASE_TABLE:AVG(COLLECTOR_CHECKSUM1)",
"datapoints": [
[2049, 1551923115000],
......
[2049, 1551924210000]
]
},
{
"refId": "B",
"query": "SELECT UNIX_TIMESTAMP(DATE_TRUNC('second', _arrival_time, 15)) AS _TIME_, AVG(COLLECTOR_CHECKSUM1), MIN(COLLECTOR_CHECKSUM1), count(*) FROM MACHBASE_TABLE GROUP BY _TIME_ ORDER BY 1 ASC LIMIT 1487 DURATION FROM 1551904553221000000 TO 1551926153221000000",
"timecolumn": "UNIX_TIMESTAMP(DATE_TRUNC('second', _arrival_time, 15))",
"target": "MACHBASE_TABLE:MIN(COLLECTOR_CHECKSUM1)",
"datapoints": [
[2049, 1551923115000],
......
[2049, 1551924210000]
]
},
{
"refId": "C",
"query": "SELECT UNIX_TIMESTAMP(DATE_TRUNC('second', _arrival_time, 15)) AS _TIME_, AVG(COLLECTOR_CHECKSUM1), MIN(COLLECTOR_CHECKSUM1), count(*) FROM MACHBASE_TABLE GROUP BY _TIME_ ORDER BY 1 ASC LIMIT 1487 DURATION FROM 1551904553221000000 TO 1551926153221000000",
"timecolumn": "UNIX_TIMESTAMP(DATE_TRUNC('second', _arrival_time, 15))",
"target": "MACHBASE_TABLE:count(*)",
"datapoints": [
[2567, 1551923115000],
......
[ 5, 1551924210000]
]
}
]

 

query를 살펴보면 3개가 모두 같은데 SELECT 의 column부분이 AVG(COLLECTOR_CHECKSUM1), MIN(COLLECTOR_CHECKSUM1), count(*)로 한번의 Query로 결과를 얻게된다. 실제로 Machbase는 한번의 Query만 수행해서 결과를 return한다.


따라서 Grafana에서 사용할 Table의 구조는 가능한 한번의 Query로 모든 data를 얻을 수 있도록 설계하는 것이 좋다.


2. Alarm


Grafana Dashboard를 사용하면서 Graph에 표현되는 값을 이용해서 특정 조건을 위반하는 경우 경고를 발생시켰으면 하는 경우가 있다. 이런 경우 alert 기능을 이용하면 완벽한 것은 아니지만 간단한 alarm은 사용할 수 있다.
Graph를 그리는데 사용되는 data를 이용해서 위반여부를 확인하므로 별도의 Query를 수행할 필요가 없다는 장점이 있다.


Alarm 설정


먼저 화면의 use alert 버튼을 클릭하면 alert 조건 설정화면이 나타난다.



실제 Graph에 사용된 값(return 값중에서 datapoints)을 기준으로 조건을 설정하면 된다. 복수의 조건을 설정하는 경우 차례대로 실행된다.



(1) checkbox : global condition 설정


check 여부 설명
checked 여러 series의 조건이 모두 만족되어야 하는 경우 사용된다. check된 모든 조건이 만족되어야 alert가 발생한다. series 내의 조건 검색으로는 사용되지 않는다.
not checked 설정된 series내의 조건만 만족하면 alert가 발생한다.

(2) reducer : 조건에 사용될 값을 구하는 함수


reducer 설명
avg 평균(sum / cnt)
min 최소값
max 최대값
sum
count 건수
last 최근값
diff 시작값과 마지막값의 차
diff_minmax 최소값과 최대값의 차
cnt_null null 값의 수
cnt_not_null count - cnt_null
percent_diff 시작값과 마지막값의 차 / 시작값과 마지막값의 평균 * 100

(3) data range : reducer를 적용할 data 범위


data range 설명
of all data DB에서 return된 전체 값을 대상으로 계산
of datas in A 최근 시간범위(A)의 data를 대상으로 계산 (e.g. A = 5m, 10m, 2h 등)

(4) 비교연산자 : 실제 비교 연산


연산자 설명
is above A 계산된 값이 A보다 크다.
is below A 계산된 값이 A보다 작다.
is outside range A, B 계산된 값이A와 B 사이에 있지 않다.(A, B는 포함되지 않음)
is within range A, B 계산된 값이 A와 B 사이에 있다.(A, B는 포함되지 않음)
has no value 값이 없음

설정된 조건에 해당되는 경우 Dashboard에 alert가 나타나고, MWA에 mail 설정이 되어 있는 경우 alert mail이 발송된다.


Alert mail 설정


$MACHBASE_HOME/webadmin/flask/mail.conf에 alert mail 발신 환경을 설정한다. 이 파일을 다른 이름으로 변경하면 mail이 발신되지 않는다.


mail.conf


mail server 설정

TLS/SSL = SSL
SMTP_SERVER = smtp.naver.com
SMTP_PORT = 465
USER_ID = user@email.com
PASSWORD = password

mail 내용 설정

SUBJECT = subject
SENDER = user@email.com
RECEIVER = receiver@email.com
FROM = alert_test
TO =
CONTENTS = Alert has occured!!\nPlease refer below.\n\n{{message}}\n-----

 

mail 내용 설정에서 SUBJECT는 mail의 제목을 나타내고 CONTENTS는 mail의 내용을 나타낸다. 이때 \n은 줄바꿈으로 변환되고 {{message}}는 Grafana에서 전달되는 message로 대체된다.


Grafana에서 전달되는 message

Alert information.
Graph Title : alert 발생한 series Title
Duration : Grafana Time range
Alert Time : alert 발생 시간
Condition : 위반된 조건


  • mail.conf 를 수정했다면 MWA를 재시작해야 수정된 내용이 적용된다.

전체 24
번호 제목 작성자 작성일 추천 조회
24
마크베이스(Machbase)를 Grafana와 연동하기(심화편 1)
machbase | 2019.03.14 | 추천 1 | 조회 113
machbase 2019.03.14 1 113
23
마크베이스 V5 와 Apache Kafka 연동
machbase | 2019.03.05 | 추천 1 | 조회 155
machbase 2019.03.05 1 155
22
마크베이스 V5 : Tutorial 6 (RestAPI with curl)
machbase | 2018.09.18 | 추천 1 | 조회 438
machbase 2018.09.18 1 438
21
마크베이스(Machbase) Tag Analyzer 사용법
machbase | 2018.08.27 | 추천 2 | 조회 590
machbase 2018.08.27 2 590
20
마크베이스 5.0 : Tutorial 4 (실제 데이터를 통한 Tag Analyzer 기초 활용)
machbase | 2018.08.27 | 추천 1 | 조회 384
machbase 2018.08.27 1 384
19
마크베이스 5.0 : Tutorial 5 (Tag Table with RestAPI)
machbase | 2018.08.24 | 추천 0 | 조회 405
machbase 2018.08.24 0 405
18
Machbase 5.0 : 센서데이터 홍수의 유일한 해결책
machbase | 2018.08.21 | 추천 0 | 조회 772
machbase 2018.08.21 0 772
17
마크베이스 5.0 : Tutorial 3 (Real Time Stream Insert : Many Sensors)
machbase | 2018.08.20 | 추천 0 | 조회 543
machbase 2018.08.20 0 543
16
마크베이스 5.0 : Tutorial 2 (Batch Loading : Many Sensors)
machbase | 2018.08.17 | 추천 0 | 조회 434
machbase 2018.08.17 0 434
15
마크베이스 5.0 : Tutorial 1 (Quick Start)
machbase | 2018.08.17 | 추천 0 | 조회 817
machbase 2018.08.17 0 817