V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tuine
V2EX  ›  程序员

数千个设备的实时数据,每 30 分钟内存储最大值即可,如何设计方案?

  •  
  •   tuine · 2021-12-26 22:20:38 +08:00 · 2966 次点击
    这是一个创建于 823 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如数千个温度传感器,每 5s 采集一次数据,后期数据使用只会使用每 30 分钟内最大值,由于大数据及实时数据处理经验较少,目前考虑是数据存储到 kafka 中,然后消费端使用 Redis 存储当前 30 分内最大值,并持续对比更新最大值,且每过一个 30 分钟循环则刷新一次 redis 值到时序数据库,求教

    第 1 条附言  ·  2021-12-27 09:46:35 +08:00
    可能描述没太清楚:
    5000 个设备,每 5 秒一条数据,一天 8640w 条数据,但实际分析和展示报表只会使用 30 分钟内的最大值(实际时间 00-30 ,30-59 分)非滑动窗口,所以打算只存中 30 分钟内最大值到数据库,之前预想是刷新本次 30 分钟内最大值存到内存中,每过一个 30 分钟存储一次最大值到数据库,这样一天大概 24w 条数据,这个数据量关系库也没啥问题了
    32 条回复    2021-12-28 23:55:25 +08:00
    masterclock
        1
    masterclock  
       2021-12-26 22:37:29 +08:00
    Influxdb 存储每 5 秒的数据,然后搞个 continuous 的 notebook 就差不多了。
    其他的 TSDB ,如 TimescaleDB (continuous aggregation)也都有类似的机制。
    git00ll
        2
    git00ll  
       2021-12-26 22:57:08 +08:00   ❤️ 1
    30 分钟是指现实世界中的每 30 分钟作为一个区间吗?
    感觉建张表存就可以了,内存里持有当前区间最大值,处理数据时比内存中值大就更新到数据库,否则就跳过。

    如果是滚动 30 分钟,可以使用找个时序数据库用一下。
    ipwx
        3
    ipwx  
       2021-12-26 22:58:51 +08:00
    为啥我觉得你用 c++ 写个程序用内存 map 就能扛下来。。。
    wangyu17455
        4
    wangyu17455  
       2021-12-26 23:32:33 +08:00 via Android
    mysql 存储时间和温度,查的时候走时间索引,查最近半小时所有数据然后 max 函数取最大值
    T0m008
        5
    T0m008  
       2021-12-26 23:46:01 +08:00
    每 5 秒几千个数值不算啥大数据,随便什么数据库都能轻松搞定
    lauix
        6
    lauix  
       2021-12-27 00:11:59 +08:00
    TSDB 了解下,当然没多少数据 redis 完全可以胜任
    1423
        7
    1423  
       2021-12-27 00:22:53 +08:00
    现在方案就挺好的,不用改
    vance123
        8
    vance123  
       2021-12-27 00:39:16 +08:00 via Android
    笑死,几千个数据存 JSON 里都可以
    lyz1990
        9
    lyz1990  
       2021-12-27 00:44:59 +08:00 via Android
    放内存得了
    learningman
        10
    learningman  
       2021-12-27 00:46:58 +08:00
    才这点,map 套 priority_queue 就好了
    Rocketer
        11
    Rocketer  
       2021-12-27 00:55:52 +08:00 via iPhone
    看得不是很明白,你是总共每 30 分钟产生一条数据,还是每台设备每 30 分钟都要产生一条数据?

    5 秒钟的那个算临时数据,不该进数据库,直接内存里处理就行。
    f165af34d4830eeb
        12
    f165af34d4830eeb  
       2021-12-27 01:04:27 +08:00
    既然用了 kafka ,可以看看 ksqldb ?感觉 ksqldb 给的样例场景和你的需求挺接近的
    geniussoft
        13
    geniussoft  
       2021-12-27 01:33:00 +08:00
    怎么感觉内存里随便放一下,然后 JSON 或者 XML 序列化都行呢...
    pengtdyd
        14
    pengtdyd  
       2021-12-27 08:59:14 +08:00
    这点数据光盘就能搞定了
    xukongyang
        15
    xukongyang  
       2021-12-27 09:00:15 +08:00
    可以学习一下 tdengine ,轻量、简单、易用.
    ebingtel
        16
    ebingtel  
       2021-12-27 09:34:47 +08:00
    flink 等类似的滑动窗口都可以……如果场景简单,你目前的方案就不错了
    tuine
        17
    tuine  
    OP
       2021-12-27 09:50:16 +08:00
    @git00ll #2 对,不是滑动。现在想的就是这种方案,数据量也没那么大
    tuine
        18
    tuine  
    OP
       2021-12-27 09:51:17 +08:00
    @T0m008 #5 那一天也 8 千多万数据,要是直接存储到 mysql 这种也不太好吧
    tuine
        19
    tuine  
    OP
       2021-12-27 09:52:24 +08:00
    @xukongyang #15 目前就是打算用这个,而且是国产 TSDB
    tuine
        20
    tuine  
    OP
       2021-12-27 09:53:13 +08:00
    @1423 #7 好的,3Q ,先按这个方案落地,后续再优化吧
    tuine
        21
    tuine  
    OP
       2021-12-27 09:54:57 +08:00
    @Rocketer #11 每台设备每 5s 都产生一条,算作临时数据,这样 30 分钟存一次数据量就下来了
    tuine
        22
    tuine  
    OP
       2021-12-27 09:55:51 +08:00
    @vance123 #8 😂要是几千个我就不问了。。。可能没描述太清楚,Append 重新说明了一下~
    yolee599
        23
    yolee599  
       2021-12-27 10:04:22 +08:00
    在设备端统计好 30 分钟最大值再上传服务器,如果要调整间隔可以设计一条设备配置指令来配置
    glfpes
        24
    glfpes  
       2021-12-27 12:40:44 +08:00 via iPhone
    Redis zset
    zrt
        25
    zrt  
       2021-12-27 13:29:11 +08:00
    看起来 c++写个单调队列就可以解决
    SmiteChow
        26
    SmiteChow  
       2021-12-27 14:37:11 +08:00
    就这点数据不用思考任何算法
    YouKnowIt
        27
    YouKnowIt  
       2021-12-27 16:36:40 +08:00
    数千个设备数据直接放内存,我估计你的数据 1gb 都用不完,每 30 分钟 load 到 db 中就行,注意内存读写锁
    frozenshadow
        28
    frozenshadow  
       2021-12-27 16:50:23 +08:00
    想玩一下的话,可以看看 flink 。可以按照 30min 时间窗计算
    cnuser002
        29
    cnuser002  
       2021-12-27 17:01:20 +08:00
    你的设备上报是 5 秒一个,但是你实际是每个 30 分钟存一个值到数据库。

    那你的主要工作,其实就是写一个比较程序,将每台设备每次上报的数据,跟 30 分钟段内最高的温度,做一个比较就行了。

    到点把最高值往数据库里写就完事了。

    那我感觉,你也没必要搞 Redis ,用你熟悉的语言把这个变换的流程,写一下就 Ok 了。
    tuine
        30
    tuine  
    OP
       2021-12-27 17:08:43 +08:00
    @frozenshadow #28 准备学习一下 玩个试试
    tuine
        31
    tuine  
    OP
       2021-12-27 17:09:00 +08:00
    @cnuser002 #29 是这个道理
    jellyspot
        32
    jellyspot  
       2021-12-28 23:55:25 +08:00
    你这个我理解就是个监控需求么,Prometheus 能实现采集监控,然后也可以用 promql 查询出 30 分钟最大的值,然后把这个值写到数据库之类的就行了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3040 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 14:54 · PVG 22:54 · LAX 07:54 · JFK 10:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.