这个项目我觉得有三个亮点
数据入库量比较大,我们做了多次优化,能够一个小时内将百万数据全部入库,tps实测达到2000左右
由于我们处理的数据量非常庞大,数据存储和管理成为了一大挑战。我们的数据库架构经过精心设计,以支持海量数据的高效存储和管理。
数据分析模块,需要查询某一区域的历史沉降信息去做对比,我们对数据库字段进行优化,添加字段来提升效率
你们是如何优化这个数据接口,支持到tps2000的,把数据存储和管理做的比较好。
随着数据量的不断增加,我们的数据处理需求也越来越复杂。最初,我们的数据仅限于北京某个区域,每天晚上收集数据并存储在MySQL中,第二天早晨9点前处理结果并返回给领导。然而,随着数据覆盖北京全域,数据量大幅增长,导致接口负载加重。
最初我们仅需将数据上传到数据库,但随着数据量的激增,MySQL的查询性能逐渐下降。为了解决这一问题,我们引入了Kafaka进行削峰,缓解了部分压力。然而,随着索引和数据量继续增加,MySQL的查询速度依然无法满足需求。我们尝试按月份水平分表,但Mysql单机性能仍然是瓶颈。
为什么选择kafka
首先我们对比了rabbitmq rocketmq kafka,ActiveMQ
首先kafka在处理百万级数据上表现比较好,性能不错,第二个对数我们的业务来说,数据保证其实不是那么重要,rocketmq 和rabbitmq对数据保证更友好,开发和部署kafka也比较简单, 社区生态kafka也比较庞大。所以我们选择了kafka
因此,我们考虑使用数据库进行改进。我们对比了MyCat和MongoDB。MyCat通过读写分离提高并发性能,但在高并发情况下,MyCat本身可能成为瓶颈,因为所有数据都要进过mycat。最终,我们选择了MongoDB,因为它本身就是替代传统关系型数据库的存在,支持高并发写入。
我们用kafka削峰把数据存到mongodb,之后采用异步把消息转发到另一个topic,然后采用多路复用的思想,接受多条消息之后,批处理到mysql中,减少了mysql的io操作
后期,为了解决大量过期数据的问题,我们可以考虑引入大数据,将过期数据存储在HBase中,实现冷热数据分离,从而进一步优化数据存储和查询性能。但我们暂时还没做,因为大家都是java,还没有考虑大数据技术,所以我们后期可以考虑数据库分冷热表。
kafka 出现临时堆积 怎么处理
我们在项目中并没有遇到Kafka消息堆积的问题,主要原因有以下几点:
- 我们的数据是按照时间来存储的,每条消息在生产后会存储8小时,8小时后自动删除。因此,Kafka中的数据能够及时清理,避免堆积。
- 我们的Kafka机器配置良好,能够容纳大量数据,处理能力充足。
尽管如此,我们也了解并掌握了一些应对消息队列中间件堆积问题的处理方式:
- 快速扩容:在消息堆积时,迅速增加Kafka集群的节点,提升集群的处理能力。
- 消息转发:将堆积的消息转发到其他的Topic,进行分流处理,缓解单一Topic的压力。
- 增加消费者:通过增加消费者实例来加快消息消费速度,从而减轻消息堆积的现象。
在我们的项目中,目标是快速处理数据而不是让数据堆积。为了实现这一目标,我们选择了分布式数据库来提高数据处理速度和效率。MySQL在单机性能上的限制促使我们转向了MongoDB,这种分布式数据库支持高并发写入和查询,能够更好地满足我们日益增长的数据处理需求。
那么多数据,数据库怎么存
我们在初期规划的时候,考虑到这么多数据了,所以按照实际的场景去测试,一张表存多少数据查询效率不受影响,我们查下来差不多一个月的数据,也就是一亿左右,因为我们做联合索引的,单条数据的大小不是特别大,所以查询效率也ok。
分表之后数据是如何查询的
我们计算前的数据是分表查询的,都是有日期的,有了日期我们就可以知道它落在那一个表上,至于计算结果,这些数据量不是很大,我们是没有分表的。
告警系统是怎么做的呢
这个告警系统大致的流程是我们有一个沉降数据的阈值,比如单日阈值,单月阈值,超过这个范围,我们就会触发报警,我们就会通过短信通知区域的负责人。但取到数据以后,他们好像使用的是引擎规则,还能动态定义,这块我没怎么了解。
kafaka消息丢失的情况是如何考虑的
我们的数据是设备数据,是可以允许丢失的,并且kafaka数据会丢这个情况,我们也在网上调研过,基于各种各样的配置可能确实存在丢的情况,但是我们不是业务信息,我们是日志信息所以可丢,但是我们也尽量做了ack,来保证消息不丢。
生产者和消费者如何保证消息不丢失
生产者 我们设置了 ack确认为all,然后重试次数为3次。
消费者 数据批量处理, 手动提交偏移量,日志记录(记录错误信息到日志表),数据核对通过雪花算法加入id
然后我们三台机器,10个消费者,10个生产者,10个分区,一个消费者对应一个分区提交ack,速度很快。
写入mongodb的数据一定保证可以写入到mysql吗
消费kafaka之后,我们会优先保证写入到mongodb,随后转发到另一个kfaka的topic中,因为我们的统计数据都是从mongodb查询的,所以后期mysql数据库消费快慢无关只做存档,哪怕数据丢了也不大,业务特性是决定我们的数据是可以丢失的,三天以后的数据,我们也会定时删除mongodb。
但其实我们也做了数据一致性检查,我们通过插入数据之前通过雪花算法生成标识,然后我们在数据插入后,我们可以通过获取id来对比,消息发送失败数据的id会重新写入消息队列,进行消费。
你的数据是如何保证写入到mongodb的
Kafka进行削峰:利用Kafka作为消息队列,将数据流进行削峰处理,能够缓解突发高并发写入压力,平滑数据写入过程。
Kafka配置:
- ACK设置为ALL:配置Kafka的生产者确认机制为
all
,确保消息在所有副本都写入成功后才确认,提高数据写入的可靠性。 - 重试机制:配置重试次数为3次,可以在网络抖动或暂时性故障情况下重试,进一步提高消息写入的可靠性。
MongoDB单节点处理能力:根据你的调研,MongoDB单节点可以处理300万条数据的写入,因此在现阶段不需要进行分片。MongoDB本身具有较高的写入性能,特别是在配置合理的情况下。
数据校对
然后我们还有就是消息在入库的时候,我们使用的是雪花算法进行唯一标识,如果有失败的消息,我们最后有一个数据一致性的检验,通过雪花id获取到消费失败的消息,然后重新入队列。
- Post title:地质监测项目
- Post author:秋水
- Create time:2024-08-04 01:35:35
- Post link:tai769.github.io2024/08/04/地质监测项目/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.