仅有且已有 redis+mysql+mongo 。
目前已采用两种方式:
请问最合理、性能开销最小的方案是什么。请教大家一些经验。
1
LsLsLsLsLs 312 天前 1
redis bitmap
|
2
yannxia 312 天前
最快的肯定是 IOT 数据上传的时候就通过 Redis 的 Sub/Pub 一类的机制让服务端缓存在内存里,那 5w 就立等可取(从内存里拿)缺点嘛,不一致就想办法补偿(去数据库同步啥的)
|
3
retanoj 312 天前
需求是想统计出各种状态的计数和吗?
|
4
opengps 312 天前
内存表
|
5
des 312 天前
不说说一次性获取这么多是做什么用,列表也显示不下吧
感觉像是在线/离线统计 |
6
ytmsdy 312 天前
在 iot 的固件里加入心跳请求吧,三秒或者 10 秒一次心跳。
把设备 ID 号丢到 redis 里面,设置 60 秒的过期时间,有心跳包上来了,就把值刷新一下。 需要统计有多少设备的话,直接统计一下 redis 里面有多少个 key 就可以了。 |
7
gongquanlin 312 天前
iot 上报时改变 mysql 状态很容易就把 mysql 干炸,之前因为这个吃过很多次亏了;就缓存到 redis 里,一般不存在性能瓶颈,定期根据 key 取模分批的同步到数据库里; model 封装一下,先读缓存,缓存没有再读库(这时候基本上就是掉线了)
维护好 redis 就行了 |
8
wanwaneryide 312 天前
根据对设备状态重要程度的重视程度吧,比如说比较一般般的话,设置设备 1 分钟上报一次状态,连续多久都是非正常的状态就提醒管理者啥的。如果对时效性比较重视,30s 或者 15s 或更短上报一次状态。何必每次查看的时候再去获取状态。如果每次查看都获取一次的话,假如这批设备多人多账号管理,极端的情况,几个人间隔几秒或者几十秒刷新一下页面,服务器得炸
|
9
me1onsoda 312 天前
这一看就是列数据库的长项。redis mysql mongo 都不太符合。
如果状态只有 01 的话用 redis 的位图吧 |
10
nothingistrue 312 天前 1
在线离线的变更,你要用连接打开、关闭事件,以及心跳事件来触发,不要依赖业务数据上报。
要是追求强一致性,那就让 IOT 服务器先自行管理在线设备集合(一般你要有下行数据需求的话,这个是必须的功能),每次查询时,基于 IOT 服务器汇报的在线设备集合,来计算待查询设备集合的在线状态。 要是不需要强一致性,那就是你的方式 2 。 至于性能开销,实际上没法直接评估,这个是随环境变更的。比如上面俩方案,第一个性能耗费在数据读方向上面,第二个性能耗费在数据写方向上面。如果平均每设备每天上下线 1000 次,则第一个方案性能好。如果设备一两年才上下线一次,则第二个方案性能好。 |
13
unt OP @nothingistrue #10 谢谢,你提供了另一种思路,通过服务器来管理,我考虑下可行性。
|
16
retanoj 312 天前
感觉 10 楼回答了服务端记录在离线状态的问题。
对于“GIS 展示”这个事情,我咋觉得不用考虑“一次获取”,而分批获取+有过程的展示在前端效果上可能更有好一些 |
18
unt OP @gongquanlin #7 单次操作确实没问题,并发操作就炸了
|
19
Mithril 312 天前
你 5W 个设备要是时钟很准,卡在同一秒上报状态的话,那就是极限状态下一秒 5W 的写操作,你那数据库分分钟就干爆了。而且你要的是“状态转换”而不是“当前状态”。
要是我的话,会做一个用来缓冲和过滤的组件,来维护这个状态,并当数据改变时再分批写入数据库。 直接做个简单的 webserver ,内存里维护一个数组。收到数据时对比一下已有数据,如果有变更就塞队列里,然后 mysql 定期从队列同步状态写回数据库。 这程序甚至都不用做持久化,每次启动的时候从数据库里读一次全局状态,或者等 30 秒后设备给你发过来就行了。 但还是同样的问题,如果你 IoT 设备时钟很准,你这 webserver 也要好好设计才行。50K 的 IOPS 写操作对于单个 server 也不是个随随便便就能搞起来的。但好在这简单的 server 你可以横向拆分,根据请求来源的设备做个路由,分到几个实例里就行了,非常容易。 |
20
kirory 312 天前
5W 也不多啊,真有性能问题直接放应用里放个 map 不就行了
|
21
allenby 312 天前 via Android
redis bitmap 不错
|
22
xmumiffy 312 天前
5w 用 redis 有啥好怕的
|
23
totoro52 312 天前
我之前阅读 thingsboard 源码他是两种都做的, 数据库也更新面板统计也存在缓存里
|
24
cutchop 312 天前
5w 又不多,直接读 mysql 不就好了吗
|
26
iv8d 312 天前
都是临时状态,一般存内存或 redis 里,没必要存 rdbms
|
28
cnsdytedison 312 天前 via Android
你说的这个 aws 家有现成的方案,可以参考。不过我也没用过,只是看过宣传。推广期价格也不贵
|
30
LiaoMatt 312 天前
设备离线上线更新数据库, 在线状态的维持靠心跳或者消息更新缓存, 然后定时读缓存刷新状态, redis 读 5W 应该还是很轻松的, 如果对实时要求不高直接通过数据库做聚合, 几万条数据应该也很轻松
|
31
LiaoMatt 312 天前
放数据库一半是因为要用设备在线状态做业务, 筛选排序, 或者一些关联数据查询需要指定某种状态的设备
|
32
ITdream 312 天前
上 IoTDB
|
33
koloonps 312 天前
在集群内部广播一下,让每个服务发送下当前在线客户端列表.
|
34
hamsterbase 312 天前
如果是实时上报的话,是不是直接在内存里维护一个 map 就行了。
1. 在内存里维护一个 map 2. 定时将 map 的数据备份储存。 |
35
unt OP |
36
a67793581 311 天前 via Android
op 记得更新一下最终方案 回馈社区
|
37
F7TsdQL45E0jmoiG 311 天前
这种是典型是时序数据,用时序数据库最好,最简单的实现方式是 Prometheus
|
38
yc8332 311 天前
不知道你存的数据多少?。。不大的话,redis 主从,查询从从库查,直接一次性 hgetall 出来,几十万一点问题都没有。
所以你说的海量到底是多少?真是海量也不可能会一次性需要把所有数据都展示。顶多做个多少在线这种,这样只要取计数就好了。具体要查看某些目标的值的时候再取详细的 |