简介

在使用 Java 对数据库进行连接时,都会获取到一个 cursor ,cursor 实际指到的是我们查询数据库的query,而并不是 query 查询到的数据集。

此次在使用 mongo 的 cursor 的过程中,对线上数据库产生了很大压力,在这里对此次的优化过程进行记录。

场景

数据源:Mongo 数据库 4台服务器 4000+表 总共3亿+数据量

背景介绍:即将建立大数据平台,需要将数据源的数据导入到 hbase 中,分为历史数据导入和实时 opLog 数据导入两部分

方案:

  1. 多线程历史数据导入
  2. 多线程实时数据导入

问题描述:

  1. 导入的数据占据资源

    1. 硬盘资源 计算需要占用的硬盘资源,事先确认硬盘资源是否充足
    2. CPU 确认运行脚本的服务器处于半空闲状态
    3. 内存 运行jar包时的脚本配置内存即可
  2. 对线上数据库的连接没有释放,导致线上数据库压力
    1. 历史数据导入时,每个线程都会新建连接,之后关闭 #可能没有关闭
    2. 实时数据导入时,轮询产生连接,但是关闭时间较长,导致的连接数增长 #关闭时长较长

解决方法:

  1. 历史数据导入时的每个线程所建立的连接,修改逻辑,使其一定被关闭
  2. 实时数据导入时的每个线程的读取 opLog 的 cursor ,使其保持活性
  3. 创建连接池,确保连接数在一定时间内

知识点

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的更多相关文章

  1. 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./ ...

  2. 一次对MKMapView的性能优化

    一次对MKMapView的性能优化 前言 最近做的项目主要是LBS这块 主打成员定位功能 我们的UI设计是这样的 乍一看上去是挺好挺美观的 不同的人会显示不同的头像 可是当人扎堆的时候 问题就来了 当 ...

  3. 前端MVC学习总结(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...

  4. 前端MVC学习笔记(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...

  5. Golang 连接 MongoDB使用连接池

    可以免费试用 MongoDB ,500MB 平时做测试没有问题啦,连接数据库可能因为网络有点慢,但是我们是测试啊,不在乎这点吧~ 这是怎么申请试用版的博客,感谢这位大佬.注册好用起来很方便~ 传送门 ...

  6. NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    目录 一.Bootstrap 1.1.添加引用 1.2.在页面中使用BootStrap 1.3.可视化布局 二.使用MongoDB创建数据库 2.1.启动MongoDB数据库 2.2.启动数据库GUI ...

  7. 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 ...

  8. 14.Iterate a Cursor in the mongo Shell-官方文档摘录

    1 迭代游标 } ); while (myCursor.hasNext()) { print(tojson(myCursor.next())); } } ); myCursor.forEach(pri ...

  9. mongo大数据量更新服务端超时解决: Cursor not found, cursor id: 82792803897

    mongodb pymongo.errors.CursorNotFound: Cursor not found, cursor id: 82792803897 默认 mongo server维护连接的 ...

随机推荐

  1. IOS订阅优惠-PHP生成ECDSA算法签名

    <?php use Ramsey\Uuid\Uuid; class ItunesSignatureGenerator { private $appBundleID = 'www.u17.com' ...

  2. 面试题1-十进制数转化为十六进制数,不使用hex方法

    问题: 给定一个整数,写一个算法将它转换为16进制,对于负数,可以使用two’s complement方法 def tohex(num): """十进制数转十六进制数&q ...

  3. python PEP8常用规范(看完你会感谢我的!)

    完整的规范移步传送门 pep8规范 官方文档:[https://www.python.org/dev/peps/pep-0008/](https://www.python.org/dev/peps/p ...

  4. solr学习笔记-导入mysql数据

    操作系统:LINUX CENTOS 6.7 solr安装目录:/usr/local/solr-6.1.0 1.准备工作: 1.1.创建数据表: CREATE TABLE `mytable` ( `id ...

  5. 刚接触SkyLine的一点小收获与感触

    因为刚接触Skyline不到一个星期,也怕把学习到的忘记掉,所以写一点学习到的一些皮毛的东西,赶紧记录一下,怕回头忘记 1.网上关于web端的开发非常多,也有很多牛人分享自己的经验,所以学习起来也相对 ...

  6. 学会这 2 点,轻松看懂 MySQL 慢查询日志

    MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1)通用查询日志:记录建立的客户端连接和执行的语句. 2)慢查 ...

  7. Windows7/win10系统安装JDK的环境变量设置javac不是内部命令或外部命令

    ---恢复内容开始--- Windows7/win10系统安装JDK的环境变量设置 Windows7 X64安装“jdk-6u26-windows-x64.exe”后,按照网上的环境变量设置方法设置了 ...

  8. python time,calendar,datetime

    time sleep:休眠指定的秒数(可以是小数) localtime:将一个时间戳转换为time.struct_time类型的对象(类似于元组) # 将一个时间戳转换为一个类似于元组的对象,不指定时 ...

  9. NLP 基于kashgari和BERT实现中文命名实体识别(NER)

    准备工作,先准备 python 环境,下载 BERT 语言模型 Python 3.6 环境 需要安装kashgari Backend pypi version desc TensorFlow 2.x ...

  10. VSCode配合chrome浏览器调试cocos2d js项目

    1.准备阶段 具备调试功能的VSCode(我的是在win10上,版本是1.17.1) 在VSCode里下载安装Debugger for Chrome扩展插件. 2.具体操作 创建一个cocosjs工程 ...