随笔——一次相对独立的大数据处理历程

4 篇文章 0 订阅
3 篇文章 0 订阅

一次相对独立的大数据处理历程

背景

某个业务需求要求遍历一个数据量在千万级的大表,这个大表存储了一类主体的部分信息;但本次需求还要处理一些超出主体信息外的内容,这要求我还要去根据主体的编号去另外的表或者使用ES查询一些信息;关联表数据及ES中的数据量级在百万左右。
本次业务的主要限制可能在于:

  1. 主体信息表量级很大,不可能做关联查询或者一次性拉取所有数据;且对于大表的读取,如果不能尽快结束,涉及到数据库数据版本控制问题等,可能遇到查询性能越来越低的问题;
  2. 关联表的相关字段可能没有建立索引;
  3. ES表中的数据可能面临可靠性问题(涉及具体业务不细说了);
  4. 该服务的执行可能需求大量服务器资源,并可能执行较长时间;
  5. 服务需要部署多个实例,但只需要一个实例运行该任务;

技术思路

解决思路

  1. 对于大表的读取首先应该采取流式读取,这里主要与sql查询的fetchsize有关,控制每次去拉取的数据条数,对大表进行分段处理;
  2. 此外,必须要确保对大表的处理要在尽可能短的时间内完成;这种情形下,我们应该尽可能减少在处理大表的过程中进行其他的耗时操作,如数据库查询等;(这也要求我们必须对任务的过程进行拆分,对数据进行分段处理)
  3. 涉及到任务的分段处理,则也要求必须对数据处理的中间结果与状态进行处理;这边主要分为使用内存对数据进行缓存以及使用本地存储暂存结果。使用内存缓存虽然简单快速,但是可能造成服务器资源紧张,这对我们可怜的服务器是不友好的,因此这里主要采用本地存储中间结果,采取的是使用fastjson将java对象转换为json字符串存储为一行,在读取的时候再反转为java对象即可。
    保证大表能顺利进行处理后,其他问题的处理就是细节上的问题了.
  4. 关联表是否建立索引主要是通过其他工具执行SQL查询,根据其执行时间量级来进行判断;至于对ES查询的效率,由于相关ES建立时其ID就是使用的相关主体的ID,这里我们直接使用idQuery应该就能确保其查询速度。
  5. 事实上,在我们采取先使用本地存储(BufferedWriter)进行数据临时落盘(落盘前已根据相关需求对数据进行了初步的处理与筛选);而后再使用本地存储(BufferedReader)进行数据流式读取(按行处理,可能要进行数据库查询或ES查询)之后,基本上就能缓解内存等方面的压力了。如果在初步处理中能筛选较多数据的话更能降低后面阶段的工作量与压力。
  6. 对于数据可靠性问题,这个没办法,只能在每次取数据后对数据格式等进行校验,遇到不该为空或错误的数据则应处理
  7. 由于实际环境的部署中该服务是作为某个整体服务的子服务定时运行的(按月),且父服务有多个实例部署,因此还需要将该子服务设置为可根据配置选择某个特定的实例进行运行,这里主要是在yml文件中添加了特定的字段进行配置,并使用@Value注解读取该配置,该配置作为标志位决定是否在本机实例中运行该服务(事实上定时任务仍然会启动,只是会检测该配置,若配置为空或不为特定的值则不调用实际处理任务的程序)

历程

第一阶段,根据需求,将任务的处理分为三个阶段,各个阶段根据内存中的缓存(HashMap)取值处理;
第二阶段,根据组长反馈的问题和提出的优化点进行相应优化(即本随笔中讲的内容);
第三阶段,构建测试环境,使用不同的配置进行测试,查看日志。

结果

根据日志统计,最后本次处理主表数据约八千万条(流式读取数据库),中间缓存数据预计大概在十万条内(单独查询数据库或ES),并最终处理产生了两千条数据,过程总耗时约12分钟,总的来说成果还算喜人吧。
菜鸟又向成长迈进了一步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值