top of page

마크베이스가 인플럭스DB보다 IoT 디바이스에 최적화된 초고속 시계열 DBMS인 이유는?

Machbase에 DHT11 온습도 센서 입력 및 데이터 조회 해보기


개요


마크베이스는 IoT에 최적화된 초고속 시계열 DBMS이다. 산업 현장의 운영 최적화와 예측 분석을 위해 데이터 병합과 모니터링 기능을 제공한다. 라즈베리파이와 같은 소형 컴퓨터에서도 빠른 속도의 입력과 분석을 할 수 있도록 해준다. 하지만, 기초적인 데이터베이스의 이용에 대한 지식밖에 없는, 사실 시계열 데이터베이스라는말 자체에도 생소함을 느끼는 초보 개발자들에게는 어렵게 다가올 수 있는 개념이다. 이 글을 쓰는 나 또한, 데이터 베이스나 SQL, 쿼리 등 데이터베이스 분야에서 지식이 거의 없다시피 하다. 이런 초보자들도 쉽게 이해하고 마크베이스 제품에 쉽게 접근하고, 사용할 수 있도록 주변에서도 쉽게 접할 수 있는 센서를 가지고 간단하게 “마크베이스 이용 가이드”를 작성해보고자 한다.


필자는 마크베이스 뿐만 아니라 InfluxDB라는 세계적으로 유명한 시계열 DBMS 또한 잠시 사용해보았다. 두 제품을 모두 사용해본 입장에서 마크베이스는 InfluxDB와 비교해도 전혀 부족한 점이 없는 성능과 사용성을 보였으며 속도 면에서는 오히려 InfluxDB에서 크게 압도하는 측면도 있었다. 특히나 일반 컴퓨터와 달리 제한된 하드웨어적 성능을 가진 라즈베리파이에서 입력과 쿼리에서 InfluxDB를 압도하는 속도를 보여주었다. 그렇기에 이 글을 보는 사용자들이 마크베이스를 선택한 것을 전혀 후회하지 않을 것임을 장담할 수 있다.


본론에 들어가기 앞서, 앞으로 진행해볼 가이드에서 어떤 것을 할지 간단하게 정리해보자. 먼저 기본이 되는 마크베이스를 설치해보자. 정적인 이미 만들어진 데이터를 사용하는 것보다는 실시간으로 생성되는, 보다 실무에 가까운 데이터를 이용하는게 체험에 있어 좋다고 생각한다. 그렇기에 DHT11이라는 IoT 온습도 센서를 이용해보고자 한다. DHT11 센서를 라즈베리파이에 연결하면 온도와 습도 데이터를 시간 단위로 얻을 수 있다. 이 데이터들을 마크베이스db에 입력하고, 외부 툴을 이용해 그래프화 해서 데이터 처리의 한 흐름을 넓게 이해해 볼 것이다. 설치부터 이용까지 세세하게 정리해 놓았으므로 쉽게 진행할 수 있다.


Machbase


Machbase-neo 설치하기


마크베이스 DB를 이용하려면 Macbase-neo를 설치해야 한다. Machbase-neo는 라즈베리파이와 같은 소형 컴퓨터부터 하이엔드 서버 다양한 범위의 서버에서 사용할 수 있으며 친숙한 문법의 MachSQL을 사용할 수 있다. 또한, HTTP, MQTT, gRPC을 통해 다양한 방식으로 데이터를 쓰고 쿼리할 수 있어 마크베이스 사용을 쉽게 만들어준다.


https://neo.machbase.com/에서 설치 방법을 소개하기에 참고하길 바란다. 마크베이스의 또 다른 장점은 설치가 상당히 쉽다는 것이다. 그저 압축 파일을 받아 풀고 서버를 실행하면 끝이다.


https://neo.machbase.com/에서 최신 버전의 Linux arm64 버전의 Edge edition 압축 파일을 다운로드하자. 버전은 지속적으로 업데이트 되므로 아래의 버전과 달라도 상관없다.



원하는 디렉토리에 압축을 풀자.



압축을 풀면, 하위 디렉토리에 machbase-neo 실행 파일이 존재할 것이다. serve를 통해 서버 구동을 시작하자.



서버 구동시에 같은 디렉토리에 Machbase 이름의 데이터 디렉토리가 생길 것이다. 앞으로 서버를 통해 입력되는 데이터나 세팅이 저장되는 디렉토리이다. 만약 상위 버전으로 업데이트 등의 이유로 재설치를 하게 된다면 Machbase 디렉토리를 새로운 Machbase 디렉토리로 옮겨줌으로써 데이터 보존이 가능하다. 서버를 시작하면 서버 화면이 출력되는데 여기서 포트를 확인할 수 있으니 적절하게 사용하면 된다.


