一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

EMQX發表於2019-12-05

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

背景

本文以常見物聯網使用場景為例,介紹瞭如何利用 EMQ X 訊息中介軟體與開源資料視覺化方案 InfluxDB + Grafana ,將物聯網裝置大量基於時序的資料便捷地展示出來。

在物聯網專案中接入平臺的裝置資料和儲存方案以下特點:

  • 資料採集的維度,頻率,以及裝置數量都比較多,採集的資料量比較大,對訊息伺服器接入點吞吐量、後端資料庫資料儲存空間消耗有很大壓力;
  • 資料按照採集週期進行上報、傳輸、儲存是一般都按照時間序列;

因此在物聯網專案中使用時序資料庫是比較好的選擇。時序資料庫可以帶來顯著的效能的提升,包括更高的容納率、更快的大規模查詢(部分資料庫比其他關聯式資料庫支援更多的查詢),以及更好的資料壓縮率等。資料入庫後,往往需要其他方式如資料視覺化系統將資料按照規則統計、展現出來,實現資料的監控、指標統計等業務需求,以便充分發揮資料的價值。

業務場景

假設現有一批裝置,每個裝置有一個 Client ID,所有裝置均通過 MQTT 協議往 MQTT 訊息伺服器上相應的主題傳送資料,主題的設計如下:

devices/{client_id}/messages
複製程式碼

每個裝置傳送的資料格式為 JSON,傳送的通過該感測器採集的溫度與溼度資料。

{
    "temperature": 30,
    "humidity" : 20
}
複製程式碼

現在需要實時儲存以便在後續任意時間檢視資料,提出以下的需求:

  • 每個裝置按照每 5 秒鐘一次的頻率進行資料上報,資料庫需儲存每條資料;
  • 通過視覺化系統檢視任意時間區間內的溫度/溼度平均值、最大值、最小值與所有資料中溫度/溼度的平均值。

最終效果

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

儀表盤右上角可以選擇時間區間、自動重新整理時間,此時裝置持續傳送資料,儀表盤資料值會隨之變化,實現了比較好的視覺化效果。

方案介紹

目前市面上已有多款物聯網訊息中介軟體、時序資料庫和資料視覺化產品,結合資料的採集上報、聯網接入、訊息儲存與視覺化功能來看,EMQ X(高效能物聯網 MQTT 訊息中介軟體) + InfluxDB(時序資料庫)+ Grafana(美觀、強大的視覺化監控指標展示工具)組合無疑是最佳的物聯網資料視覺化整合方案。

方案整體架構如下圖所示:

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

  • EMQ XEMQ X 是基於高併發的 Erlang/OTP 語言平臺開發,支援百萬級連線和分散式叢集架構,釋出訂閱模式的開源 MQTT 訊息伺服器。EMQ X 內建了大量開箱即用的功能,其企業版 EMQ X Enterprise 支援通過規則引擎或訊息持久化外掛將裝置訊息高效能地儲存到 InfluxDB,開源使用者需自行處理訊息儲存環節。
  • InfluxDB:InfluxDB 是一個由 InfluxData 開發的開源時序型資料庫。它由 Go 寫成,著力於高效能地查詢與儲存時序型資料。InfluxDB 被廣泛應用於儲存系統的監控資料,IoT 行業的實時資料等場景。
  • Grafana: Grafana 是一個跨平臺、開源的度量分析和視覺化工具,可以通過將採集的資料查詢然後視覺化的展示。它可以快速靈活建立的客戶端圖表,皮膚外掛有許多不同方式的視覺化指標和日誌,官方庫中具有豐富的儀表盤外掛,比如熱圖、折線圖、圖表等多種展示方式;支援 Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和 KairosDB 等資料來源,支援資料項獨立/混合查詢展示;可以建立自定義告警規則並通知到其他訊息處理服務或元件中。

實現步驟

安裝 EMQ X、InfluxDB 與 Grafana

