1
skallz 3 天前
如果查询范围不大的话,可以考虑直接让前端拿对应文件的内容前端处理,让客户端分担服务端的性能压力,哈哈哈哈,前提是你的文件服务器和业务服务器不是同一个服务器,比如用的云服务商 oss 之类的
|
2
chihiro2014 3 天前
为什么感觉应该是使用 influxdb 之类的产品,而不是 mongo
|
3
xiaofsu 3 天前
最好的办法就是换个时序数据库。
|
4
daxin945 3 天前
如果是我的话可能会用 clickhouse 替换 mongo
|
5
MoYi123 3 天前
没必要, 数据库一般会用一些压缩算法, 肯定比你支持存 json 文件要省的.
数据库里用 partition table, 按日期分 内存溢出肯定是你代码有错, 86400*200 个 float 应该还不到 100MB. |
6
timethinker 3 天前
mongodb 从 5.0 开始支持时间序列( Time Series ),可以提高查询速度。
https://www.mongodb.com/docs/manual/core/timeseries/timeseries-procedures/ |
7
sagaxu 3 天前
数据总量是多少,每次查询返回多少,有点儿慢是多慢,查询是怎么写的,这些都没讲清楚,不大好分析。
|
8
Oldletter 3 天前
MongoDB 支持 TTL 索引,允许自动删除超过指定时间的数据。你可以为 time 字段创建一个 TTL 索引来确保数据库中只保留 3 天的数据,这样就不需要手动写脚本来删除过期数据。
你的数据感觉不是特别大,所以建议你看看代码问题吧 |
9
iamtuzi3333 OP @skallz 范围也大,会查询去年某一个月的所有数据,前端处理不太现实,现在文件跟业务都在一个服务器。
@chihiro2014 我之前看过这个,但是他对 json 格式数据不太友好,部署相对麻烦。 @xiaofsu 看了部分时序数据库,发现部分接口、迁移、数据格式不太方便。 @daxin945 我查查这个数据库看看效果。 |
10
iamtuzi3333 OP @MoYi123 内存溢出是 node 的问题好像,我试过查询去年某一段时间的数据,他就查询内存栈溢出了。
@sagaxu 数据总量很多,每天 86400 条 json 存入,每次查询返回不定期,就是得根据前端传回的时间范围作为查询条件,有时候会查询去年某一段时间的数据,慢的时候主要是等待很久,数据库的每个集合的 timestamp 字段有做索引。查询代码如下: // 获取 MongoDB 原生数据库连接 const db = mongoose.connection.db; // 获取指定的集合 const collection = db.collection(collectionName); // 构建查询条件 const query = {}; const timestampInt = parseInt(timestamp, 10); query.timestamp = timestampInt; // 查询数据 const result = await collection.find(query).toArray(); if (result.length <= 0) { ctx.status = 200; ctx.body = { message: 'no data', data: [] }; return; } @Oldletter 代码相对来说比较简单,就是传入集合名字,时间范围,就去对应的结合查询,查询代码如上,后端用的 node ,koa 框架,但是我发现 Mongo 的数据迁移不太方便,比如说我要把 a 服务器的某一个库的所有数据转移到 b 服务器的 Mongo 实例中,就不太方便了。 |
12
sagaxu 3 天前
前端查一个月的数据干嘛用?浏览器根本无法展示。显然要做好聚合,缩小数据规模。
|
13
aloxaf 3 天前
没用过 MongoDB ,不过这类时间序列数据查询的优化方向都是差不多的:
1. 提前按天、按小时聚合数据,根据查询范围来调整返回数据的精度。就像楼上说的,一个月的数据得上百万条了,前端要这么多数据干嘛。 2. 原始数据可以存的时候就按小时打包来存,没必要每秒生成一条记录。 3. 你这数据量也不大,但不知道 MongoDB 存这些数据效率如何,如果太占空间可能要考虑对旧数据降采样(你真的需要查询三年前某分钟内每秒的数据?)或者转冷存储。 不过还是推荐直接用数序数据库,不仅速度更快还节省空间,而且「优化花费的时间」未必比「迁移花费的时间」更少,除了 influxdb 外也可以看看 timescaledb ,对于有 sql 经验的人来说迁移真的方便) |
14
iamtuzi3333 OP |
15
nivalxer 3 天前
场景比较类似,只不过我们这边传感器数据没有到每秒,一般大概 10 几秒到几分钟不等。
目前也是 Mongodb 的方案,按每个站点(一个站会有多个参数)一张表方式存储,每个小时会抽一条数据放小时表,统计报表再根据公司配置进行公司表级的存储。 Mongodb 需要考虑查出来的文档返回不能超过 16M ,虽然有一些配置可以绕过限制。目前感觉在数据量比较多,也根据查询条件(时间等)加了索引情况下,响应速度一般。 如果数据比较频繁并且需要偶尔查出来比较多的历史数据(多天、月、季度)还是看看其他的方案,目前我也想看看有没有除 MongoDb 外的其他更好的方案。 |
16
hd10180 3 天前
|
17
securityCoding 3 天前
时序数据库干的活不要硬来
|
18
yyt6801 3 天前
楼上都提到的时序数据库就是为了解决这种问题, 首先你要知道 每秒的那个 data:[]里面都代表什么东西;知道结构其他都好办了, 剩下的交给时序数据库解决
|
19
sagaxu 3 天前
@iamtuzi3333 “比如每十分钟提取一个最大值”,这个事情可以提前做好。我之前做过一个数据结构类似的项目,有分钟汇总,小时汇总,天汇总,都是提前生成缓存好,当日数据还会存一份在内存里加速访问。一般查询都有个特点,时间段跨度越大,越不关心局部数据,缓存好的汇总表能极大提高查询速度。
一次查大量数据,只能在后台定时任务里跑,不能由前端触发查询,否则任何数据库都无法满足。数据量量一大,即使 nodejs 直接读文件解析,不经过 db ,也会消耗很大资源。 |
21
kivmi 2 天前
从大数据处理基本都是 map-reduce ,所以,这么直接查询原始数据,总感觉有些不妥
|
22
iamtuzi3333 OP @nivalxer 我是每个传感器一个表,返回的文档长度不超过 16M 吗,有更好的方案可以分享一下。
@hd10180 他格式没有这么多,就是固定的 data 数组,要么 50,100,200 ,是根据采样率来定的。传感器也没有 uuid 全靠自己编。 @yyt6801 data 数组就是 50 或者 100 或者 200 个浮点数,每秒的数据都是这样。 @sagaxu 是的,我现在只统计了每秒的最大值,最小值,平均值,读取起来还不算太费劲。正常来说我们只关注十分钟这个节点,还有每分钟数据,这个都还算好用处理。文件确实,主要是读取文件比较麻烦,文件目录不固定,没有很好的索引方式。 @kivmi 是的,但是我们的数据也不算大,就是多,频繁,每秒都有,直接查询原始数据出来也是为了做进一步处理,比如取出每一分钟的最大值,最小值,均值,方差这一些。 |
23
nivalxer 2 天前
我们这边行业比较特殊,对接 PLC 走场站这块,虽然 PLC 站控那边数据是实时的,我们采集远传还是以间隔来走的,所以数据量不会太多,在 10 秒频率下,按天走也不会超过 16M 。这个 16M 是输出文档大小,如果采用分页查询等,输出文档不超过 16M 也没啥问题。
数据库我们暂时还是 mongodb 还没改,计划后面改,还没测试其他方案。 我们行业场景,其实客户不会关注每秒的数据情况,所以大部分时间客户查的小时表(每小时一条取样)和统计表(小时、日、月)这两种,压力就还好。少量在出报警、统计到处等场景才会查完整历史数据。 可以按客户场景来处理。如果客户有每条数据必须存和频繁的查询需求,在不过多改动现有技术架构情况下,可能看看其他数据库比较合适。 |
24
fishman231 2 天前
MongoDB 也是有时序集合,可以使用 TTL 索引自动删除过期文件.另外时序集合可压缩数据,这样是否可以所有数据都存数据库呢
|
25
pangzipp 2 天前
mongodb 本身有数据压缩
你能够实现 3 天以前数据读本地文件文件, 那也可以在 mongodb 里分表。 可以评估下计划投入的资源,成本多少? 用自己熟悉的技术栈 |
26
iamtuzi3333 OP @nivalxer 挺好,后者历史数据我们很像,不过我就是还有一个实时数据的波形展示。
@fishman231 我查询看看。 @pangzipp 目前还没有实现三天以前读取本地文件,就是想这么做,看到一个方案就是只存储最近几天的数据,然后历史数据都存储到文件,查询历史数据通过读文件的形式去完成。MongoDB 分表我还不熟悉;技术栈都是啥好用简单方便就上啥了。 |