다음의 명령어로 SQL 쉘 모드로 들어갈 수 있다. 여기서는 테이블 생성, 삭제, 출력, 쿼리 등 다양한 기능을 사용할 수 있다.



DHT11 센서는 무엇인가?


DHT11 센서에 대해 모르는 사람이 별로 없을 거라고 생각하지만, 간단하게 이야기해보자.



DHT11 센서는 온도와 습도 데이터를 실시간으로 시리얼 데이터로 얻을 수 있는 8비트 마이크로 컨트롤러이다. 아두이노나 라즈베리파이 등 소형 IoT기기에서 다양하게 쓰이며 구하기 쉽다. 섭씨 0~50도 범위의 온도와 20~90% 범위의 습도를 측정할 수 있다. 3가지의 핀으로 구성되어 있다. 각각 VCC, DAT, GND로, VCC는 3V 또는 5V사이의 파워를 받고, DAT은 본체로 데이터를 전달해주며 GND은 접지 역할을 한다.


라즈베리파이4와 연결하기



DHT11 센서를 라즈베리파이 본체와 연결해보자. 위의 핀맵을 보면서 DHT11의 각 핀의 역할에 맞게 연결하면 된다. VCC는 5V power(pin 2)와 연결하고, DAT은 GPIO 2(pin 4)에 연결한다. GND는 Ground(pin 6)에 연결한다. 연결이 매우 간단하다. 딱히 신경 쓸 부분은 없지만, GPIO 2에 연결했다는 점은 기억하자. 이는 데이터를 얻는 코드에서 사용된다. 연결이 되었으면 다음과 같이 센서에 붉은 LED가 들어올 것이다.



DHT11 데이터를 얻어 텍스트화 해보기


DHT11의 사용법을 이해하기 위해서 간단하게 데이터를 얻어 csv형식으로 출력해보자. 여기서 csv란 데이터가 “,”로 나뉘어진 데이터 형식을 말한다. 사용하는 DB에 맞춰서 형식을 변경하기에 편한 포맷이기에 raw한 데이터를 기록할 때 많이 쓰인다. 코드는 파이썬을 기반으로 작성했다. 사실 성능면에서는 제한된 환경의 라즈베리파이에서 파이썬을 주력으로 쓰기에는 어려움이 많다. 하지만, dht11처리를 위한 Adafruit 모듈을 비롯해 다양한 api를 제공하며 그에 대한 docs가 잘 되어 있기에 파이썬을 선택했다.


Adafruit는 라즈베리파이에 기본적으로 깔려 있지 않다. 설치해보자.



기본적인 사용법은 다음과 같다.


adafruit_dht 모듈을 import한다.



DHT11 디바이스를 초기화 하고, 온도와 습도를 얻는다. GPIO2를 연결했기에 핀 넘버는 2이다.



3초마다 온도와 습도 데이터를 얻어 측정 당시의 시간과 함께 CSV 형태로 콘솔창에 출력하자. 시간은 보통 unix time 포맷을 사용한다. unix time( = Epoach, Posix time)은 1970년 1월 1일 00:00:00 UTC 을 기준으로 현재까지 누적된 초를 나타낸다. 나노 단위까지 표현하기도 하며, 일반적으로 DB에 나노초 단위까지도 입력한다. 하지만 이번 코드는 초 단위까지만 출력했다.


datetime.datetime.now(datetime.timezone.utc).timestamp()는 utc를 기준으로 unix time을 출력한다.


Adafruit_DHT.read_retry(self.sensor,self.pin) 메소드는 호출 당시의 습도와 온도 데이터를 얻는다.



dht_csv_print.py로 저장하여 실행해보았다. 콘솔창 출력 결과는 다음과 같다.



위의 형식이 csv형태이다. 물론 보기에는 복잡하고 가시성이 떨어지지만 대량의 데이터를 작은 용량으로 저장할 수 있으며 변환이 용이하다.


실시간으로 온,습도 데이터를 Machbase에 입력하기


DHT11 사용법을 알았으니 이제 직접 db에 데이터를 올려 보자. 동일하게 3초 주기로 데이터를 얻어올 것이며 파이썬으로 작성한다. 마크베이스는 mqtt, rest등 여러 가지 입력 방법을 제공하지만, rest API가 가장 간단하고 파이썬에서 쓰기 쉬워서 이를 이용한다. 파이썬에서는 requests 모듈을 import 하면 http 프로토콜을 간단한 메소드로 이용할 수 있다.


