简介: 获取更详细的 Databricks 数据洞察相关信息,可至产品详情页查看:https://www.aliyun.com/product/bigdata/spark
作者

美的暖通与楼宇事业部 先行研究中心智能技术部

美的暖通 IoT 数据平台建设背景

美的暖通与楼宇事业部(以下简称美的暖通)是美的集团旗下五大板块之一,产品覆盖多联机组、大型冷水机组、单元机、机房空调、扶梯、直梯、货梯以及楼宇自控软件和建筑弱电集成解决方案,远销海内外200多个国家。当前事业部设备数据上云仅停留在数据存储层面,缺乏挖掘数据价值的平台,造成大量数据荒废,并且不断消耗存储资源,增加存储费用和维护成本。另一方面,现有数据驱动应用缺乏部署平台,难以产生实际价值。因此,急需统一通用的 IoT 数据平台,以支持设备运行数据的快速分析和建模。

我们的 IoT 数据平台建设基于阿里云 Databricks 数据洞察全托管 Spark 产品,以下是整体业务架构图。在本文后面的章节,我们将就IoT数据平台建设技术选型上的一些思考,以及 Spark 技术栈尤其是 Delta Lake 场景的应用实践做一下分享。

选择 Spark & Delta Lake

在数据平台计算引擎层技术选型上,由于我们数据团队刚刚成立,前期的架构选型我们做了很多的调研,综合各个方面考虑,希望选择一个成熟且统一的平台:既能够支持数据处理、数据分析场景,也能够很好地支撑数据科学场景。加上团队成员对 Python 及 Spark 的经验丰富,所以,从一开始就将目标锁定到了 Spark 技术栈。

选择 Databricks 数据洞察 Delta Lake

通过与阿里云计算平台团队进行多方面的技术交流以及实际的概念验证,我们最终选择了阿里云 Databricks 数据洞察产品。作为 Spark 引擎的母公司,其商业版 Spark 引擎,全托管 Spark 技术栈,统一的数据工程和数据科学等,都是我们决定选择 Databricks 数据洞察的重要原因。

具体来看,Databricks 数据洞察提供的核心优势如下:

  • Saas 全托管 Spark:免运维,无需关注底层资源情况,降低运维成本,聚焦分析业务
  • 完整 Spark 技术栈集成:一站式集成 Spark 引擎和 Delta Lake 数据湖,100%兼容开源 Spark 社区版;Databricks 做商业支持,最快体验 Spark 最新版本特性
  • 总成本降低:商业版本 Spark 及 Delta Lake 性能优势显著;同时基于计算存储分离架构,存储依托阿里云 OSS 对象存储,借助阿里云 JindoFS 缓存层加速;能够有效降低集群总体使用成本
  • 高品质支持以及SLA保障:阿里云和 Databricks 提供覆盖 Spark 全栈的技术支持;提供商业化 SLA 保障与7*24小时 Databricks 专家支持服务

IoT 数据平台整体架构

整体的架构如上图所示。

我们接入的 IoT 数据分为两部分,历史存量数据和实时数据。目前,历史存量数据是通过 Spark SQL 以天为单位从不同客户关系数据库批量导入 Delta Lake 表中;实时数据通过 IoT 平台采集到云 Kafka ,经由 Spark Structured Streaming 消费后实时写入到 Delta Lake 表中。在这个过程中,我们将实时数据和历史数据都 sink 到同一张 Delta 表里,这种批流一体操作可大大简化我们的 ETL 流程(参考后面的案例部分)。数据管道下游,我们对接数据分析及数据科学工作流。

IoT 数据采集:从 Little Data 到 Big Data

作为 IoT 场景的典型应用,美的暖通最核心的数据均来自 IoT 终端设备。在整个 IoT 环境下,分布着无数个终端传感器。从小的维度看,传感器产生的数据本身属于 Small Data(或者称为 Little Data)。当把所有传感器连接成一个大的 IoT 网络,产生自不同传感器的数据经由 Gateway 与云端相连接,并最终在云端形成 Big Data 。

在我们的场景下,IoT 平台本身会对不同协议的数据进行初步解析,通过定制的硬件网络设备将解析后的半结构化 JSON 数据经由网络发送到云 Kafka。云 Kafka 扮演了整个数据管道的入口。

数据入湖:Delta Lake

IoT 场景下的数据有如下几个特点:

  • 时序数据:传感器产生的数据记录中包含时间相关的信息,数据本身具有时间属性,因此不同的数据之间可能存在一定的相关性。利用 as-of-join 将不同时间序列数据 join 到一起是下游数据预测分析的基础
  • 数据的实时性:传感器实时生成数据并以最低延迟的方式传输到数据管道,触发规则引擎,生成告警和事件,通知相关工作人员。
  • 数据体量巨大:IoT 网络环境下遍布各地的成千上万台设备及其传感器再通过接入服务将海量的数据归集到平台
  • 数据协议多样:通常在 IoT 平台接入的不同种类设备中,上传数据协议种类多样,数据编码格式不统一