本文所用各個元件均有 Docker 映象,除 EMQ X 需要修改少數配置為了便於操作使用下載安裝外,InfluxDB 與 Grafana 均使用 Docker 搭建,詳細的安裝步驟本文不再贅述。

三大部件官網均有不同作業系統/平臺的服務或安裝包資源與教程:

EMQ X Enterprise 安裝

安裝

如果您是 EMQ X 新手使用者,推薦通過 EMQ X 指南 快速上手

訪問 EMQ 官網 下載適合您作業系統的安裝包,由於資料持久化是企業功能,您需要下載 EMQ X 企業版(可以申請 License 試用) 寫本文的時候 EMQ X 企業版最新版本為 v3.4.5,該功能需要使用該版本及以上版本,下載 zip 包的啟動步驟如下 :

## 解壓下載好的安裝包
unzip emqx-ee-macosx-v3.4.4.zip
cd emqx

## 將 License 檔案複製到 EMQ X 指定目錄 etc/, License 需自行申請試用或通過購買授權獲取
cp ../emqx.lic ./etc

## 以 console 模式啟動 EMQ X
./bin/emqx console
複製程式碼

修改配置

本文中需要用到的配置檔案如下:

  1. License 檔案,EMQ X 企業版 License 檔案,使用可用的 License 覆蓋:
etc/emqx.lic
複製程式碼
  1. EMQ X InfluxDB 訊息儲存外掛配置檔案,用於配置 InfluxDB 連線資訊、選取入庫主題:
etc/plugins/emqx_backend_influxdb.conf
複製程式碼

根據部署實際情況填寫外掛配置資訊如下:

backend.influxdb.pool1.server = 127.0.0.1:8089

backend.influxdb.pool1.pool_size = 5

## Whether or not set timestamp when encoding InfluxDB line
backend.influxdb.pool1.set_timestamp = true

## Store Publish Message
## 由於業務僅需 devices/{client_id}/messages 主題,此處修改預設配置的主題過濾器
backend.influxdb.hook.message.publish.1 = {"topic": "devices/+/messages", "action": {"function": "on_message_publish"}, "pool": "pool1"}
複製程式碼
  1. EMQ X InfluxDB 訊息儲存外掛訊息模板檔案,用於定義訊息解析入庫模板:
## 模板檔案
data/templates/emqx_backend_influxdb_example.tmpl

## 重新命名修改為
data/templates/emqx_backend_influxdb.tmpl
複製程式碼

由於 MQTT Message 無法直接寫入 InfluxDB, EMQ X 提供了 emqx_backend_influxdb.tmpl 模板檔案將 MQTT Message 轉換為可寫入 InfluxDB 的 DataPoint:

{
  "devices/+/messages": {
    "measurement": "devices",
    "tags": {
      "client_id": "$client_id"
    },
    "fields": {
      "temperature": ["$payload", "temperature"],
      "humidity": ["$payload", "humidity"]
    },
    "timestamp": "$timestamp"
  }
}
複製程式碼

關於 EMQ X InfluxDB 使用詳細教程見 InfluxDB 資料儲存

InfluxDB 安裝

通過 Docker 進行安裝,對映資料資料夾與 8089 udp 埠與 8086 埠(Grafana 使用):

EMQ X 僅支援 InfluxDB UDP 通道,需要 influx_udp 外掛支援,且資料庫名稱指定為 db

## 使用 influx_udp 外掛
git clone https://github.com/palkan/influx_udp.git

## 進入外掛目錄
cd influx_udp

## 通過外掛配置建立並啟動容器
docker run --name=influxdb --rm -d -p 8086:8086 -p 8089:8089/udp \
	-v ${PWD}/files/influxdb.conf:/etc/influxdb/influxdb.conf \
  -e INFLUXDB_DB=db \
  influxdb:latest

## 啟動後檢查容器執行狀態
docker ps -a