코드는 모듈처럼 사용할 수도 있게 마크베이스 클래스를 따로 만들어 이용했다. 클래스는 받은 데이터를 적절한 JSON 포맷으로 변경해주는 to_jsonmessage() 메소드와 데이터를 db에 올리는 write_data_machbase() 메소드로 구성했다. 내용은 쉬우므로 이해에 어려움이 없을 것이다. 알아야 할 점은 write_data_machbase()에서 requests의 post 결과로 응답값이 오는데 응답값이 200일 때만 입력 성공이라는 점이다.


데이터는 리스트 형태로 받아올 것이다. 이전처럼 csv 파일에 데이터를 받아올 수도 있지만, 같은 코드파일에서 데이터를 받아 즉시 입력할 것이어서 파싱이 쉽도록 리스트로 받았다.. 3초마다 루프를 돌려 데이터를 얻어 마크베이스 db에 입력하도록 했다.


이 부분에서 시행착오가 있었다. 처음에 생각하기에는 혹시나 db에 입력하는 과정에 병목이 생겨 3초마다 정확하게 데이터를 얻지 못할 경우도 있을까 싶어 데이터를 얻는 프로세스를 따로 지정해 “멀티 쓰레드” 또는 “멀티 프로세스”를 적용하려고 했다. 하지만, 직접 사용해보니 파이썬은 효율적인 멀티 성능을 만들어내지 못하고 오히려 기존보다 더 큰 병목 현상을 만들어내어 데이터를 3초보다 훨씬 긴 시간동안 얻지 못하는 상황이 발생했다. 오히려 “멀티”를 포기하고 나니 3초마다 데이터가 정확하게 얻어졌다.


루프마다 데이터를 얻고, 마크베이스에 입력하고, 그동안의 시간을 측정하여 3초에서 뺀 만큼 프로세스를 슬립하는 방법을 택했다. 이렇게 하니 정확하게 3초마다 기록이 되었다. 구성 코드는 다음과 같다.


==================================================================

import datetime, time

import Adafruit_DHT

import json

import requests

class machbase():

def init(self, url :str, table :str):

self._url = url

self._tablename = table

self._header = {'Content-Type': 'application/json; charset=utf-8'}

def to_jsonmessage(self, dataset):

table_dict = dict()

table_dict["table"] = self._tablename

data_dict = dict()

data_dict["columns"] = ["sensorname", "time", "value"]

row_list = list()

row_list.append(["temperature", dataset[2], dataset[0]])

row_list.append(["humidity", dataset[2], dataset[1]])

data_dict["rows"] = row_list

table_dict["data"] = data_dict

return table_dict

def write_data_machbase(self, record):

table_dict = self.to_jsonmessage(record)

table_json = json.dumps(table_dict)

response = requests.post(url = self._url, data = table_json, headers = self._header)

if response.status_code == 200:

print("Http post success!")

return 0

else:

print("Http post failed!")

return -1

if name == "__main__":

machbase_table = "TEMP_HUM_EXAMPLE"

pinnum = 2

machbase_client = machbase(url = machbase_url, table = machbase_table)

while True:

start = float(time.time())

utctime = int(datetime.datetime.now(datetime.timezone.utc).timestamp())*1000000000

hum, temp = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11 ,pinnum)

if hum is not None and temp is not None:

datalist = list()

datalist.append(float(temp))

datalist.append(float(hum))

datalist.append(utctime)

machbase_client.write_data_machbase(datalist)

stop = float(time.time())

elapsed = stop - start

sleep_t = 3 - elapsed

if sleep_t >= 0:

time.sleep(sleep_t)

==================================================================


마크베이스에서 http 프로토콜에 쓰는 json 포맷은 다음과 같다.

name은 tag key의 이름, time은 timestamp, value는 tag의 실제 값을 나타낸다.



파이썬 프로그램을 실행했고, 입력이 시작되었다.


30분 정도 뒤에 machsql 쉘 화면에서 select * from TEMP_HUM_EXAMPLE 을 통해 데이터를 확인했다.


==================================================================

gon@raspberrypi:~/Desktop/exer ./machbase shell sql "select * from TEMP_HUM_EXAMPLE"

║38 temperature 2023-01-26 04:35:09.000000 26.000000

║39 humidity 2023-01-26 04:35:06.000000 19.000000

║40 temperature 2023-01-26 04:35:06.000000 26.000000

║41 temperature 2023-01-26 04:35:03.000000 26.000000

║42 humidity 2023-01-26 04:35:03.000000 19.000000

║43 temperature 2023-01-26 04:35:00.000000 26.000000

║44 humidity 2023-01-26 04:35:00.000000 19.000000

║45 humidity 2023-01-26 04:34:57.000000 19.000000