IoT 数据上述特点给数据处理、数据分析及数据科学等带来了诸多挑战,庆幸的是,这些挑战借助 Spark 和 Delta Lake 都可以很好地应对。Delta Lake 提供了 ACID 事务保证,支持增量更新数据表以及流批同时写数据。借助 Spark Structed Streaming 可以实现 IoT 时序数据实时入湖。

以下是 Delta Lake 经典的三级数据表架构。具体到美的暖通 IoT 数据场景,我们针对每一层级的数据表分别做了如下定义:

  • Bronze 表:存储原生数据(Raw Data),数据经由 Spark Structed Streaming 从 Kafka 消费下来后 upsert 进 Delta Lake 表,该表作为唯一的真实数据表  (Single Source of Truth)
  • Silver表:该表是在对 Bronze 表的数据进行加工处理的基础上生成的中间表,在美的暖通的场景下,数据加工处理的步骤涉及到一些复杂的时序数据计算逻辑,这些逻辑都包装在了 Pandas UDF 里提供给 Spark 计算使用
  • Gold 表:Silver 表的数据施加 Schema 约束并做进一步清洗后的数据汇入 Gold 表,该表提供给下游的 Ad Hoc 查询分析及数据科学使用

数据分析:Ad-Hoc 查询

我们内部在开源 Superset 基础上定制了内部版本的 SQL 查询与数据可视化平台,通过 PyHive 连接到 Databricks 数据洞察 Spark Thrift Server 服务,可以将 SQL 提交到集群上。商业版本的 thrift server 在可用性及性能方面都做了增强,Databricks 数据洞察针对 JDBC 连接安全认证提供了基于 LDAP 的用户认证实现。借助 Superset ,数据分析师及数据科学家可以快速高效的对 Delta Lake 表进行数据探索。

数据科学:Workspace

楼宇能耗预测与设备故障诊断预测是美的暖通 IoT 大数据平台建设的两个主要业务目标。在 IoT 数据管道下游,需要对接机器学习平台。现阶段为了更快速方便地支撑起数据科学场景,我们将 Databricks 数据洞察集群与阿里云数据开发平台 DDC 打通。DDC 集成了在数据科学场景下更友好的 Jupyter Notebook ,通过在 Jupyter 上使用 PySpark ,可以将作业跑到 Databricks 数据洞察集群上;同时,也可以借助 Apache Airflow 对作业进行调度。同时,考虑到机器学习模型构建、迭代训练、指标检测、部署等基本环节,我们也在探索 MLOps ,目前这部分工作还在筹备中。

典型应用场景介绍

Delta Lake 数据入湖(批流一体)

使用 UDF 函数定义流数据写入 Delta Lake 的 Merge 规则

%spark
import org.apache.spark.sql._
import io.delta.tables._ // Function to upsert `microBatchOutputDF` into Delta table using MERGE
def upsertToDelta(microBatchOutputDF: DataFrame, batchId: Long) {
// Set the dataframe to view name
microBatchOutputDF.createOrReplaceTempView("updates")
// Use the view name to apply MERGE
// NOTE: You have to use the SparkSession that has been used to define the `updates` dataframe
microBatchOutputDF.sparkSession.sql(s"""
MERGE INTO delta_{table_name} t
USING updates s
ON s.uuid = t.uuid
WHEN MATCHED THEN UPDATE SET
t.device_id = s.device_id,
t.indoor_temperature =
s.indoor_temperature,
t.ouoor_temperature = s.ouoor_temperature,
t.chiller_temperature =
s.chiller_temperature,
t.electricity = s.electricity,
t.protocal_version = s.protocal_version,
t.dt=s.dt,
t.update_time=current_timestamp()
WHEN NOT MATCHED THEN INSERT
(t.uuid,t.device_id,t.indoor_temperature,t.ouoor_temperature ,t.chiller_temperature
,t.electricity,t.protocal_version,t.dt,t.create_time,t.update_time)
values
(s.uuid,s.device_id,s.indoor_temperature,s.ouoor_temperature,s.chiller_temperature,s.electricity,s.protocal_version
,s.dt,current_timestamp(),current_timestamp())
""")
}

使用 Spark Structured Streaming 实时流写入 Delta Lake

%spark

