Mongo Cursor
简介
在使用 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):表示此次操作保持的最长时间,即server端保持cursor状态的最长时间,如果超时server端将移除此cursor,即再次通过此cursor遍历数据将会error。
4)sort(Bson bson):根据指定field排序,参与排序的字段最好是索引,如果不是,将会在内存中排序,如果参与排序的数据尺寸大于32M,将会抛出error。1表示正序,-1表示倒叙,比如"age":1表示按照age正序排序。
5)noCursorTimeout(boolean timeout):如果cursor空闲一定时间后(10分钟),server端是否将其移除,默认为false,即server会将空闲10分钟的cursor移除以节约内存。如果为true,则表示server端不需要移除空闲的cursor,而是等待用户手动关闭。无论如何,开发者都需要注意,手动关闭cursor。
6)partial(boolean partial):对于sharding集群,如果一个或者多个shard不可达,是否允许返回部分数据(只从正常的shard中获取数据)。
7)cursorType():指定cursor类型,当cursor遍历完毕后是否关闭cursor,默认是关闭,无论何时都建议手动关闭cursor(不管是否耗尽curosr);当然有些开发场景可能需要保持cursor的活性,遍历到cursor的最后一条后,不关闭cursor,继续等待,此后一段时间内如果有新数据插入到cursor之后,则可以继续遍历,这就是Tailable Cursor,通常对于Capped Collection中使用。目前支持支持3种类型的Cursor:NonTailable、Tailable、TailableAwait。
8)projection(Bson bson):限定返回结果中需要包含的filed或者数组元素。在6)中我们已经看到相关的几个例子。默认情况下,将会返回document的所有字段,1表示包含,0表示不包含。
连接池
Mongo Client本身即是一个连接池,有默认参数,也可以自己设置参数,建议全局使用同一个mongo的client实例。
NOTE: 连接池里的连接数 = ConnectionsPerHost * threadsAllowedToBlockForConnectionMultiplier
参数说明:来自于http://api.mongodb.com/java/3.2/
com.mongodb
Class MongoClientOptions.Builder
参数名 | 默认参数值 | 参数说明 |
---|---|---|
ConnectionsPerHost | 100 | 设置每台主机的最大连接数 |
Description | null | |
RequiredReplicaSetName | null | 设置群集所需的副本集名称 |
ConnectTimeout | 10000 | 设置连接超时 |
HeartbeatConnectTimeout | 20000 | 设置用于群集心跳的连接的连接超时 |
HeartbeatFrequency | 10000 | 设置心跳频率。这是驱动程序尝试确定群集中每个服务器当前状态的频率。默认值为10,000毫秒 |
HeartbeatSocketTimeout | 20000 | 设置用于群集心跳的连接的套接字超时 |
LocalThreshold | 15 | 设置本地阈值 |
MaxConnectionIdleTime | 0 | 设置池连接的最大空闲时间 |
MaxConnectionLifeTime | 0 | 设置池连接的最长生存期 |
MaxWaitTime | 120000 | 设置线程阻塞等待连接的最长时间 |
MinConnectionsPerHost | 0 | 设置每台主机的最小连接数 |
MinHeartbeatFrequency | 500 | 设置最小心跳频率。如果驱动程序必须频繁地重新检查服务器的可用性,它至少会在上次检查后等待这么长时间,以避免浪费精力。默认值为500毫秒 |
ServerSelectionTimeout | 30000 | 以毫秒为单位设置服务器选择超时,这定义了驱动程序在引发异常之前等待服务器选择成功的时间。 值0表示如果没有服务器可用,它将立即超时。负值意味着无限期等待。 |
SocketTimeout | 0 | 设置socket超时 |
threadsAllowedToBlockForConnectionMultiplier | 5 | 设置允许阻塞等待连接的线程数的乘数。 |
socketKeepAlive | 设置是否启用套接字保持活动 | |
sslEnabled | 设置是否使用SSL。将此设置为true也会将SocketFactory设置为sLSocketFactory。GetDefault ( )并将此设置为false会将SocketFactory设置为SocketFactory。GetDefault ( ) | |
sslInvalidHostNameAllowed | 定义是否允许无效主机名。默认为false。在将此设置为真之前要小心,因为这会使应用程序容易受到中间人攻击 | |
readPreference | 设置读取首选项 | |
writeConcern | 设置写入关注点。 | |
readConcern | 设置读取关注点。 | |
codecRegistry | 设置编解码器注册表 请注意,DB和DBCollection的实例不使用注册表,因此无需在注册表中包含DBObject的编解码器。 |
|
addCommandListener | 添加给定的命令侦听器。 | |
socketFactory | 设置socket工厂。 | |
cursorFinalizerEnabled | 设置是否启用游标终结器 | |
alwaysUseMBeans | 设置驱动程序注册的JMX Beans是否应该始终是MBean,而不管VM是Java 6还是更高版本。如果为false,如果虚拟机为Java 6或更高版本,驱动程序将使用MXBeans,如果虚拟机为Java 5,则使用mbean。 | |
dbDecoderFactory | 设置解码器工厂 | |
dbEncoderFactory | 设置编码器工厂 | |
legacyDefaults | 将默认值设置为MongoOptions中的值 |
Mongo Cursor的更多相关文章
- src/github.com/mongodb/mongo-go-driver/mongo/cursor.go 游标的简洁实用
src/github.com/mongodb/mongo-go-driver/mongo/cursor.go // Copyright (C) MongoDB, Inc. 2017-present./ ...
- 一次对MKMapView的性能优化
一次对MKMapView的性能优化 前言 最近做的项目主要是LBS这块 主打成员定位功能 我们的UI设计是这样的 乍一看上去是挺好挺美观的 不同的人会显示不同的头像 可是当人扎堆的时候 问题就来了 当 ...
- 前端MVC学习总结(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例
这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...
- 前端MVC学习笔记(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例
这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...
- Golang 连接 MongoDB使用连接池
可以免费试用 MongoDB ,500MB 平时做测试没有问题啦,连接数据库可能因为网络有点慢,但是我们是测试啊,不在乎这点吧~ 这是怎么申请试用版的博客,感谢这位大佬.注册好用起来很方便~ 传送门 ...
- NodeJS+MongoDB+AngularJS+Bootstrap书店示例
目录 一.Bootstrap 1.1.添加引用 1.2.在页面中使用BootStrap 1.3.可视化布局 二.使用MongoDB创建数据库 2.1.启动MongoDB数据库 2.2.启动数据库GUI ...
- MongoDB - MongoDB CRUD Operations, Query Documents, Iterate a Cursor in the mongo Shell
The db.collection.find() method returns a cursor. To access the documents, you need to iterate the c ...
- 14.Iterate a Cursor in the mongo Shell-官方文档摘录
1 迭代游标 } ); while (myCursor.hasNext()) { print(tojson(myCursor.next())); } } ); myCursor.forEach(pri ...
- mongo大数据量更新服务端超时解决: Cursor not found, cursor id: 82792803897
mongodb pymongo.errors.CursorNotFound: Cursor not found, cursor id: 82792803897 默认 mongo server维护连接的 ...
随机推荐
- redis 学习(5)-- 列表类型
redis 学习(5)-- 列表类型 列表特点 有序.可以重复.左右两边插入弹出 索引相关知识 索引从左往右,从0开始逐个增大 0 1 2 3 4 5 索引从右往左,从-1开始逐个减小 -6 -5 - ...
- webAapi
学习目标: 掌握API和Web API的概念 掌握常见浏览器提供的API的调用方式 能通过Web API开发常见的页面交互功能 能够利用搜索引擎解决问题 typora-copy-images-to: ...
- sql server lower函数
lower()函数 --将大写字符数据转换为小写字符数据 语法:lower(character_expression) --character_expression是指定要进行转换的字符串
- MongoDB v4.0 命令
MongoDB v4.0 命令 官方文档 > 点这里 < 操作系统库 #操作管理员库 use admin #鉴权 db.auth("root","admin& ...
- MySQL存储引擎知多少
MySQL是我们经常使用的数据库处理系统(DBMS),不知小伙伴们有没有注意过其中的“存储引擎”(storage_engine)呢?有时候面试题中也会问道MySQL几种常用的存储引擎的区别.这次就简短 ...
- Visual Studio 2010中的js注释
Visual Studio 2010中的js注释已经很强大了,但怎么才能和调用c#的方法一样容易呢?怎样才能让每个参数都有注释说明呢?底下就是想要的答案. 先上图,如图所示: 其中红色的办法为注释效果 ...
- docker下进去mysql 编写语句
设置密码可使用 docker exec -it mysql01 bash --mysql01:数据库名字 mysql -u root -p ALTER USER 'root'@'%' I ...
- vagrantfile 配置
config.vm.network "forwarded_port", guest: 22, host: 2222, id: "ssh", disabled: ...
- 关于select的取值
这篇博客,主要是记录我我所犯的错误,或者自己的写法不规范导致了错误,大家可以引以引以为鉴. 我要获取select当前的值,在IE9上我可以直接写document.getElementById(&quo ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(19)|多线程]
[易学易懂系列|rustlang语言|零基础|快速入门|(19)|多线程] 实用知识 多线程 我们今天来讲讲Rust中的多线程. 我直接来看看代码: use std::thread; use std: ...