複製程式碼

至此,可以重啟 EMQ X 並啟動外掛以應用以上配置:

./bin/emqx stop

./bin/emqx start

## 或使用 console 模式可以看到更多資訊
./bin/emqx console

## 啟動外掛
./bin/emqx_ctl plugins load emqx_backend_influxdb

## 啟動成功後會有以下提示
Plugin emqx_backend_influxdb loaded successfully.

複製程式碼

Grafana 安裝

使用以下命令通過 Docker 安裝並啟動 Grafana:

docker run -d --name=grafana -p 3000:3000 grafana/grafana

複製程式碼

啟動成功後瀏覽器訪問 http://127.0.0.1:3000 訪問 Grafana 視覺化皮膚,使用 admin admin 預設使用者名稱密碼完成初次登入,登入後按照提示修改密碼使用新密碼登入進入主介面:

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

寫入模擬資料

進行視覺化配置之前需要寫入模擬資料,方便配置過程中進行效果預覽。

以下指令碼模擬完成了 100 個裝置在過去 12 小時內、每隔 5 秒鐘上報一條模擬溫溼度資料併傳送到 EMQ X 的場景,讀者安裝 Node.js 平臺後可以通過以下命令啟動:

npm install mqtt mockjs --save
node mock.js

複製程式碼

模擬指令碼執行完畢後,資料將寫入 InfluxDB db 資料庫中,通過以下命令進入 InfluxDB 容器並檢視資料:

## 進入 docker 容器
docker exec -it influxdb bash

## 進入 influxdb 命令列
root@581bde65650d:/# influx

## 切換到 db 資料庫
use db;

## 查詢資料
select * from devices limit 1;

## 查詢結果
name: devices
time                client_id      humidity temperature
----                ---------      -------- -----------
1574578725608000000 mock_client_1  54.33    98.5

複製程式碼

附:模擬指令碼如下:

// Node.js
// mock.js
const mqtt = require('mqtt')
const Mock = require('mockjs')

class MockData {
  constructor(clientNum = 20) {
    this.EMQX_SERVER = 'mqtt://localhost:1883'
    this.clientNum = clientNum
    this.clients = {}
    this.startMock()
  }

  async startMock() {
    const now = Date.now()
    // last 12h every 5s
    for (let ts = now - 12 * 3600 * 1000; ts <= now; ts += 5 * 1000) {
      for (let i = 0; i < this.clientNum; i++) {
        const clientId = `mock_client_${i}`
        const client = this.clients[clientId] || await this.createClient(clientId)
        this.clients[clientId] = client
        const mockData = this.getMockData()
        client.publish(`devices/${clientId}/messages`, JSON.stringify(mockData))
        console.log(`${clientId} send temperature ${mockData.temperature} humidity ${mockData.humidity}`)
      }
    }
  }

  /**
   * Init a virtual mqtt client
   * @param {string} clientId ClientID
   */
  createClient(clientId) {
    return new Promise((resolve, reject) => {
      const client = mqtt.connect(this.EMQX_SERVER, {
        clientId,
      })
      client.on('connect', () => {
        console.log('client s% connected', clientId)
        resolve(client)
      })
      client.on('error', (e) => {
        reject(e)
      })
    })
  }

  /**
   * Generate mock data
   */
  getMockData() {
    return {
      temperature: parseFloat(Mock.Random.float(22, 100).toFixed(2)),
      humidity: parseFloat(Mock.Random.float(12, 86).toFixed(2)),
    }
  }
}

// startup
new MockData(100)

複製程式碼

視覺化配置

元件安裝完成,模擬資料寫入成功後,按照 Grafana 視覺化介面的操作指引,完成業務所需資料視覺化配置。

新增資料來源(Add data source)

