我是TJ,来自MongoDB的高级解决方案架构师,主要工作是帮助客户成功使用MongoDB,涉及到模式设计,最佳操作性能调优等。
那么什么是物联网呢?
它是技术领域排名第二或第三的流行词汇。根据profoundry的数据,在30天的时间里,就出现了9300万的谷歌搜索结果和3万6千的推特提到了物联网。
作为一个流行词汇,这就意味着有无数的解释,这样就使得其很难有一个人们普遍认同的定义。
而好的一个方面呢就是每个人都有机会尝试一下。而我自己关于物联网的定义就是: Internet 4.0。
为什么是 4.0呢?
互联网的原型出现于1960s,但是也是从1980s才逐渐变得成熟。最开始的时候,互联网大部分用于大学和研究机构。我们称之为1.0。
在1990s,伴随着个人电脑连接到互联网,互联网开始商业化,得到蓬勃的发展。这个阶段为2.0阶段。
不到10年前, iPhone的诞生将我们带入了3.0,移动时代。随着移动设备的快速发展,现在有近30亿用户通过互联网连接在一起,其中手机占用了互联设备高达80%的市场份额。
服务器,个人电脑,到移动设备,最后扩展到所谓的things,传统意义上非智能的设备。Internet 4.0 是当前互联网的拓展到配备着传感器和网络模块的设备,能够感知周围环境并且与世界的其它部分进行通信。防止走丢失的脚环手环,十字路口的自动感应红绿灯, 家庭里能够自动调节温度和灯光色调的智能家电,这些都是4.0的一些切切实实发生在生活中的场景。
我们现在正处于Internet 4.0时代的Beta阶段。如果您在90s没有构建网站,或在2008创造一个iPhone应用,那么现在就是您的机会-抓住物联网的浪潮。一旦beta阶段结束,竞争将会变得更加激烈。
好的,那么关于物联网,从技术角度,我们到底需要了解些什么呢?这里,我从postscapes.com摘取了一些幻灯片,Postscapes是一个专注于物联网所有信息的综合网站。它与Harbor研究所一起合作,提供大量内容丰富的信息图。他们在把物联网这个抽象技术的可视化上面做了很多工作,让人比较容易的理解这个复杂的概念。如果您刚开始接触物联网领域,我强烈推荐您了解一下完整内容。
在Postscapes 的观点中,有三到四个关键组成部分:传感器/连接、 人和进程。
当我们讨论物联网时,首先会想到传感器。传感器是互联网的眼睛和耳朵。在早期1.0时代,键盘是外部世界和互联网的主要接口。而在2.0个人电脑时代,我们增加了相机和麦克风。手机、GPS、加速度计以及陀螺仪几乎成了标准配置。在物联网的时代,传感器有了更广泛的用途。温度、压力、环境灯光、速度、位移、湿度、 扭矩,任何您想了解的信息都可以通过传感器获取。
除了传感器,同等重要的是:驱动物联网应用对不断变化的环境进行响应的驱动器。例如,当云检测到用电高峰时,一个连通的空调控制器可能会自动稍微升高温度来节约用电。
传感器,特别是那些行业的传感器屡见不鲜,他们已经存在了几十年。如今的不同之处在于:通过网络的互联将其带入了下一个等级。通过使用大量的网络协议,例如WIFI, Bluetooth, Zigbee,z-wave,GPRS,这些传感器现在可以将它们所看见的,听到的和感觉到的信息发送到连接的网络上或者云上。其中,zigbee和z-wave专门为智能对象提供的。与Wifi相比,zigbee和z-wave的有效工作范围相对较小,但是好处是它们通常也只需要非常少的电量消耗和硬件资源。Zigbee经常用于不到100KB RAM的芯片上。
我们将传感器和驱动器作为输入和输出,将数据实时接入,并且在同一个通信渠道将命令发送到这些设备,以响应输入输出的变化。这种双向的架构为我们开启了设计和搭建应用的新时代。在我看来,称之为Internet 4.0更好的原因在于这些物品都与我们相连:人,我们的日常生活以及网络都息息相关。
目前,各行各业都可以发现IoT应用。Geofencing在养老院和奶牛饲养管理方面非常流行。通过GPS追踪和报告进行实时的车辆管理。农业方面也正在通过监控周围环境并将及时的反馈提供给种植者来提高产量。电池持续工作能力的提升也是使用智能手环或移动应用也变得越来越高效。智慧城市和智慧家庭也是物联网应用的热门领域。
西班牙北部城市桑坦德拥有20,000个传感器连接着建筑,基础设施,交通,网络及公用设备。这些传感器监测着污染、噪声,交通及停车的情况,帮助城市管理提供明智、及时的决策,保证最大化利用城市资源。
下面,我们来看一些已经在我们生活中发生的一些应用场景。
第一个是Vital Herd提供的connected cow应用。他们生产了一种电子药片给奶牛吃到胃里。药片在奶牛胃部的底部一直停留, 并且将生命特征相关的信息传输出来:比如说,心率和呼吸率,消化信息,内脏温度以及胃中的化学成分。数据被发送到云中,进行聚类分析以后,为每种动物创建生命特征标准,然后把信息以一种易于理解、可控的仪表盘形式返回给生产者。
这些重要的数据提供了对影响产奶量疾病全新的、早期的警报,可以让农场主及时采取措施来防患于未然。仅仅是在美国就有9400百万的奶牛,公司预计潜在降低的成本高达数十亿。
第二个是世界上最大的农用收割机厂商。 John Deere将传感器添加到了他们最新的设备上,来帮助农场主们管理他们的车队。采集的信息组合了历史和实时的数据,包括天气预测、土壤情况、农作物特点以及其它的数据集。这些数据都展示在MyJohnDeere.com以及iPad和iPhone应用-Mobile Farm Manager上,帮助农场主决定什么时候再什么地方种植什么作物,什么时候对那块地进行耕种,耕种在什么地方的农作物将会获得最好的收成, 甚至 是在耕种的时候选择哪条路径。
所有的这些将会提高农作物的生产效率,最终能够得到更高的产量和收入。John Deere使用MongoDB存储传感器数据并提供实时的分析功能,以便在用户界面上展现结果。
你也许还没有意识到,传感器或互联设备的数目已经达到了惊人的数字。根据思科的调查,在2016年,已经有200亿到智能物件的连接。我们必须清楚地认识到地球上每个人平均有4个传感器。而且,这个数字还会继续增加,到2020年,总数将会到达500亿。互联网设备可能会有个增长的天花板,但是物联网,目前还看不到天花板在哪里。
另一组数据是,根据IDC的统计,全球物联网的市场规模将会达到7.1万亿。几年之前,这个数据为1.9万亿。物联网的生态系统包括智能和嵌入式系统交付、连接服务、基础设施及特定用途的物联网平台、安全、分析及个性化服务等。
根据这个图表,亚洲在物联网应用的部署上将会超过其他大洲。此外,国家正在将物联网部署作为一项国策。例如,根据政府计划,在未来的5年内政府预计将会投入1700亿美元到物联网领域。这确实是一个非常庞大的数字。
http://www.iotprimer.com/2013/11/iot-protocol-wars-mqtt-vs-coap-vs-xmpp.html
好的,已经啰嗦了不少,让我们开始来点干货吧。物联网之所以成为最热门的话题的一个原因在于:它其实包容,涵盖了很多技术。粗分我们就有5类。在最低层,我们有硬件平台。最近最受欢迎的是Arduino, Raspberry Pi, Intel Edison等。这里有一些基本的迷你操作系统供您搭建设备上的应用。在硬件平台之上,我们有无线传输层,例如Zigbee, Z-Wave, WIFI, GPRS, Bluetooth-LE。这一层的作用是提供物理传输通道来交换设备和云或者服务器上的数据。类似于我们7层网络协议中的物理层和链路层
传输层之上是通信协议。
考虑一下传输层作为处理设备和网关之间1到0数据交换的底层结构。通信层提供更高级别的语言能够被我们的Java/C#/python项目所理解。例如,MQTT,CoAP,XMPP等。 这个大致对应于7层网络协议中TCP、IP以上的协议,包括会话控制,协议语言解析等。
现在,我们进入到中间件/存储层。这一层将会读取数据并且分发数据出去,并且将数据永久保存等。最后,物联网在顶层直接与人类交互,进行价值传递。最简单的形式就是:允许用户读取和控制他们的智能物品,例如照明灯,冰箱和电饭煲等。
更多特定的应用包括商务智能分析、工作流集成等。
这里是一个图表,描述了不同技术部件之间的关系。在这边,有传感器和驱动器、一般说来,传感器会不间断工作,感知周围的信息,转换成数字信息,并且建立到本地网关的联系,然后将数据传送过去。然后本地网关将会选择马上转发,也可以在整合一系列的数据点之后,通过网络批量发送到中心服务器,一般是到云中或者是企业的数据中心内。
网关的使用是可选的。有时候,设备可能会直接与智能手机进行交互,数据交互到此结束。另一些时候,传感器也许会自己配备GPRS模块因此可以直接和远程服务器进行通信。
http://www.forbes.com/sites/huawei/2015/05/12/the-challenges-of-iot-to-build-a-better-connected-future/
那么,开发一个物联网应用的挑战在哪里呢?
首先在硬件层,没有标准的传感器接口也许是物联网应用更广泛推广的第一个阻碍。各个厂商忙着推出自己的接口自己的标准,目前还没有形成一个大多数行业认同的标准接口,限制了在家居或者智慧城市的推广。
无线传输的能源也是个巨大的问题。因为其消耗资源较高。
最后,中间件最大的挑战在于处理多变的数据格式的能力,可能是有非标准的传感器接口及庞大数据量造成的。作为一个物联网顶层应用开发者来说,这也是我们所需要关心的地方。下面我们用一个生活中的例子来理解一下这个挑战。
大家应该都还记得前年在印度洋上方神奇失踪的MH370航班吧?事故发生之后,许多人都在好奇,在如今的技术下,为什么我们都不能追踪如此大的一架飞机呢?
我们来看一下这个问题。
如今,飞机上追踪的数据可能有多重来源。例如:ADS-C, HFDL, EUROCONTROL, ACARS(航空公司通信寻址&报表系统)。当一件事故发生时,一个强壮的追踪系统需要组合各种来源的数据来拼凑出一张完整的画面。例如,MH370 的ACARS系统被飞行员故意关闭掉了。在这种请况下,多重来源的数据可以帮助降低后来定位飞机的困难。
即使数据来自于一个渠道,数据也有可能根据数据的特征有不同的形式,例如位置数据可以以坐标对的形式出现,以及嵌套数据结构表示的引擎参数 等等。
您将如何在数据库中对这些数据进行建模呢?
这些并不是非常结构化的数据对传统关系型数据库造成了非常大的挑战。传统的关系型数据库适用于所有数据都清楚定义以及结构化数据模型的情况。例如,如果你想要设计一个庞大的表,每种测量值都是一个列。到最后,你将会在那些没有数据的列中浪费很多存储null值的空间。第二个缺点是:如果你想增加更多的度量标准,你将不得不修改模式结构。
一个更好的候选方案是使用一个EVA表,表示:实体、属性、值。EAV模式使用两个表的设计,一个表格在不同的行中一般存储着不怎么变化的数据。然后在用一个单独的元数据表存储那些可能只存在于某些行的、多变的数据字段,例如经度/纬度,速度,引擎燃料等。
这看起来是一个更好的设计,因为它不存在空值的问题。然而,如果你仔细想一想,METRIC_VALUE列必须定义为一个文本字段或者是足够长的字符串字段来存储可能的最大的指标值。结果是,你仍然会面对一些很大的磁盘空间浪费并且降低输入输出效率。更糟糕的是,如果你想在该列进行索引,这将会大大降低索引效率。
此外,EAV设计尚有另外一个缺点,它将会使得查询更加困难。特别是:如果你想基于多个字段查找一行或一个文档,例如,找到离纽约不超过100公里并且燃料量少于10%的飞机,你将需要在AV表中做多个join操作才能够在多属性字段上进行筛选。
这就是我想给大家看的一个多变数据结构问题的例子。
下面一个场景:找到在某个特定区域内的所有飞机,必须selfjoin两次或更多,这对大型表的性能来说是致命的。
我们再来看另外一个数据挑战,那就是是海量数据的问题。我们再次使用航班追踪的例子。假设我们每分钟发送多种状态的数据,一些数据也许需要更频繁,其它的则不需要。为了展示的需要,我们只使用一分钟的时间间隔。
3个小时的飞行
1.8 Billion / 86400(seconds) ~= 21,000查询每秒
如果你是国内的电信运营商,或者维护着facebook类型的社交网站,这个数量级并不意味着什么。但是对普通的供应商而言,这就造成了一个需要他们去克服的重大技术阻碍。
我可以负责任的告诉您:管理海量,形式多变的数据是非常困难的一件事情。如果有选择,我可能会回家种田去。
还好,物联网的时代,有物联网的数据管理工具,我们来看一下目前的非关系型数据中排名第一MongoDB,看它如何可以帮我们解决复杂的物联网数据的存储管理和查询问题。
MongoDB是一个文档型的非关系数据库。它的理念是基于一个Nexus架构,就是集关系型的优秀的查询功能,强一致事务性及丰富完整的企业级管理集成工具和非关系性的灵活模式,水平扩展性和高性能特点于一体的新一代数据库。MongoDB在保持着构建功能性应用所需的核心数据库功能的同时,也能够处理不断改变的需求。
而灵活、敏捷性和扩展性正是物联网应用最重要的技术需求。
什么是灵活性?灵活性就是当你团队接到一个业务的时候,定义好你的usecase,设计你的架构,画出来sequencediagram和classdiagram,就可以开干了。不必去等待2个月时间做ER图,因为mognodb,不需要ERdiagram。
什么是灵活性?当你的开发出alpha版本后,产品经理过来告诉你,程序员哥哥,客户说他们有推出一个新的征婚匹配算法,需要记录用户的爱好基础上再打分,另外一个用户本来只允许有一个profile的,现在对VIP用户推出多个profile。你想对产品经理大吼一声“不早说啊,我都设计好了完美的数据模式”,可是你不行产品经理是你心仪的mm。有了MongoDB,这些都不是问题,数据库标的数据模式不用改,因为我们从来就没有在库里定义。只需要在应用里修改你的数据对象模型就Okay了
什么是灵活性?当你需要处理形状各异的采集数据,当你需要整合多个相似系统到一个的时候,在同一个表里对类似而不完全相同的异构数据进行存储管理,就是灵活性。
我们来结合机器采集数据的案例来看一下MongODB对异构、可变数据的管理。
假设我们要采集飞机上的一些运行数据,如location地理位置,速度,和引擎温度,油量等参数。那么我们可以考虑这样一个灵活的metrics属性模式。Metrics是一个子文档,下面可以有任意的采集值字段,无需事先定义,可以任意增加。这里我们列出两条采集的数据(如 1 所示)。第一条采集的是油量和引擎的温度,第二条则是位置信息。在MongoDB里面,这两条数据可以直接插入到同一个表里面。 MongoDB提供一种叫做稀疏索引的,比如说,这里我们建了个location的稀疏索引(如2所示)这个索引会忽略所有文档没有这个location字段的,只对有location值的文档建立索引,这样做可以避免浪费宝贵的资源。
当有一天产品经理告诉你需要收集一个新的字段elevation的时候,你可以说,YesMadam!然后直接在程序里向MongoDB插入一条新结构的文档,就这么简单!
当然只是把数据存进去,并没有真正解决所有的问题。最关键的还是要用数据,如何把数据高效的取出来,做展示,或者分析。
第一个需求场景是希望对某一个航班飞机油量的监控并画出histogram图,这个不要太简单,一个find 查询,找到指定日期以来所有油量事件就可以了
第二个需求稍微复杂些,我们希望随时看到纽约机场周围20公里范围内所有的飞机,那么我们这里要用到geonear一个地理查询功能。第一步是找到最近几分钟内,发送过location事件的飞机,并且在一定半径内的,最后用group的last操作符取得最后的位置(因为每一架飞机有多个location事件)
那么我们刚才分析了一下MongoDB的灵活模型对物联网数据的很好的适用性。这里我们再来介绍一个常见的优化手段,利用到了mongodb的富文档结构特性。
我们知道许多传感器数据都是时间序列数据。例如:风传感器,潮汐监测以及位置追踪等采集数据的无非这种类型: Timestamp,采集器名称/ID,采集值。对于时序类型的数据,我们可以采用一种叫做时间分桶的优化策略。
所谓分桶优化,就是与其对每一条数据创建一个文档,我们可以把某一个时间段内的测量数据聚合到一起放到一个文档内,利用MongoDB提供的内嵌式数组或子文档特性。如下图所示,我们把16:00开始一个小时内每分钟采集的油量数据聚合到了一个具有60个字段的子文档内。每个字段表示一个分钟采集点。
这样做的好处是什么?
- 更少的文档数量 – 节省对文档存储需要的额外空间
- 写入性能的提升 – 更少的索引条目意味着更新索引表的代价也大大降低
- 可查询性&更优秀的分析支持– 可以提前把这个小时的平均值计算出来,用来在图标上展现按小时颗粒度的histogram
接下来我们再来看一下物联网数据所需要的另一个维度: 扩展性。
我们刚才讲到了航班监控一天就要采集近20亿条数据,这个不是任何单台数据库可以能够扛得住的。在这里我们必须使用分布式技术把海量的数据分发到不同的数据节点上去。
在MongoDB里面,扩展性是通过mongodb的分片集群来实现的。 一个分片集群主要包括:用来做数据路由的mongos,数据节点(Primary 和 Secondary),以及存储集群元数据的配置服务器(config)。每一个分片(shard) 本身由一主二从(或多从)组成一个高可用复制集。
当你需要支持更多的并发、更高的每秒查询率或者更大的数据量时,你可以通过向现有集群增加更多的分片来简单地向外拓展。而且支持不下线在线扩容。数据基本上均匀分布在多个分片上。例如,在这里,我们有4个分片,每个分片存储着总量25%左右的数据。如果数据量增加50%或者更多,你可以便利地向集群中增加2个或4个或更多分片来处理更大的数据量。
这里有两个使用MongoDB进行大规模扩展的案例,一个是国外的一家在线提供设计云服务的厂商,利用MongoDB的分片实现了120万每秒的混合读写。另一个案例是大家都用的百度云。百度云用MongoDB存储媒体文件的元数据,目前这个最大的表已经有超过1000多亿的记录,大概有20多个分片来支撑这个巨大。
分片集群在MongoDB里面是非常易于使用的,MongoDB会帮你处理好数据均衡,并且可以在线扩容或者缩容,集群拓扑架构基本上对应用可以做到无感知。但是很关键的一点作为架构师或者开发需要了解的就是要选择一个合适的分片键。
片键是Mongo用来决定数据分布的一个基准原则。MongoDB 有3种分片方式:基于范围,基于hash和高级的自定义标签方式。
在选择片键的时候要注意以下几个原则:
1) 基数要足够大,太小的话会导致jumbo chunk,就是一个chunk内包含的文档数过多,超过默认的64M,mongoDB将不会对其进行迁移
2)查询定向性: 避免scattergather。如果你的片键是基于范围的,那么使用片键作为前缀的范围查询就会有较好的定向性 –mongo 可以把请求直接定向到某一个分片。相反,如果采用hash 片键,或者范围查询字段不是片键,那么就会产生scattergather。这个要看你应用的主要查询模式来考量
3) 避免热分片。如果采用时间字段,或者mongo的_id字段,就会导致热分片。这是因为最新写入的数据按照时间分块的话都会集中到一个负责最新数据的分片上,这样其他的分片就闲置在那里。
在这里我们针对于物联网数据的特征可以来分析一下什么样的片键会是个好的选择。我一般会用一个表格来做这个事情,表格的列就是3个片键的指标,分别为基数,写分发和范围查询的定向性。然后每一行就是一个候选的片键。
第一个_id ,它的基数很大 – 等于文档总数,不能更大了,所以是个好的选择从基数的角度。可是从写分发的角度来看就是一个糟糕的选择,因为_id的高位时时间戳,会导致热分片。一般我们做范围查询,往往是针对于某一个触感器一段时间范围内数值的查询,这种场景下由于片键不包含传感器ID或标识符,所以这种查询将是个scattergather,总而言之不是很好的选择。
第二个选择是 对_id做has来作为片键。Hash方式一般对写分布支持较好,但是也有scatter gather的问题
如果换用asset_id来作为片键,我们会发现它的基数有可能不够多、大。因为一个系统的传感器可能只有几千个甚至几百。这么小的基数会导致一个asset的chunk里面有太多文档,导致jumbochunk。
最佳的方案是可以采用一个组合片键的方式,用asset_id加ts的方式来做。这个组合可以保证基数是最大的,同时也没有热分片现象,查询也因为由于包含了常用字段asset_id而可以实现定向,是一个比较理想的片键
最后我们来看一些在物联网里使用MongoDB的解决方案。 在商用方案中,我们了解到的国内最大的一家IT方案提供商,产值几千亿的公司,其中的物联网通用方案就选择了MongoDB来存储采集的原始数据。宝马,路虎,以及国内的楼兰宝盒等都使用到了MongoDB。在开源方案中案例也是比比皆是。像Kaa, IoTgo和Sitewhere, 这些都是能够快速开启您的点对点物联网应用的中间件解决方案。
例如,如果你是一个智能物品的制造商(例如,儿童追踪鞋),你不需要搭建一个完整的后台服务来实现数据读取、管理安全和考虑扩展性问题,您可以使用其中的一项技术作为核心技术。所有你需要做的就是使用SDK或者API将你的设备连接到这些后台服务器,可能还需要一个终端用户界面封装器在用户进入到系统之后,读取和管理数据。使用这些方案将会大大降低您物联网解决方案的花费并且加速应用进入市场的时间。
我们来花点时间来看其中一个方案,Sitewhere。它是一个相对复杂但是功能完整的物联网平台解决方案,它大致有5个模块:Sitewhere引擎,数据采集,数据输出,事件处理和其它服务。
Sitewhere引擎是系统的核心,而设备输入模块支持MQTT,直接的socket例如WiFi或者GPRS或者HTTP/Restful的API终端等。
如果有必要的话,这些数据将会被清洗、过滤和转化,然后存储到MongoDB中,MongoDB是其默认的存储解决方案。
数据输出允许你与设备进行双向通信,发送命令和指令到设备。
作为一个企业级别的软件,Sitewhere也有许多Mule AnyPiont/Hazelcast和 Azure EventHub的集成解决方案。
我们继续聊一下飞机追踪的案例。我们想在一张地图上追踪所有感兴趣的航班,例如:位置,速度以及燃油油量等。通过使用Google Map的API,实现这个功能非常容易。我们只需要从MongoDB里面做一个简单的查询来返回某架飞机某个时段的采集数据,然后将它们显示在地图上即可。
实现这个动态监控APP所需要做的就是1-2-3.
1: 在XML中定义需要存储的数据结构
2: 利用Sitewhere的SDK来把原始采集数据接入到平台
3: 通过Sitewhere的数据API检索相关数据并进行展示
除了数据API,sitewhere平台还提供了一些基础的资产管理功能。例如,您可以查看一系列的设备/资产,管理关系及实现想设备发送批量命令的功能。
最后,让我们再来回顾一下我们今天讲的主要内容。
物联网应用的数据有一下特点: 海量,多为时序数据, 具有多形态,并且通常有实时分析需求。
MongoDB适用于物联网的原因就在于它的分片集群架构可以提供大数据能力,无论是从数据量还是并发量上。它的动态模式对异构多形数据的支持也是有得天独厚的优势。如果你正在考虑开发物联网的应用,无论只是用MongoDB来作为数据存储,还是使用刚才提到到一些开源的框架中间件,都会是一个不会让你后悔的选择。
评论前必须登录!
注册