import org.apache.spark.sql.functions._
import org.apache.spark.sql.streaming.Trigger def getquery(checkpoint_dir:String,tableName:String,servers:String,topic:String ) {
var streamingInputDF =
spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", servers)
.option("subscribe", topic)
.option("startingOffsets", "latest")
.option("minPartitions", "10")
.option("failOnDataLoss", "true")
.load()
val resDF=streamingInputDF
.select(col("value").cast("string"))
.withColumn("newMessage",split(col("value"), " "))
.filter(col("newMessage").getItem(7).isNotNull)
.select(
col("newMessage").getItem(0).as("uuid"),
col("newMessage").getItem(1).as("device_id"),
col("newMessage").getItem(2).as("indoor_temperature"),
col("newMessage").getItem(3).as("ouoor_temperature"),
col("newMessage").getItem(4).as("chiller_temperature"),
col("newMessage").getItem(5).as("electricity"),
col("newMessage").getItem(6).as("protocal_version")
)
.withColumn("dt",date_format(current_date(),"yyyyMMdd"))
val query = resDF
.writeStream
.format("delta")
.option("checkpointLocation", checkpoint_dir)
.trigger(Trigger.ProcessingTime("60 seconds")) // 执行流处理时间间隔
.foreachBatch(upsertToDelta _) //引用upsertToDelta函数
.outputMode("update")
query.start()
}

数据灾备:Deep Clone

由于 Delta Lake 的数据仅接入实时数据,对于存量历史数据我们是通过 SparkSQL 一次性 Sink Delta Lake 的表中,这样我们流和批处理时只维护一张 Delta 表,所以我们只在最初对这两部分数据做一次 Merge 操作。同时为了保证数据的高安全,我们使用 Databricks Deep Clone 来做数据灾备,每天会定时更新来维护一张从表以备用。对于每日新增的数据,使用 Deep Clone 同样只会对新数据 Insert 对需要更新的数据 Update 操作,这样可以大大提高执行效率。

CREATE OR REPLACE TABLE delta.delta_{table_name}_clone

DEEP CLONE delta.delta_{table_name};

性能优化:OPTIMIZE & Z-Ordering

在流处理场景下会产生大量的小文件,大量小文件的存在会严重影响数据系统的读性能。Delta Lake 提供了 OPTIMIZE 命令,可以将小文件进行合并压缩,另外,针对 Ad-Hoc 查询场景,由于涉及对单表多个维度数据的查询,我们借助 Delta Lake 提供的 Z-Ordering 机制,可以有效提升查询的性能。从而极大提升读取表的性能。DeltaLake 本身提供了 Auto Optimize 选项,但是会牺牲少量写性能,增加数据写入 delta 表的延迟。相反,执行 OPTIMIZE 命令并不会影响写的性能,因为 Delta Lake 本身支持 MVCC,支持 OPTIMIZE 的同时并发执行写操作。因此,我们采用定期触发执行 OPTIMIZE 的方案,每小时通过 OPTIMIZE 做一次合并小文件操作,同时执行 VACCUM 来清理过期数据文件:

OPTIMIZE delta.delta_{table_name} ZORDER by device_id, indoor_temperature;
set spark.databricks.delta.retentionDurationCheck.enabled = false;
VACUUM delta.delta_{table_name} RETAIN 1 HOURS;

另外,针对 Ad-Hoc 查询场景,由于涉及对单表多个维度数据的查询,我们借助 Delta Lake 提供的 Z-Ordering 机制,可以有效提升查询的性能。

总结与展望

我们基于阿里云 Databricks 数据洞察产品提供的商业版 Spark 及 Delta Lake 技术栈快速构建了 IoT 数据处理平台,Databricks 数据洞察全托管免运维、商业版本引擎性能上的优势以及计算/存储分离的架构,为我们节省了总体成本。同时,Databricks 数据洞察产品自身提供的丰富特性,也极大提升了我们数据团队的生产力,为数据分析业务的快速开展交付奠定了基础。未来,美的暖通希望与阿里云 Databricks 数据洞察团队针对 IoT 场景输出更多行业先进解决方案。

原文链接
本文为阿里云原创内容,未经允许不得转载。