新增資料來源,即顯示的資料來源資訊。選取 InfluxDB 型別資料來源,輸入連線引數進行配置,預設情況下,關鍵配置資訊如下:

  • URL:填寫 InfluxDB 連線地址,由於我們使用 Docker 安裝,Grafana 由於 InfluxDB 容器網路不互通,此處可以輸入當前伺服器內網/區域網地址而非 127.0.0.1localhost
  • Auth:InfluxDB 預設啟動無認證方式,根據實際情況填寫;
  • Database:填寫 db ,為 EMQ X 預設寫入資料庫名。

新增儀表盤(New Dashboard)

新增好資料來源後,新增需要顯示的資料儀表盤資訊。儀表盤為多個視覺化皮膚的集合,點選 New Dashboard 後,選擇 Add Query 通過查詢來新增資料皮膚:

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

建立皮膚需要四個步驟,分別是 Queries(查詢)Visualization(視覺化)General(圖表配置)Alert(告警),下面按照業務需求與完成以下建立流程:

溫、溼度平均值皮膚

使用 Grafana 的視覺化查詢構建工具,查詢出所有裝置的平均值:

  • FROM:選取資料的 measurement,按照 emqx_backend_influxdb.tmpl 檔案配置,此處 measurementdevices
  • SELECT:選取、計算的欄位,此處兩個查詢需要使用 Aggregation 功能處理,分別選擇 temperature meanhumidity mean,查詢並計算溫度、溼度欄位的平均值;
  • GROUP BY:預設使用時間區間聚合。
    • time($__interval) 函式表示取 $__interval 時間區間內的資料,如 time(5s) 表示從每 5 秒時間區間原始資料內取出值來進行計算(SELECT 中的計算)
    • fill 參數列示沒有值時候的預設值,為 null 的時候該資料點不會在圖表顯示出來;
    • tag 可選,按照指定 tag 進行顯示。
  • ALIAS BY:該查詢的別名,方便視覺化檢視。

Visualization 預設不做更改,General 裡面修改皮膚名稱為 Device temperature and humidity mean value,如果需要對業務進行監控告警,可以在 Alert 裡編排告警規則,此處僅做視覺化展示,不使用此功能。

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

完成建立後,點選左上角返回按鈕,該 Dashboard 裡成功新增一個資料皮膚。點選頂部導航欄儲存圖示,輸入 Dashboard 名稱完成 Dashboard 的建立。

一小時搭建 EMQ X + InfluxDB + Grafana 物聯網資料視覺化方案

溫、溼度最大、最小值皮膚

繼續點選 Dashboard 的 Add panel 按鈕,新增溫度最大值、最小值圖表。操作步驟同新增平均值,僅對查詢中 SELECT 統計方法欄位做出調整,調整為 Selectors 功能中的 maxmin 方法。

溫、溼度總平均值、資料條數皮膚

繼續點選 Dashboard 的 Add panel 按鈕,新增溫、溼度總平均值,資料條數皮膚。操作步驟近似上面兩個步驟,分別使用 countmean 方法對指定欄位操作,取消 GROUP BY 欄位即可完成查詢。Visualization 配置中選擇圖表型別為 Gauge(儀表) 即可。

儲存儀表盤,拖拽調整每個資料皮膚大小、位置,最終得到一個視覺效果較好的資料儀表盤。最終報表完成後,呈現的就是文章開頭展示的效果。

總結

至此我們完成了 EMQ X 與 InfluxDB + Grafana 物聯網資料視覺化整合方案的搭建實現。通過本文,讀者可以瞭解到利用 EMQ X 豐富的擴充能力在資料視覺化解決方案裡可以非常快速、靈活地開發出基於 InfluxDB + Grafana 的視覺化系統,實現海量資料儲存、計算分析與展現。深入學習掌握 Grafana 的其他功能後,使用者可以定製出更完善的資料視覺化乃至監控告警系統。


更多資訊請訪問我們的官網 emqx.io,或關注我們的開源專案 github.com/emqx/emqx ,詳細文件請訪問 官方文件

相關文章