最近需要实时采集一些数据,还要把这些数据存储起来,存储个半年再删掉;留下最近半年的数据,用来观测仪器的运行状况是否一切正常,不正常时要根据仪器收集到的数据对设施进行调整。
于是便想着把这些数据存储到Redis或MongoDB里,这两款数据库都是NoSql数据库,相比较于关系型数据MySql在某些场景有一定的优势,比如,这两款数据库都可以设置失效时间,到了半年自动删除,不用人工干预。
这个需求有几个特点:
第一,每隔五秒就会有大批量数据产生,进行插入操作;
第二,不需要、不涉及修改;
第三,数据存储有期限,过了半年,这些收集到的数据就没有用了,可以删掉以节约存储空间;
第四,查询的时候需要看某一个测量值的变化曲线图,还需要调整时间的间隔,采集的时候五秒采集一次,可能需要观察间隔一分钟的数据曲线图。
接下来算了一下数据量,每5秒钟收集一条数据,一分钟收集12条,一个小时60分钟,一天12个小时,半年180天,大约5000个这样的测量仪,半年存储的数据量为5000 * 12 * 60 * 12 * 180 = 77 7600 0000,半年下来可以积攒大约78亿条数据。每条数据的数据长度虽不算长,只有七八个以下的字段,但是数据量在那里呢。
Redis有五种数据类型,不同的数据类型存储量会有差异:
Strings类型:一个String类型的value最大可以存储512M大小的数据;
Lists类型:list的元素个数最多为2^32-1个,也就是42 9496 7295个;
Sets类型:set元素个数最多为2^32-1个,也就是42 9496 7295个;
Hashes类型:键值对个数最多为2^32-1个,也就是42 9496 7295个;
Sorted sets类型:跟Sets类型相似。
Redis默认有六个数据库,从0-5,每个数据库单例能处理key:2.5亿个,一个key或是value大小最大是512M;Redis性能还是极高的,读的速度是110000次/s,写的速度是81000次/s 。
Redis相关参考文档:
https://www.php.cn/redis/redis-java.html
https://www.runoob.com/redis/redis-tutorial.html
https://redis.io/
按照目前的情形,78亿条数据放在一个Redis里面,忽略每条数据的大小,单看个数,放在哪个数据类型里,都放不下呀。话又说回来,如果内存放不下了,Redis会转存到硬盘上。可是,要对每条数据设置超时时间,这样就只能存储在String类型里。盘算下来,Redis还是不合适呀。会不会还有更合适的方案呢?
那就看看MongoDB吧,对MongoDB有些心理阴影,从网上零零碎碎的资料得知,如果数据多了,在查询时,MongoDB会越来越吃内存,需要不断地扩充或优化,卡死的时候还需要重启,服务器是想重启就能重启的吗?当然,这也是别人的经验,自己并未测试过。
关于MongoDB的文章参考:
https://www.cnblogs.com/daofaziran/p/11013469.html
https://www.runoob.com/mongodb/mongodb-tutorial.html
https://www.mongodb.org.cn/
无意中搜到了下面的一段对话,使用场景很相似呀。
上图中的仪器比我的多多了,数据量也庞大很多,那么时序数据库又是个什么玩意?
什么是时序数据库?
时序数据库能做些什么?
这篇文章很长,上面有概念,中间有实例,业务场景也分析得很到位,时序数据库有哪些,性能如何,也列了个全面。
资料看完了,试着把其中的概念用自己的话在理一理,以便加深印象。
实时序列数据(TimeSeries Data),简称时序数据,是按照时间顺序记录系统、设备状态变化的数据被称为实时序列数据。
时序数据有一个典型的特点:
产生频率快,每一个监测点一秒钟内就可产生多条数据;
严重依赖于采集时间,每一条数据均要求对应唯一的时间;
测点多、信息量大,常规的实时监测系统均有成千上万的监测点,监测点每秒钟都产生数据,每天产生几十GB的数据量;
时序数据库(Time Series DataBase),英文简称TSDB,全称时间序列数据库,针对时序数据的应用场景而生,是存储和管理时间序列数据的专业化数据库,广泛应用于物联网设备监控和互联网业务监控场景。
时序数据库相关的基本概念:
度量(metric):监测数据的具体指标,相当于关系型数据库中的表table,比如:温度、湿度、电压、风力等等具体的测量指标。
域(field):度量下数据的子类别,随着时间戳的变化而变化的数据;一个度量可以有多个域;比如风力,还可以分为风向和风速。
标签(tag):被监测的具体对象,可以用来存放被检测设备的唯一标识;标签可用来做主键,也可以是几个标签组成的联合主键;一个标签由一个标签键(TagKey)和一个对应的标签值(TagValue)组成。
度量值(value):度量对应的数值,被检测对象收集到的数据,具体的温度、湿度数字。
时间戳(Timestamp):数据(度量值)产生的时间点,按照采集的频率生成,可以精确到纳秒级ns,即long型19位。
数据点(Data Point):针对监测对象的某项指标(由度量和标签定义),按特定时间间隔(连续的时间戳)采集的每个度量值就是一个数据点;
时间序列(Time Series):1个度量 + 1个域(可选) + n个标签(n>=1)定义了一个时间序列。主要是针对某个监测对象的某项指标(由度量和标签定义)的描述。某个时间序列上产生的数据值的增加,不会导致时间序列的增加。
时间精度:时间线数据的写入时间精度——纳秒、毫秒、秒、分钟、小时或者其他稳定时间频度;
数据组(Data Group):可以按标签将这些数据分成不同的数据组;
聚合(Aggregation):可以对一段时间内的数据点做聚合,如每10分钟的和值、平均值、最大值、最小值等;
最后总结
首次接触到时序数据库,每一个概念要先理理清楚,多理解几次,毕竟和传统的关系型数据库MySql,无论在设计上,还是在使用上,都有很大的差别,和Redis、MongoDB也不一样;初次使用,在做设计时,思维上要有一个转变,才能做好这个设计。
网友评论