【实践案例】Databricks 数据洞察在美的暖通与楼宇的应用实践的更多相关文章

  1. Agora 教程丨一个典型案例,教你如何使用水晶球“数据洞察”

    7 月初,声网Agora 水晶球的"数据洞察"功能正式版上线."数据洞察"可显示两种数据,一种是用量,另一种是质量. "数据洞察"的&quo ...

  2. 《数据可视化之美》高清PDF全彩版|百度网盘免费下载|Python数据可视化

    <数据可视化之美>高清PDF全彩版|百度网盘免费下载|Python数据可视化 提取码:i0il 内容简介 <数据可视化之美>内容简介:可视化是数据描述的图形表示,旨在一目了然地 ...

  3. 美图App的移动端DNS优化实践:HTTPS请求耗时减小近半

    本文引用了颜向群发表于高可用架构公众号上的文章<聊聊HTTPS环境DNS优化:美图App请求耗时节约近半案例>的部分内容,感谢原作者. 1.引言 移动互联网时代,APP 厂商之间的竞争非常 ...

  4. 《SaltStack技术入门与实践》—— 实践案例 <中小型Web架构>3 Memcached配置管理

    实践案例 <中小型Web架构>3 Memcached配置管理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Memcached介绍 Me ...

  5. 实践案例:平安健康的 Dubbo3 迁移历程总结

    本篇是 Apache Dubbo 的实践案例.感兴趣的朋友可以访问官网了解更多详情,或搜索关注官方微信公众号 Apache Dubbo 跟进最新动态. 1 背景 我们公司从15年开始就使⽤dubbo作 ...

  6. 实践案例:同程艺龙网的 Dubbo 升级经验总结

    本篇为同程艺龙旅行网 Apache Dubbo 的实践案例总结.感兴趣的朋友可以访问官网了解更多详情,或搜索关注官方微信公众号 Apache Dubbo 跟进最新动态. 作者信息: 严浩:同程艺龙高级 ...

  7. T-SQL使用案例——结果数据前面自动补0

    原文:T-SQL使用案例--结果数据前面自动补0 现象: 在开发的过程中,往往需要数字和字符串互转.在转换的过程中,可能需要把1编程00001,这样的格式.实现这种样子是有非常多的方法,本文主要提供一 ...

  8. DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能

    DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己 ...

  9. 微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io

    原文:微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io 这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三 ...

  10. - 反编译 AndroidKiller 逆向 实践案例 MD

    目录 目录 反编译 AndroidKiller 逆向 实践案例 MD AndroidKiller 简介 插件升级 基本使用 实践案例 修改清单文件 打印 debug 级别的日志 方式一:直接代理 Lo ...

随机推荐

  1. Qt HTTP网络相关GET,POST(HTTP 模拟POST 表单(multipartform)最简单和正式的方法)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  2. 小米Linux 运维工程师面试真题

    小米Linux 运维工程师面试真题 首先我们来看下小米 Linux 运维工程师招聘岗位要求: [岗位定义]运维工程师 [岗位薪资]10K-24K [基本要求]北京 / 经验 3-5 年 / 本科及以上 ...

  3. 开发一个本地的供需求平台软件小程序单靠广告费就能月入3w+,你觉得香不香!

    最近合作了一个客户,需求是把现成的这种网站包装成App,在各大应用商店也能下载,做用户留存. 需求不复杂,现在已经完工了.事后处于好奇我又分析了一下这个项目的商业模式发现还挺好的,看前台数据基本上已经 ...

  4. 记录--npm, npx, cnpm, yarn, pnpm梭哈

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 依赖管理解决了在软件开发过程中管理和协调各种依赖项的问题,简化了开发流程,提高了项目的可靠性.可维护性和可重复性.它们帮助开发人员更高效地 ...

  5. 一个可以让你有更多时间摸鱼的WPF控件(一)

    前言 我们平时在开发软件的过程中,有这样一类比较常见的功能,它没什么技术含量,开发起来也没有什么成就感,但是你又不得不花大量的时间来处理它,它就是对数据的增删改查.当我们每增加一个需求就需要对应若干个 ...

  6. React组件封装:文字、表情评论框

    1.需求描述 根据项目需求,采用Antd组件库需要封装一个评论框,具有以下功能: 支持文字输入 支持常用表情包选择 支持发布评论 支持自定义表情包 2.封装代码 ./InputComment.tsx ...

  7. 网络设备性能指标之pps

    基本概念: Bps:Byte per second 每秒传输多少字节 bps: bits per second 每秒传输多少位 ,这个也叫做端口速率 pps:Packet Per Second(包每秒 ...

  8. Cesium 根据飞机航线计算飞机的Heading(偏航角)、Pitch(俯仰角)、Roll(翻滚角)

    需求 设置飞机的一些坐标位置(经纬度高度),插值得到更多的坐标位置,然后飞机按照这些坐标集合形成的航线飞行,飞机的朝向.俯仰角以及飞机转弯时的翻转角根据坐标集合计算得出,而不需要手动设置heading ...

  9. 数据解析之re正则表达式

    数据解析之re正则表达式 1. 正则基础 1.1 为什么使用正则 需求 判断一个字符串是否是手机号 解决 编写一个函数,给函数一个字符串,如果是手机号则返回True,否则返回False 代码 def ...

  10. #Dinic,最大权闭合子图#CF1473F Strange Set

    题目 分析 对于这种依赖关系,可以将正权值连源点,负权值连汇点, 然后 \(i\) 向 \(j(j<i)\) 连无穷大的边,注意到如果完全建图空间不够, 考虑记录每个约数最后一次出现的位置,直接 ...