资讯动态

Apache Doris在农业物联网时序数据实时分析中的落地实践

发布时间:2026/10/8 20:56:26 来源:尧图企业网站定制
我一直在做农业科技物联网这块前阵子接了个任务把几个示范园区里作物生长环境的实时数据全部汇总起来做统一分析和展示。数据源很杂有大棚里的温湿度传感器、土壤墒情站、光照传感器还有气象站每分钟的气象观测记录。刚开始数据量还不大一天也就几百万条等后面园区铺开了几分钟不上亿行说不过去。当时第一反应是从 MySQL 拆业务表但积累下来肯定扛不住。后来也考虑过 Hive 加 Spark 的离线方案但客户要的是“早上的数据下午能看趋势”的准实时效果离线链路太长。最后定下来用 Apache Doris把整个作物的生长数据分析平台搭在上面。折腾了两个多月从安装部署、建模导入到后面的查询优化和可视化踩了一堆坑也沉淀了不少可复用的经验。这篇文章就把整个项目从零到一的落地过程掰开来看重点说 Doris 在农业作物生长数据分析里到底怎么用又是怎么一步步把数据仓库、分析查询和前端大屏串起来的。1. 项目背景与Doris选型逻辑1.1 农业作物生长数据到底长什么样很多人一听“农业大数据”第一反应是地图、遥感影像、无人机视频那些。但实际上真正高频产生的恰恰是最不起眼的传感器时序数据。我们的田间部署了土壤温湿度传感器、空气温湿度传感器、光照传感器、CO₂传感器、雨量计、风速风向仪有些重点大棚里还有叶片茎流传感器。这些设备基本上按秒级或者分钟级上报每条记录就是一串带着时间戳、设备ID、数值、经纬度或者棚号的日志。举一个我实际处理的样例数据设备ID是DEV_ZHANG_001时间戳是2024-06-01 08:12:30数值包括空气温度28.6℃、空气湿度72.5%、土壤湿度35.4%、光照强度4800 lux、CO₂浓度420 ppm另外还有对应的大棚ID、作物品种奶油生菜、当前生长阶段苗期。这样的记录一个普通大棚一天大概是2到5万条五十个大棚一天就百万级。如果保持明细存储一年下来就是上亿加上以后农业数据治理要保存3到5年这个量完全达到大数据处理范畴。这类数据的最大特点四个字时间序列。所有分析都离不开时间窗口比如“看这几天土壤湿度的下降曲线”“对比不同大棚同品种作物的光照累计值”“统计过去一周每个时段的温度均值”。而且数据价值在于趋势和异常模式不在于某条单点值。所以数据平台的核心能力必须是按时间范围聚合扫描这种场景用传统关系型数据库硬查非常吃亏。1.2 为什么最终选择Doris而不是MySQL、Hive或ClickHouse这个选型论证我做了好几版也顺便把踩过的备选方案写出来方便有类似场景的朋友少走弯路。先看 MySQL。它是我们业务后台的主力库第一周试着把传感器原始数据全部写入MySQL按天分表结果从亿级数据里做一次时间段筛选加AVG聚合经常运行七八秒而且监控到磁盘IO和慢查询都明显恶化。MySQL在3000万以下可以说还得心应手农联网园区规模上来以后硬撑就只能靠分库分表中间件复杂度很快超过收益。再看 Hive 加 Spark 离线体系。数据仓库的规范性它很好但问题是链路重、延迟高。我们要喂给前端大屏的数据从采集到展示希望控制在5分钟以内Hive批处理加上调度排队很难做到准实时。而且Spark SQL 的调优本身非常吃经验如果团队没有专门的大数据运维真没必要为了“用Hadoop”而去搞一套重量级集群。ClickHouse 也是当时重点对比的对象。单列压缩、向量化执行聚合性能确实猛很多时序监控平台都在用。但它的上手门槛不低分布式表、本地表、副本仲裁机制、ZooKeeper依赖这些对一个小团队来说都是额外运维负担。另外我们还需要实时写入支持更新、删数据ClickHouse虽然也能做但要玩明白MergeTree家族的特性需要不少时间。最终选 Doris核心原因几个第一Doris是标准MPP架构同时兼容MySQL协议。意味着业务团队不需要学习新查询语言常用BI工具连接Doris就像连MySQL一样直接填写JDBC地址和账号密码就能用这对农业科技这种非互联网大厂环境特别友好。第二导入链路完整支持实时写入。Doris不仅支持Stream Load、Broker Load还能直接通过Routine Load消费Kafka数据这就打通了我们的“传感器 - Kafka - Doris”通道基本近实时更新数据延迟控制在秒级。第三智能物化视图和预聚合能力。对于每天都跑的固定报表可以通过物化视图把聚合结果提前存到后台查询时自动命中不用每条查询都全量扫。第四运维成本还是要比其他大数据组件低。整个集群只有FE和BE两类节点没有额外依赖ZooKeeper它内部元数据靠FE的BDBJE实现高可用对我们这种没有专职DBA的团队很友好。1.3 架构链路和整体设计确定Doris之后我画了一条非常朴素的数据链路没有上太多花架子组件传感器节点通过MQTT或者HTTP把采集记录推送到边缘网关边缘网关做简单的协议转换、时间对齐和数据过滤统一打包发到Kafka消费端用Doris Routine Load直接把Kafka里的JSON/CSV写进明细表日常查询走Doris FE由BE并行处理可视化层一部分接开源BI工具一部分让我自己写了封装接口给前端大屏和桌面客户端。这里有个细节边缘网关过滤不是简单去重而是要处理设备重连后重复上报和离线缓存补报。如果在源头没把重复数据降下来后面Doris导入时虽然也有max_filter_ratio兜底但会把脏数据积累到表里影响所有聚合结果。我们在网关侧维护了一个简单的“时间戳上限”缓存同一设备同一秒的数据默认只保留最后一次防止重复上报。2. 数据建模与表结构设计2.1 表模型选择Aggregate、Duplicate还是UniqueDoris的数据建模核心是理解三种表模型Duplicate Key、Aggregate Key和Unique Key。咱们把农业数据套进去看就非常清楚。对于传感器明细数据就是每一次采集产生的原始记录我们最需要的是留着、查、聚合分析所以我用了Duplicate Key。它的特点是明细不丢失存多少是多少。你按任意维度去复用到其他报表都可以不会因为预聚合丢了细节。代价是存储占用量大解决办法也只能靠分区淘汰和压缩后面会讲。对于按日生成的统计指标比如每个大棚每天的积温、日均湿度、最高光照我建议建Aggregate Key 模型表。写入时Doris会根据Key列做聚合SUM、MAX、MIN、REPLACE这些函数先算一层。这样报表查询速度飞快因为明细已经在后台塌缩好了。典型场景就是“日汇总表”Date、PlotID、CropType作为Key土壤湿度均值用AVG实际在Aggregate模型里用SUM/COUNT配合最高气温用MAX最低气温用MIN累计光照用SUM。对于需要更新的维度信息比如作物批次的当前生长阶段、预计采收日期、负责人变更就建Unique Key表。它实际上是Aggregate模型的一个特例把REPLACE作为聚合函数后写入的数据覆盖旧值。比如每天凌晨更新一遍作物批次的最新状态直接根据批次ID覆盖即可。2.2 分区分桶量化计算的几个关键参数不少人建Doris表时最纠结的就是分区分桶怎么设置。这块如果只凭感觉写后面性能差距会非常大。先说分区。我按record_time做Range分区一天一个分区一个分区的数据量大约400万到1000万之间对Doris来说比较合适。如果数据量实在小比如只有500万不到可以三天一个分区甚至一周一个分区。区间分区的另外一个好处是清理数据太爽了想删两个月前的历史数据直接删对应分区即可底层直接释放存储不会产生大量DELETE标记。再说分桶。Doris是分布式存储一个分区内的数据要切成若干桶每个桶是一个Tablet散落在BE节点上。分桶列一般用查询最频繁的等值条件字段我用的是device_id因为很多查询会按某一个传感器设备去查。也有时候会考虑用plot_id看业务侧哪种条件更常见。桶数量怎么定经验值是单个Tablet的数据量控制在1GB到2GB之间。如果每天一个分区大约600万行每行大概80字节总共就是480MB。那这个分区设32个桶就太多了设成8个桶比较合理。早期我图省事把桶数量设成64导致Tablet数量非常多FE元数据压力大BE之间调度复制也慢。后面改成合理桶数查询和导入都很稳。建表语句里要设置副本数。农业平台节点不算特别多我建议replication_num设为2或者3保证一个BE节点故障数据不丢就行。2.3 核心建表SQL示例直接给一段能跑的实际建表SQL这是我在建农业传感器明细表时的核心结构CREATE TABLE IF NOT EXISTS crop_sensor_detail ( record_time DATETIME COMMENT 采集时间, device_id VARCHAR(64) COMMENT 设备ID, plot_id VARCHAR(64) COMMENT 大棚/地块ID, crop_type VARCHAR(32) COMMENT 作物品种, growth_stage VARCHAR(32) COMMENT 生长阶段, temperature DOUBLE COMMENT 空气温度℃, humidity DOUBLE COMMENT 空气湿度%RH, soil_moisture DOUBLE COMMENT 土壤湿度%, sunlight_lux DOUBLE COMMENT 光照强度lux, co2_ppm INT COMMENT CO2浓度ppm, ph_value DOUBLE COMMENT 土壤pH值, batch_id VARCHAR(32) COMMENT 批次ID, raw_json VARCHAR(512) COMMENT 原始上报数据备查 ) ENGINE OLAP DUPLICATE KEY(record_time, device_id) PARTITION BY RANGE(record_time) ( PARTITION p20240601 VALUES LESS THAN (2024-06-02), PARTITION p20240602 VALUES LESS THAN (2024-06-03) ) DISTRIBUTED BY HASH(device_id) BUCKETS 16 PROPERTIES ( replication_num 2, storage_medium SSD, storage_cooldown_time 2024-01-01 00:00:00 );有几个注意点分区字段必须属于Key列而且建表时用VALUES LESS THAN指定边界后面新增分区最好用命令动态加不要靠手工拼。分桶字段也必须在Key中。因为Doris数据分布是根据Key的Hash。storage_cooldown_time设置了数据冷却时间过期后自动从SSD迁移到普通HDD对成本控制很有用。我留了一个raw_json原始字段用来保留完整上报数据方便后期发现解析错误时回溯。动态分区配置也需要开启CREATE TABLE crop_sensor_detail ... PROPERTIES ( dynamic_partition.enable true, dynamic_partition.time_unit DAY, dynamic_partition.start -30, dynamic_partition.end 1, dynamic_partition.prefix p );这样每天自动帮我把未来一个分区和过去30天分区创建好省得半夜凌晨爬起来建分区。2.4 数据导入方式从Kafka到Doris的准实时管道实时链路我用Routine Load消费Kafka数据这个功能非常贴合我们的场景。创建导入任务的SQL大致长这样CREATE ROUTINE LOAD rl_crop_sensor ON crop_sensor_detail COLUMNS(record_time, device_id, plot_id, crop_type, growth_stage, temperature, humidity, soil_moisture, sunlight_lux, co2_ppm, ph_value), PROPERTIES ( desired_concurrent_number 3, max_batch_interval 10, max_error_number 1000, max_filter_ratio 0.01 ) FROM KAFKA ( kafka_broker_list 10.0.0.11:9092, kafka_topic crop-sensor-log, kafka_group_id doris_routine_load_group )有几个参数必须要理解max_batch_interval控制最多攒10秒就导入一批保证准实时max_error_number是允许出错的条数上限max_filter_ratio允许最多过滤1%的数据比如某个传感器上报格式临时变了不至于让整个任务挂掉。大促期间如果某一类设备集体异常过滤比例超限任务会暂停需要人工介入排查这个要配个告警脚本。如果是历史数据首次灌入我建议直接用Stream Load从CSV文件或者直接从备份库导出导入速度快而且更好控制错误率。命令行举例curl --location-trusted -u root: -T crop_sensor_2023.csv \ -H label:crop_sensor_20230601 \ -H column_separator:, \ -H max_filter_ratio:0.01 \ http://localhost:8030/api/crop_db/crop_sensor_detail/_stream_load注意8030是BE的HTTP端口不是FE的8030实际集群里可以写任何一个BE。如果希望负载均衡可以在前端挂一层代理统一转发。3. 集群部署与调优实战3.1 集群规划FE、BE节点怎么分配Doris集群有两类关键节点FE负责元数据管理、SQL解析、查询计划生成BE负责数据存储和执行计算。生产环境建议至少3个FE1主2备BE节点按数据量扩。我们初期规模大概每天新增5000万条明细压缩后每天还不到100GB所以我用的是“4台物理机”的紧凑方案两台部署FE单独用SSD元数据最怕磁盘卡顿另外两台以及前两台中的剩余资源一起部署BE。但更推荐的做法是FE和BE分开部署避免FE元数据目录被BE数据文件目录挤占磁盘空间。如果只有两台机器又想要稳定我建议一台只放FE一台只放BE再用一台云主机做FE的Observer节点。BE节点少不要紧数据副本数设为2即可扛单节点故障。Doris官方文档里对硬件没有特别苛刻的要求普通x86服务器、内存能上64GB就挺舒服。FE节点内存不需要配置太高8G到16G足够支撑千万级Tablet数量的元数据关键是元数据写在SSD上不然FE重启恢复速度很慢。实际项目中我吃过BE目录放在机械硬盘的亏导入数据时磁盘IO直接顶满后面老老实实全换成了SSD。3.2 安装部署与关键参数解析Doris安装并不复杂下载对应版本二进制包解压后正常启动FE和BE就行。几个关键文件值得认真调fe/conf/fe.conf里我调整过的参数meta_dir元数据存放路径一定指到独立SSD不要跟操作系统盘共用。http_portFE的HTTP端口默认8030对外提供web UI和部分管理操作。query_portMySQL协议端口我用默认9030。max_java_heap_size建议设成4GB以上FE内存太小时元数据操作频繁会感觉卡。be/conf/be.conf里最核心的几个参数storage_root_path多个数据目录用分号分隔比如/data01/doris;/data02/doris这能让Doris自动把不同Tablet均衡到多块盘上。mem_limitBE进程内存上限默认是物理内存的90%这个对纯数据节点来说可以保留。如果主机上还要跑其他服务就得调低。max_stream_load_size单次Stream Load最大导入量默认其实不大做历史数据回灌时要调大我设置了5GB。集群启动顺序是先启动FE等FE进程状态变为FOLLOWER或LEADER后再启动BE节点然后通过MySQL协议把BE节点加进集群SHOW FRONTENDS; -- 检查FE状态 ALTER SYSTEM ADD BACKEND 10.0.0.12:9050; SHOW BACKENDS; -- 检查BE是否正常加入3.3 集群扩容和参数调优后面数据量涨上来了需要加BE节点扩容这个比想象中平滑很多。新BE节点启动并加入集群后Doris会自动把部分Tablet从旧节点迁移过来。扩容期间查询会有些波动但不会完全不可用。要注意的是加完BE节点后要观察它的TabletNum和DataUsedCapacity指标如果迟迟不均衡可以调小BE的tablet_repair_delay_factor或者手动执行ADMIN REPAIR TABLE。另外一个调优点Doris查询引擎默认开启向量化数量量小的时候可能感觉不到一旦大表聚合分析向量化优势非常明显。建表以及查询时可以显式使用SET enable_vectorized_engine true;来确认已开启新版本默认开启老版本需要设置。内存调优有个很容易被忽略的点BE的内存是共享的导入和查询都在抢。如果某段时间常做大规模查询同时又有高吞吐的Kafka导入任务可能BE内存被挤爆导致OOM或查询超时。我一般设定mem_limit80%另外在查询侧给高耗任务单独设exec_mem_limit避免一个慢查询把整个节点的内存池耗尽。4. 数据分析实践从SQL到可视化4.1 典型分析指标与SQL实现先拿走这类的数据落到Doris后最常用的几个分析SQL例子都是生产中跑过的可以直接套用。第一个场景按大棚、按天统计作物环境均值看生长环境是否符合设定区间。SELECT DATE_FORMAT(record_time, %Y-%m-%d) AS dt, plot_id, AVG(temperature) AS avg_temp, AVG(humidity) AS avg_humidity, AVG(soil_moisture) AS avg_soil_moisture, MAX(sunlight_lux) AS max_sunlight FROM crop_sensor_detail WHERE record_time 2024-05-01 AND record_time 2024-06-01 AND crop_type 奶油生菜 GROUP BY dt, plot_id ORDER BY dt ASC, plot_id ASC;这段SQL对明细表做按天分组聚合。由于分桶键是device_id如果查询条件里有大棚过滤建议把plot_id也放到分桶键或者建辅助索引否则Doris需要扫描该时间范围内所有设备的数据再过滤效率会低一些。第二个场景同一品种不同生长阶段的环境差异对比。比如看看苗期和成熟期对土壤湿度要求差多少。SELECT growth_stage, COUNT(*) AS sample_cnt, AVG(soil_moisture) AS avg_moisture, PERCENTILE_APPROX(soil_moisture, 0.5) AS median_moisture, STDDEV(soil_moisture) AS stddev_moisture FROM crop_sensor_detail WHERE plot_id IN (PLOT_01,PLOT_02) GROUP BY growth_stage ORDER BY field(growth_stage, 苗期, 生长期, 成熟期, 采收期);PERCENTILE_APPROX是Doris提供的近似分位数函数对传感器这类带噪声的数据非常实用。均值往往会被极端值带偏中位数更能反映整体水平。我一开始只用AVG发现有个大棚某个传感器故障导致土壤湿度持续报0均值立刻掉下去但实际中位数根本没有变化。后面排查异常就靠这个函数直接看中位数。第三个场景环境因子与生长速率的简单关系分析。Doris本身没有直接的皮尔逊函数但可以用窗口函数和聚合公式算。它也可以借助SQL的协方差和标准差组合来计算SELECT plot_id, (SUM((temperature - avg_temp) * (leaf_growth_rate - avg_rate)) / (SQRT(SUM(POW(temperature - avg_temp, 2))) * SQRT(SUM(POW(leaf_growth_rate - avg_rate, 2))))) AS corr FROM ( SELECT plot_id, temperature, leaf_growth_rate, AVG(temperature) OVER (PARTITION BY plot_id) AS avg_temp, AVG(leaf_growth_rate) OVER (PARTITION BY plot_id) AS avg_rate FROM crop_growth_stat ) t GROUP BY plot_id;这个SQL是按棚计算温度和叶面积增长速率的相关系数虽然底层扫描量很大但在几亿行表里跑也还行因为分区裁剪和向量化已经把性能拉得很高。如果频繁用建个物化视图更划算。第四个场景跨日累计数据看有效积温。农业上有个“有效积温”概念用来判断作物发育速率。计算逻辑是把日均温超出基准温度的部分累加起来。SELECT plot_id, SUM( CASE WHEN avg_temp 10 THEN (avg_temp - 10) ELSE 0 END ) AS effective_gdd FROM ( SELECT plot_id, DATE_FORMAT(record_time, %Y-%m-%d) AS dt, AVG(temperature) AS avg_temp FROM crop_sensor_detail WHERE record_time 2024-02-01 AND record_time 2024-04-01 GROUP BY plot_id, DATE_FORMAT(record_time, %Y-%m-%d) ) day_temp GROUP BY plot_id ORDER BY effective_gdd DESC;这个就是标准积温计算可以根据积温预测下一阶段大概什么时候出现。生产里这个查询每天凌晨跑一次把结果写到Aggregate汇总表供业务方直接读取。4.2 可视化大屏与BI接入方案Doris的数据最终需要投到前端大屏上这里我分别尝试过两条路开源BI工具和自研Web接口。开源BI我推荐用Superset或者DataEase两者都能很自然地通过MySQL协议连Doris。DataEase对国内数据大屏模板支持更多一些直接连接MySQL数据源把Doris地址填进去就能用。要做更灵活的可视化直接用ECharts写大屏前端后端写一个Spring Boot接口用JDBC查询Doris返回JSON给前端渲染。注意连接池的选择要适配高并发查询我用的Druid连接串里加上useServerPrepStmtstrue能明显减少SQL解析开销。4.3 桌面客户端大数据表格卡顿的优化实战这里提一个跟“农业科技”看似关系不大、但实际在我们温室内桌面端监控里发生过的问题客户要在PC端展示全园区传感器最近一周的所有明细数据带滚动查看和数据导出。最开始用QTableWidget写数据量一上万就卡成PPT。后面翻出了Qt大数据表格优化的经典思路把QTableWidget换成QTableView加自定义QAbstractTableModel用模型-视图分离不预先创建上千个单元格控件而是只生成视觉可见区域的Item滚动时按需刷新完美解决。具体做法是重写自定义Model继承QAbstractTableModel在data()方法里根据index去内存数组取值rowCount()返回总行数headerData()返回列头。绑定到QTableView之后只给表头设置了setSectionResizeMode同时关闭了网格线和编辑滚动流畅度提升了好几个量级。再用一个后台线程查Doris数据一次性加载到内存前端只做纯展示。几十万条数据的表在这个结构下完全能扛住。4.4 查询性能与加速技巧最后说几个给Doris查询提速的实战技巧分区裁剪必须保证查询条件里有时间范围。很多慢查询都是没带过滤条件Doris被迫扫全表这时无论分桶多合理都白搭。常用固定聚合建物化视图。我根据“设计阶段每天每个大棚都要出日汇总”这个固定需求建了一张日汇总物化视图查询时Doris会自动改写计划命中物化视图速度能快20倍以上。对查询频率高但数据量小的维度表建议设置replication_num2并尽量让数据放在快速存储上。写SQL时避免SELECT *只取必要列既能减少网络传输也能让Doris只扫描对应列的数据。5. 常见问题与踩坑实录5.1 外部引擎连接Doris报“missing”相关错误我们在把Doris接入Presto的跨源查询时碰到过一个挺隐蔽的错误提示“Relation xxx missing database/schema”。当时第一反应是表不存在但用MySQL协议直接查又是好的。后面排查半天才发现是Presto连接器里connector.namedoris后查询时必须写三段式命名即catalog.database.table而我们的查询语句只写了两段Presto把它当作默认schema里的表结果始终找不到。解决方法非常简单确认JDBC URL路径完整写好jdbc:mysql://fe_host:9030/your_db并且在SQL里写全catalog.db.table如果用了旧版本的Presto-Doris驱动还要检查驱动里对库名和表名大小写的处理。这个现象比较典型一般排查顺序是首先确认Doris侧表存在接着检查连接驱动版本和URL最后看查询SQL的命名空间。5.2 BE节点掉线和Tablet副本缺失问题有一次服务器机房短暂断电重启后BE节点注册不回来查询直接报tablet missing数据表现出部分空洞。这里最重要的排查工具是SHOW BACKENDS; SHOW TABLET FROM crop_sensor_detail; ADMIN SHOW REPLICA STATUS FROM crop_sensor_detail;发现某个BE节点状态还是false说明进程起来了但心跳没有正常上报。到BE节点日志里看到磁盘检查失败原来是数据目录的软链接被人为改动过。把软链接恢复后重新ALTER SYSTEM ONLINE BACKEND ip:port;才恢复。副本缺失后Doris会自动从其他副本恢复数据这个期间所有访问都尽量选择存活副本所以感觉不会完全断但如果有2副本都挂了同一分区查询就会报错。此时只能从备份恢复或重新导入数据所以备份习惯越早建立越好。Doris的数据备份我用的官方BACKUP命令每天把最新分区备份到远端对象存储。注意BACKUP是元数据加数据文件的逻辑备份恢复速度不至于很快但至少能兜底。5.3 李鬼数据导致聚合值异常前面用中位数排查过传感器故障这里专门提一下。传感器上报偶尔会出现数值跳变比如湿度从70%直接变0%Doris不会帮你判断数据合理性照单全收。所以导入前最好在网关侧实现一层范围校验超过合理上下限的数值直接重标或丢弃。如果已经进了Doris查询时也要用条件过滤异常值SELECT ... WHERE temperature BETWEEN -20 AND 60 AND humidity BETWEEN 0 AND 100这种过滤条件要写进公共视图让所有下游查询默认都带不然每次写SQL都有人忘。5.4 数据导入慢或者任务暂停Routine Load偶尔会出现导入任务暂停的情况。最典型的原因是消费Kafka延时太高或者Kafka里出现了超大消息体超过了单条限制。排查步骤是用SHOW ROUTINE LOAD;查看任务状态查看RL_RUNNING中的OtherSortMessages和ErrorLogs;如果某分区offset非法可以用PAUSE ROUTINE LOAD、RESUME ROUTINE LOAD来恢复。我们在导入时还遇到过时间字段格式不统一的问题。有的设备上报2024-06-01 08:12:30有的上报2024/06/01 08:12:30还有的上报Unix时间戳。这种情况Doris导入会自动失败。我在Routine Load里增加了一个自定义列转换逻辑把时间字段先用from_unixTime和str_to_date函数处理再写入。建任务时用COLUMNS(record_time str_to_date(datas[时间], %Y/%m/%d %H:%i:%s), ...)这样能灵活兼容多种源头格式。5.5 时序采样延迟导致的虚假波动这个问题我们常忽略Doris里的数据时间戳是设备上报时间但这个时间跟实际采集时间可能存在偏差。物联网设备经常因网络抖动把多条记录攒成批一起上报Doris里看到的效果就是某个时间点“毫无征兆”地出现密集数据另一个时间点却是空档。这在分析时序曲线时是非常干扰的。我们的处理方式是在网关侧增加“采样等待窗口”比如规定每5秒最多向Kafka发送同一设备的记录超过时间窗口的记录合并。同时在Doris查询里尽量用分钟级聚合来抵消秒级抖动。千万不能直接使用单秒原始数据出趋势图曲线不是真实变化而是网络噪声。6. 个人经验总结与踩坑提示这个项目从部署Doris到现在也跑了快半年了最大的体会有几个。第一农业数据里的“脏”跟互联网日志的“脏”很不一样它是设备物理噪声上下跳变、漂移、断档这些要靠业务规则清洗不能完全依赖计算引擎容错。第二Doris真正舒服的地方不只是快而是它对中小团队很友好不用专门养一个大数据平台组专职DBA加一个后端开发就够支撑整套数据分析体系。第三所有建模优化最好从业务查询反推。我们先列清业务到底要哪几个报表、哪几个指标再去设计分区、分桶、物化视图效果比上来就想搞“完美数据仓库”好太多。最后再分享一个小技巧建议大家把生产环境里的慢查询日志定期拉出来分析高频SQL的共性然后把能通过物化视图、分区裁剪解决的都解决掉。我在这个项目里就是靠这招把原来经常超时的十几个查询全部优化到秒级。数据平台从来不是一次建完就完事它是跟着数据增长和业务变化不断长出来的Doris给我最大的感觉就是这个“生长”过程要比很多其他组件平滑不少。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