║46 temperature 2023-01-26 04:34:57.000000 26.000000

==================================================================


데이터가 성공적으로 입력되고 있었다. 일주일 정도 프로그램을 켜놓고 데이터를 입력했다.


간단하게 이용해 볼 수 있는 쿼리


데이터를 입력했다고 끝이 아니다. 데이터를 입력하기만 하고 전체 데이터를 출력하기만 하면 사실 DB를 이용할 이유가 없다. 사용자가 원하는 방향에 맞춰 테이블을 정리하고 필터링하여 원하는 값만 출력되도록 쿼리를 해봐야 한다. 마크베이스에서 쿼리를 어떻게 하면 되는지 알려주기 위해 두 가지 간단한 쿼리를 진행해보겠다.


1. temperature, humidity의 최곳값 구하기

MachSQL은 기본 SQL과 거의 유사한 문법을 제공한다.

최곳값 구하는 max 함수와 group by를 이용해서 쿼리해보자.




2. 1시간마다 temperature, humidity 값의 평균 구하기

마크베이스는 date_trunc() 함수를 통해 원하는 시간 단위로 테이블을 자를 수 있다.

세 가지 인자가 들어가는데 첫 인자는 시간 표현의 단위로 ‘h’(시간), ‘m’(분) 등 다양한 단위 입력 이 가능하다. 두 번째 인자는 TIME을 입력하고, 세 번째 인자는 선택한 시간 단위의 인터벌을 의 미 한다. 에를 들어, 한 시간 단위로 테이블을 자르고 싶으면 date_trunc(‘h’, TIME, 1) 이런 식으로 입력한다.


==================================================================

select name, avg(value), date_trunc('hour', TIME, 1) as _TIME from temp_hum_example

group by _TIME,

name order by _TIME;

==================================================================



데이터양이 많더라도 매우 빠른 시간으로 결과를 출력해 낸다. SQL 문법에 대해 알고 있으면 간단하게 쿼리를 하고 원하는 방향으로 테이블을 출력할 수 있다. 다양한 쿼리를 시도해보자. 문법도 쉽고, 기존이랑 거의 유사하여 쉽게 접근할 수 있을 것이다.


정리

기본적으로 마크베이스 서버를 구동하고 이용하기 위해서는 machbase-neo 설치가 필요하다. machbase-neo는 압축 파일을 받아 풀면 바로 사용할 수 있어 편하다. 서버를 구동한 뒤, DHT11 센서에서 온,습도 데이터를 받아 DB에 입력해봤다. 파이썬에 따로 마크베이스 api가 마련되어 있지는 않지만 requests 모듈을 이용하면 쉽게 http post가 가능하여 마크베이스 http에 맞는 json 형식만 만들어지면 쉽게 데이터를 입력할 수 있었다. 하지만, 클라이언트 라이브러리가 없는 점은 아쉬운 점이었다. 쿼리는 범용적인 SQL언어와 유사한 MachSQL을 사용할 수 있었다. 쿼리 과정 또한, 콘솔창에서 SQL 쉘 모드를 열면 콘솔상으로 원하는 쿼리문을 실행할 수 있었기에 사용성이 뛰어났다. 대량의 데이터에 대해서도 쿼리 결과를 출력하는데 거의 1초 걸리지않는 빠른 속도를 보여줬다.


마크베이스를 공부하고 이용한지 한 달 정도 되었다. 필자는 마크베이스를 비롯한 DB 분야에 대해 거의 문외한이었다. 하지만, 초보자의 입장에서 마크베이스를 바라볼 때, 마크베이스는 접근하기 쉬운 DB였다. 또한, 필자는 모든 과정을 라즈베리파이라는 IoT 디바이스에서 진행했다. 마크베이스는 이런 제한된 하드웨어에서도 뛰어난 입력성능과 쿼리성능을 보여줬다. 덕분에 부담 없이 다양한 크기의 데이터를 입력하고 시험해 볼 수 있었다. 그리고 이런 대부분의 작업을 콘솔 창에서 진행할 수 있었다. 대부분 작업을 ssh로 연결하여 사용했는데 마크베이스를 사용할 때는 모니터를 연결할 일이 없었다. 사용자는 저렴한 가격의 라즈베리파이 하나만 있어도 자유롭게 원격 접속하여 마크베이스를 사용할 수 있다. 필자는 이 부분을 큰 장점으로 생각한다. 이 글을 보는 사용자들도 가볍게 접근할 수 있는 마크베이스를 체험해 보길 바란다.



조회수 16회댓글 0개

Comments


단락 텍스트입니다. 텍스트를 추가 및 편집하려면 여기를 클릭하세요.  

bottom of page