设计: 一个统计设备上下线的方案

2021-03-30 11:56:43 +08:00
 lanqing
假设有 10000 台设备,统计任意 A 天到 B 天的某设备 SN 的在线时长
我能收到每台设备的上线下线消息。
如何存储,如何查询,大佬们有啥方案么?

本人不才,设计到 mysql 存储每台设备每天的上下线消息,但是不管是查询还是设计,都感觉丑陋无比,有啥更好的方案么?
4741 次点击
所在节点    Python
39 条回复
wangyuhang
2021-03-30 12:18:04 +08:00
你现在有哪几个方案,说下
dapang1221
2021-03-30 12:22:21 +08:00
能保证一个上线消息必定会受到一个下线消息吗?能的话一条记录两个字段,上线时间、下线时间,用这俩一减。不能保证的话,做心跳包机制,收到消息的数量 * 心跳包间隔就是在线时间
vcfghtyjc
2021-03-30 12:29:04 +08:00
感觉问题描述的不太清楚呀。是要设计数据库,还是设计整个系统架构?
opengps
2021-03-30 12:34:37 +08:00
我也有过类似的设计,设计出来总感觉不完美,似乎关系型数据库用起来不匹配
IvanLi127
2021-03-30 12:47:54 +08:00
今日每台设备每次上下线消息存 redis 或者数据库,次日定时统计。redis 用 list 存上线时间 下线时间,list key 日期+设备编号,应该差不多了
oott123
2021-03-30 13:20:40 +08:00
首先做个数据库,redis 还是 mysql 不重要,把设备 ID 存进去,在线状态设为不在线
收到上线消息,去数据库里改成在线;下线消息同理

然后配一个 Promethues,监控项是每台设备的当前在线情况

搞完了,然后你想用什么时序数据库存想怎么查都可以
xcstream
2021-03-30 13:25:24 +08:00
定义任务 每天计算一下所有设备的在线时长
lanqing
2021-03-30 14:05:42 +08:00
@dapang1221 上线下线存一条消息,我担心 10000 台*100 天*10 次上下线 = 1000W 条数据,mysql 查询会不会有点性能问题
lanqing
2021-03-30 14:06:11 +08:00
@vcfghtyjc 能够存储,能够查询就行了
lanqing
2021-03-30 14:08:46 +08:00
@oott123 时序数据库能解决天到天的查询是么?我去看下
scofieldpeng
2021-03-30 14:47:48 +08:00
要统计在线时长,首先定义怎么判定在线这个过程,如果是设备会自动上报,

你只有 1w 各设备,mysql 一张表就能解决,

sn,first_report_time,last_report_time 这 3 个字段就可以完成你说的时长+统计,每个设备每天一条记录,当收到上报信息的时候,看下这张表 sn 有没有今日的记录,没有的话 insert,first_report_time,last_report_time 写入上报时间,有的话就只需要更新 last_report_time 就好了

楼上说的普罗米修斯啥的,真没必要
scofieldpeng
2021-03-30 14:49:34 +08:00
一天 1w 条记录,就算跑一年也才 365w 条记录,这点量,太小了,随便玩
Slartibartfast
2021-03-30 14:53:38 +08:00
你这个用 MySQL 足够了,如果太大,就按照时间或者设备 id 分库分表。
4kingRAS
2021-03-30 15:24:08 +08:00
id 一个表,device 一个表包括上线 timestamp 。下线 timestamp, 上下线的 log 一个表,记录 id,时间,动作。
统计用 log 表在 Java 里统计。
silencegg
2021-03-30 15:26:26 +08:00
CREATE TABLE `heart_beat` (
`sn` varchar(50) DEFAULT NULL COMMENT 'sn',
`start_time` varchar(50) DEFAULT NULL COMMENT '心态开始时间',
`end_time` datetime DEFAULT NULL COMMENT '心跳结束时间',
`online_time` bigint(20) DEFAULT NULL COMMENT '在线时长',
`creat_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`reason` varchar(50) DEFAULT NULL COMMENT '原因'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='心跳'
silencegg
2021-03-30 15:27:40 +08:00
这个是之前我用 EMQ 监听设备上下线的表来统计设备在线时长
4kingRAS
2021-03-30 15:28:47 +08:00
原来是担心一天内上下线次数太多啊,那就做个 trigger,log 表限制为只记录当日,0 点统计时长存入一个专门统计时间的表:id ,日期,第一次上线,最后一次下线,在线时长。虽然多了一个表,但是比较灵活。
q149072205
2021-03-30 15:41:20 +08:00
还有一个问题,如果第一天上线一直没下线 ,到第二天下线你要怎么统计
Lee2019
2021-03-30 15:42:29 +08:00
用 influxdb 之类的 tsdb 呢?
甚至直接写到 prometheus 里面?
{sn="xxx", active=1/0}这种?
LeeReamond
2021-03-30 15:46:05 +08:00
以天为单位展示就以天为单位储存,每天登录多长时间通过业务维护,整个系统很简单

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/766456

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX