Elastic: 把 MQTT 数据传入到 Elasticsearch

Elasticsearch 可以存储 PB 级的数据并实时分析数据,而 MQTT 被广泛使用于物联网中。那么我们该如果把 MQTT 的数据传入到 Elasticsearch 中呢?

我们可以通过如下的架构来把 MQTT 数据传入到 Elasticsearch:

在这里,我们可以通过一个叫做 MQTT 的 router 来把数据传入到 Elasticsearch。这些物联网的数据可以包括温度,速度,位置,速度,湿度,重力加速度,光感等。

下面,我们来介绍一下如何实现把 MQTT 的数据接入到 Elasticsearch 中来。为了说明问题方便,我们的测试环境是这样的:

如上图所示,我们在 MacOS 上安装好自己的 Elastic Stack。在 Ubuntu 18.04 的机器上安装好自己的 MQTT broker 及运行 MQTT 的 publisher。

 

准备工作

安装 Elasticsearch

如果大家还没安装好自己的 Elastic Stack 的话,那么请按照我之前的教程 “如何在Linux,MacOS及Windows上进行安装Elasticsearch”  安装好自己的 Elasticsearch。由于我们的Elastic Stack需要被另外一个 Ubuntu VM 来访问,我们需要对我们的 Elasticsearch 进行配置。首先使用一个编辑器打开在 config 目录下的 elasticsearch.yml 配置文件。我们需要修改 network.host 的 IP 地址。在你的 Mac 及 Linux 机器上,我们可以使用:

$ ifconfig

来查看到我们的机器的 IP 地址。针对我的情况,我的机器的 IP 地址是:192.168.0.100。

我们也必须在 elasticsearch.yml 的最后加上 discovery.type: single-node,表明我们是单个 node。

等修改完我们的 IP 地址后,我们保存 elasticsearch.yml 文件。然后重新运行我们的 elasticsearch。我们可以在一个浏览器中输入刚才输入的 IP 地址并加上端口号 9200。这样可以查看一下我们的 elasticsearch 是否已经正常运行了。

安装 Kibana

我们可以按照 “如何在Linux,MacOS及Windows上安装Elastic栈中的Kibana” 中介绍的那样来安装我们的 Kibana。由于我们的 Elasticsearch 的 IP 地址已经改变,所以我们必须修改我们的 Kibana 的配置文件。我们使用自己喜欢的编辑器打开在 config 目录下的 kibana.yml 文件,并找到 server.host。把它的值修改为自己的电脑的IP地址。针对我的情况是:

同时找到 elasticsearch.hosts,并把自己的 IP 地址输入进去:

保存我们的 kibana.yml 文件,并运行我们的 Kibana。同时在浏览器的地址中输入自己的 IP 地址及 5601 端口:

如果配置成功的话,我们就可以看到上面的画面。

 

安装 Ubuntu 虚拟机

这个不在我的这个教程之内。在网上我们可以找到许多的教程教我们如何安装 Ubuntu 虚拟机。

 

安装 MQTT mosquito

我们在 Ubuntu 机器里,执行如下的指令:

sudo apt-get update
sudo apt-get install -y python-paho-mqtt

一旦上面的命令执行成功后,我们可以通过如下的命令来检查 mosquito 服务是否已经成功运行:

sudo systemctl status mosquitto

更多关于 mosquito 的安装请参阅链接

我们也可以同时执行如下的指令来安装 MQTT 的客户端:

sudo apt-get install mosquitto-clients

安装 Python 2 及 Elasticsearch Python


我们可以按照如下的指令来安装 python 2:

 sudo apt install python-minimal

然后我们打入如下的指令来安装Elasticsearch Python:

sudo apt install python-elasticsearch

到目前位置我们的安装基本上已经完成了。

 

MQTT router

在我们的实现中,我们使用 Python 语言来实现对 MQTT 信息的转发。其基本原理是订阅我们所感兴趣的 topic,然后把我们截获的数据再转发到 Elasticsearch 中。我们可以通过如下的指令来下载我的测试程序:

git clone https://github.com/liu-xiao-guo/mqtt-elasticSearch

具体实现如下:

mqttToElasticSearch.py

mqttServer="localhost"
mqttPort="1883"

channelSubs="test"
#use below as alternative to subscribe to all channels
#channelSubs="#"

import paho.mqtt.client as mqtt
from datetime import datetime
from elasticsearch import Elasticsearch


# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe(channelSubs)

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))
 
# this is the syntax to follow for the elasticSearch update taken from documentation
#    es.index(index="mqtt-index", doc_type="_doc", id=42, body={"any": +str(msg.payload, "timestamp": datetime.now()})
#    {u'_id': u'42', u'_index': u'my-index', u'_type': u'test-type', u'_version': 1, u'ok': True}

#our implementation uses this to separate numeric(float) from string data

    try:
        float(msg.payload)
        es.index(index="mqtt-index", doc_type="_doc", body={"topic" : msg.topic, "dataFloat" : float(msg.payload), "timestamp": datetime.utcnow()})
    	
    except:
        pass
        #es.index(index="my-index", doc_type="string", body={"topic" : msg.topic, "dataString" : msg.payload, "timestamp": datetime.utcnow()})
    
# by default we connect to elasticSearch on localhost:9200

es = Elasticsearch(
    ['192.168.0.100'],
    http_auth=('user', 'secret'),
    scheme="https",
    port=9200,
)
 

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(mqttServer,mqttPort, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

在这里,我使用了一个叫做 test 的 topic 来做测试。在实际的使用中,需要根据自己的需求来调整。同时在 Elasticsearch 的初始化过程中,我们需要填入自己的 IP 地址:

es = Elasticsearch(
    ['192.168.0.100'],
    http_auth=('user', 'secret'),
    scheme="https",
    port=9200,
)

我们向 Elasticsearch 中写入一个叫做 mqtt-index 的索引。

我们可以通过如下的方式来运行我们的 router:

python2 mqttToElasticSearch.py 

我们可以在另外一个 terminal 中打入如下的指令:

mosquitto_pub -m "1" -t "test"

请注意这里的 mosquitto_pub 是来自上面的 mosquitto-clients 安装。那么这个时候再我们的 mqttToElasticSearch.py 运行的客户端中,我们可以看到:

显然我们的router已经收到者信息。我们可以在Kinaba中查看mqtt-index:

GET mqtt-index/_search

显示结果:

    "hits" : [
      {
        "_index" : "mqtt-index",
        "_type" : "_doc",
        "_id" : "Ce0pkm8B9t-DLEX5oV8G",
        "_score" : 1.0,
        "_source" : {
          "topic" : "test",
          "timestamp" : "2020-01-11T01:13:07.278997",
          "dataFloat" : 1.0
        }
      },
      {
        "_index" : "mqtt-index",
        "_type" : "_doc",
        "_id" : "CO0pkm8B9t-DLEX5oF8_",
        "_score" : 1.0,
        "_source" : {
          "topic" : "test",
          "timestamp" : "2020-01-11T01:13:07.279708",
          "dataFloat" : 1.0
        }
      }
    ]
  }

在上面的数据显示我们的 Elasticsearch 已经成功地收到数据了。

我们也可以使用在git项目中的 publisher.py 来发送信息:

publisher.py

#!/usr/bin/env python2

import paho.mqtt.client as mqtt
import sys


print ("argv[0]: %s" % (sys.argv[1]))

client = mqtt.Client()
client.connect("localhost",1883,60)
client.publish("test", sys.argv[1]);

我们可以按照如下的命令来发送信息:

python2 publisher.py 5

至此,我们已经成功地把我们的 MQTT 数据发送到了 Elasticsearch。

如果有兴趣的开发者,也可以参照项目https://github.com/nathan-K-/mqttbeat。由于一些原因,该项目不能很好地和最新版本的 Elasticsearch 工作。需要作者更进一步完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值