记一次大数据量处理性能调优的过程总结

一、背景介绍

1、系统的架构是spring+mybaties+oracle。
2、系统处理的数据量在五十万到百万级之间,采用了kafka进行分布式处理,主要功能和要优化的模块在数据清算和数据导出。

二、可优化点介绍

1、kafka—分布式订阅-发布消息系统
kafka是一款可靠、可扩展、高性能的消息系统,具体介绍可以看Kafka简介,这篇文章写的很不错。
在本系统主要是利用kafka集群,开辟多个kafka分区(Partition)来实现并行消费而提高性能。
2、阻塞队列的使用
在数据导出模块的消费端,先利用多线程并行分批处理需要导出的数据,同时用单线程去把数据写到文件里。这里面数据的传递用到了阻塞队列里,我用的是效率更高的LinkedBlockingQueue,这个可以看我的另一篇博客Java阻塞队列的学习笔记 文章有介绍为什么LinkedBlockingQueue的效率高一些。这样这个阻塞队列就等于自己实现的一个小的消息系统,生产者生产数据和消费者取数据可以同时进行,提高系统整体的处理性能。
3、oracle的sql语句优化
下面的是我总结的oracle的sql语句常用优化原则:
- 尽量使用表的别名去操作列,提高表的连接效率和避免列名歧义。
- Select避免使用*,因为oracle解析sql语句时会去查询数据字典把'*'转换成列名,这里会消耗一些时间。
- 把sql语句转换成全部大写,如果是小写,oracle解析sql时也会去转成大写的,所以我们可以自己先转成大写的。
- 多表查询时表的顺序,oracle解析表时是按照从右至左的顺序,所以我们应该把数据量小的表放在右边,如果是连接用的中间表,也应该放在最右边。
- where子句的顺序 ,oracle解析where子句时是按照自上而下的顺序,所以我们应该把能够筛选出大量数据的条件放在后面,而连接表的子句应该放在靠近where的位置。
- 尽量不要使用order by,在oracle里,如果order by后面的条件没有加索引的话就会造成全表扫描。
3、代码优化–总结几个我日常发现的小技巧
for循环的使用:
用for(i=0;i<size;i++)的效率会高于foreach方法;for循环里面的条件size不要直接用list.size()放在for循环里面取,先在循环外面取出size,再放到for循环里,不然每循环一次都要去取列表的size。
事务的控制
使用事务的原则是避免长事务和避免乱开事务,很典型的就是我们经常会在service的实现类上加上事务注解,而实际上类的很多方法根本不需要开事务,造成了资源的浪费,我们应该在需要用到事务的方法上去开启事务。
多线程和线程池的运用
利用多线程并行处理是提高性能的关键,而合理的使用线程池也可以减少重复创建线程的损耗,同时异步处理耗时比较长的操作也可以提升用户体验。这里推荐一篇关于要开多大的线程池比较合适的文章.线程池数量设置 这个文章写分析的很好。
尽量减少数据库的连接开销
减少与数据库的交互,使用批量插入或更新的方法,或者增加缓存的使用,减轻数据库的压力,数据库IO非常耗时,特别是在这种百万级数据量的处理上,往往你在数据库连接上优化了一点点时间,到最终的性能却会提高很多。

以上就是我最近在工作中遇到性能优化需求所关注的一些关键点,如果有错误的地方,欢迎指正。

PS:刚开始写博客,才疏学浅,语言组织能力也不行,请各位见谅~~

猜你喜欢

转载自blog.csdn.net/peerless_fu/article/details/80685746