简介
在使用 Java 对数据库进行连接时,都会获取到一个 cursor ,cursor 实际指到的是我们查询数据库的query,而并不是 query 查询到的数据集。
此次在使用 mongo 的 cursor 的过程中,对线上数据库产生了很大压力,在这里对此次的优化过程进行记录。
场景
数据源:Mongo 数据库 4台服务器 4000+表 总共3亿+数据量
背景介绍:即将建立大数据平台,需要将数据源的数据导入到 hbase 中,分为历史数据导入和实时 opLog 数据导入两部分
方案:
- 多线程历史数据导入
- 多线程实时数据导入
问题描述:
- 导入的数据占据资源
- 硬盘资源 计算需要占用的硬盘资源,事先确认硬盘资源是否充足
- CPU 确认运行脚本的服务器处于半空闲状态
- 内存 运行jar包时的脚本配置内存即可
- 对线上数据库的连接没有释放,导致线上数据库压力
- 历史数据导入时,每个线程都会新建连接,之后关闭 #可能没有关闭
- 实时数据导入时,轮询产生连接,但是关闭时间较长,导致的连接数增长 #关闭时长较长
解决方法:
- 历史数据导入时的每个线程所建立的连接,修改逻辑,使其一定被关闭
- 实时数据导入时的每个线程的读取 opLog 的 cursor ,使其保持活性
- 创建连接池,确保连接数在一定时间内
知识点
cursor
cursor的获取:find() 方法返回的是一个 FindIterable 对象,对此对象的控制即可对 cursor 的属性进行控制,根据FindIterable获取一个Cursor 。
1)batchSize(int size):每次网络请求返回的document条数,比如你需要查询500条数据,mongodb不会一次性全部load并返回给client,而是每次返回batchSize条,遍历完之后后再通过网路IO获取直到cursor耗尽。默认情况下,首次批量获取101个document或者1M的数据,此后每次4M,当然我们可以通过此方法来覆盖默认值,如果文档尺寸较小,则建议batchSize可以大一些。
2)skip(int number)、limit(int number):同SQL中的limit字句,即表示在符合匹配规则的结果集中skip一定数量的document,并最终返回limit条数据。可以实现分页查询。
3)maxTime(int time,TimeUnit unit):表示此次操