本文将为您提供关于如何在Mongoskin中使用无序批量插入?的详细介绍,我们还将为您解释mongo批量写入的相关知识,同时,我们还将为您提供关于Django+MongoDB批量插入数据、java–如
本文将为您提供关于如何在Mongoskin中使用无序批量插入?的详细介绍,我们还将为您解释mongo批量写入的相关知识,同时,我们还将为您提供关于Django+MongoDB批量插入数据、java – 如何在hibernate中启用批量插入?、javascript – Node.JS Mongo数据库驱动程序没有拆分批量插入?、MongoDB 批量插入和循环插入性能测试的实用信息。
本文目录一览:- 如何在Mongoskin中使用无序批量插入?(mongo批量写入)
- Django+MongoDB批量插入数据
- java – 如何在hibernate中启用批量插入?
- javascript – Node.JS Mongo数据库驱动程序没有拆分批量插入?
- MongoDB 批量插入和循环插入性能测试
如何在Mongoskin中使用无序批量插入?(mongo批量写入)
我在使用Mongoskin在Node上执行批量插入(MongoDB 2.6+)时遇到麻烦。
var dbURI = urigoeshere;var db = mongo.db(dbURI, {safe:true});var bulk = db.collection(''collection'').initializeUnorderedBulkOp();for (var i = 0; i < 200000; i++) { bulk.insert({number: i}, function() { console.log(''bulk inserting: '', i); });}bulk.execute(function(err, result) { res.json(''send response statement'');});
上面的代码给出以下警告/错误:
(node) warning: possible EventEmitter memory leak detected. 51 listeners added. Use emitter.setMaxListeners() to increase limit.TypeError: Object #<SkinClass> has no method ''execute''(node) warning: possible EventEmitter memory leak detected. 51 listeners added. Use emitter.setMaxListeners() to increase limit.TypeError: Object #<SkinClass> has no method ''execute''
是否可以使用Mongoskin执行无序批量操作?如果是这样,我在做什么错?
答案1
小编典典您可以执行此操作,但是您需要更改调用约定才能执行此操作,因为只有“回调”形式实际上会返回.initializeUnorderedBulkOp()
可以从其调用方法的集合对象。您认为此用法的方式也存在一些差异:
var dbURI = urigoeshere;var db = mongo.db(dbURI, {safe:true});db.collection(''collection'',function(err,collection) { var bulk = collection.initializeUnorderedBulkOp(); count = 0; for (var i = 0; i < 200000; i++) { bulk.insert({number: i}); count++; if ( count % 1000 == 0 ) bulk.execute(function(err,result) { // maybe do something with results bulk = collection.initializeUnorderedBulkOp(); // reset after execute }); }); // If your loop was not a round divisor of 1000 if ( count % 1000 != 0 ) bulk.execute(function(err,result) { // maybe do something here });});
因此,实际的“批量”方法本身不需要回调并且可以完全按照文档中的说明工作。该exeception是.execute()
其实际发送的语句到服务器。
尽管驱动程序会为您解决一些问题,但在调用execute之前先排队太多操作可能不是一个好主意。这基本上是在内存中建立的,尽管驱动程序一次只能发送1000个批次(这是服务器的限制,并且整个批次都在16MB以下),但您可能希望在此处进行更多控制,至少限制内存使用。
这就是所示模数测试的重点,但是如果对构建操作的内存和可能非常大的响应对象来说不成问题,那么您可以继续排队操作并调用.execute()
一次。
“响应”的格式与BulkWriteResult文档中给出的格式相同。
Django+MongoDB批量插入数据
在百万级和千万级数据级别进行插入,pymongo的insert_many()方法有着很强的优势。原因是每次使用insert_one()方法进行插入数据,都是要对数据库服务器进行一次访问,而这样的访问是基于TCP连接的,每次在发送请求的时候服务器端都需要对TCP报文进行解析。而使用insert_many(),可以一次给服务器发送大量的数据,只需要一次的TCP报文解析,既可以插入大量数据,避免了大量的报文解析工作。这样一来,数据插入的效率就会大大提升。所以,为了提升效率,笔者建议在十万数据级别以上使用insert_many()方法。
下面是我通过使用pymongo原生方法和框架中的经常使用的Mongoengine进行的性能测试。
一、使用Mongoengine
Mongoengine是基于面向对象的,在构建集合的时候非常方便,就直接写一个类。而pymongo是继承于MongoDB的文档类型的,所以在框架中使用会相对没有那么方便。但是Mongoengine目前来讲还有许多还没有完善的地方。个人觉得,还是根据实际的需求来选择不同的引擎。
插入数据方面,Mongoengine在0.15版本之前只有save()方法,在0.15版本之后添加了insert_one()和inset_many()方法,具体可以看官方文档:。
但是由于Django官方没有将MongoDB列为建议使用的数据库,所以不支持0.9之后的版本。
代码:
beda947bf607dfddac67f9.jpg" alt="" width="368" height="88">
插入一千条数据
插入方法:使用save()保存数据
耗时:大概2秒钟
插入10万条数据
插入方法:使用save()
耗时:两分多钟
二、使用pymongo
(1)测试1:插入一百万数据
插入方法:insert_many()
耗时:28秒
代码:
耗时时间:
插入结果:
(2)测试2:在一百万条数据基础上增加十万数据
插入方法:insert_one()
耗时:1分钟29秒
代码:
耗时时间:
插入结果:
通过上面的测试,很明显的看到,无论是使用Mongoengine的save()方法,还是使用pymongo的insert_one()方法,在大数据量的插入时都会耗费大量的时间,在百万级别的数据就已经需要花费5-6个小时的时间了,显然,这样的效率是很低的。更别说千万级别的数据了。
而使用pymongo的insert_many()方法,在插入百万条数据只是花费了28秒,速度好像快得有点难以想象是吧?按照这样的推算,千万级别数据的数据也大概花费不到5分钟就可以完成了。
那么为什么pymongo的原生方法insert_many()有这么高的效率呢?如何能更进一步提高效率呢?通过阅读源码和分析参数,来了解一下。
insert_many() 定义源码:
官方对参数的解析:
参数:
documents就是我们需要插入的数据文档,也就是上文的articles
下面重点讲ordered和bypass_document_validaion
1. ordered
默认情况下是True,即按顺序来插入多条数据,如果发生错误,就会终止后面的插入。如果设置为False,文档将以任意的顺序将数据插入到服务器中,并且是并行进行的,客户端会尽力将所有的数据都插入到服务器中。所以,设置为False会在数据的插入效率有很大的提升,但也要付出一点数据安全性的代价。
2. bypass_document_validation
默认情况为False。如果为True,那么允许在写入发生错误的时候推出文档级别的验证,不影响后面的数据插入。
设置合适的参数值,可以更好地为海量数据的插入提供更好的插入环境。
笔者:
欢迎评论!希望本人的文章对阅读者有帮助,在写作过程中难免有疏漏,希望读者在发现错误的地方及时向我提出,我会尽快修改自己的技术疏漏。我也会定时写一些自己学习中的收获和项目中的经验。希望前行的路上,有更多乐于分享的人一起作伴。
java – 如何在hibernate中启用批量插入?
<property name="jdbc.batch_size">50</property>
我得到以下输出:
[...] cfg.SettingsFactory INFO - JDBC batch updates for versioned data: disabled [...] cfg.SettingsFactory INFO - Order sql inserts for batching: disabled
然后这个:
[...] jdbc.AbstractBatcher DEBUG - Executing batch size: 1
从不超过批量:1基本.
我错过了一个设置?
解决方法
<property name="hibernate.jdbc.batch_size">30</property> <property name="hibernate.order_inserts">true</property> <property name="hibernate.order_updates">true</property> <property name="hibernate.jdbc.batch_versioned_data">true</property>
如果您可以使用SEQUENCE<那么你不应该使用IDENTITY发电机,因为it disables batch fetching.
如果您不能使用SEQUENCE(例如MysqL),请尝试使用单独的机制来启用批量插入(例如jOOQ),而不是使用不会缩放并具有高性能损失的TABLE生成器.
javascript – Node.JS Mongo数据库驱动程序没有拆分批量插入?
var MongoClient = require('mongodb').MongoClient; MongoClient.connect('mongodb://localhost/testdb',function(err,db) { var collection = db.collection('testcollection'); var docs = []; var doc = { str: 'Lorem ipsum dolor sit amet,consectetur adipiscing elit. Etiam sit amet urna consequat quam pharetra sagittis vitae at nulla. Suspendisse non felis sollicitudin,condimentum urna eu,congue massa. Nam arcu dui,soDales eget auctor nec,ullamcorper in turpis. Praesent sit amet purus mi. Mauris egestas sapien magna,a mattis tellus luctus et. Suspendisse potenti. Nam posuere neque at vulputate ornare. Nunc mollis lorem est,at porttitor augue soDales sed. Ut dui sapien,fermentum eu laoreet sed,soDales et augue. Aliquam erat volutpat.' }; for (var i = 0; i < 100000; i++) { docs[i] = doc; } collection.insert(docs,function(err) { throw err; }); });
但是,我收到以下错误:
/var/node/testproject/node_modules/mongodb/lib/mongodb/connection/base.js:242 throw message; ^ Error: Document exceeds maximum allowed bson size of 16777216 bytes at InsertCommand.toBinary (/var/node/testproject/node_modules/mongodb/lib/mongodb/commands/insert_command.js:86:11) at Connection.write (/var/node/testproject/node_modules/mongodb/lib/mongodb/connection/connection.js:230:42) at __executeInsertCommand (/var/node/testproject/node_modules/mongodb/lib/mongodb/db.js:1857:14) at Db._executeInsertCommand (/var/node/testproject/node_modules/mongodb/lib/mongodb/db.js:1930:5) at insertAll (/var/node/testproject/node_modules/mongodb/lib/mongodb/collection/core.js:205:13) at Collection.insert (/var/node/testproject/node_modules/mongodb/lib/mongodb/collection/core.js:35:3) at /var/node/testproject/dbtest.js:15:16 at /var/node/testproject/node_modules/mongodb/lib/mongodb/mongo_client.js:431:11 at process._tickCallback (node.js:664:11)
由于单个文档明显小于16 MB并且给定堆栈跟踪,因此驱动程序似乎不会自动拆分命令.我如何解决这个问题,最好不要自己编码?
解决方法
您似乎期望这是每个文档的限制,但您没想到的是您的整个请求实际上是BSON文档.
这是mongodb的有线协议的一部分,因此批量请求受到相同的限制,因为您的整个提交的大小不能超过16MB.
如果您查看2.6 documentation中的插入和更新操作的runcommand页面,则会明确说明.
所以从本质上讲,这不是一个错误.您需要分解大批量请求,并将它们保持在16MB大小之下.
MongoDB 批量插入和循环插入性能测试
一万条数据批量插入和循环插入
- 循环插入
var startTime = (new Date()).getTime()
var db = connect(''log'')
for(var i = 0;i<10000;i++){
db.test.insert({num:i})
}
var runTime = (new Date()).getTime()-startTime
print(''insert time is ''+ runTime)
// 第一次 2699ms
// 第二次 2743ms
// 第三次 2699ms
- 批量插入
var startTime = (new Date()).getTime()
var db = connect(''log'')
var tempArr = []
for(var i = 0;i<10000;i++){
tempArr.push({num:i})
}
db.test.insert(tempArr)
var runTime = (new Date()).getTime()-startTime
print(''insert time is ''+ runTime)
// 第一次 114ms
// 第二次 108ms
// 第三次 112ms
总结: 大批量数据插入数据库的时候,批量插入速度是循环插入20倍还有多
我们今天的关于如何在Mongoskin中使用无序批量插入?和mongo批量写入的分享已经告一段落,感谢您的关注,如果您想了解更多关于Django+MongoDB批量插入数据、java – 如何在hibernate中启用批量插入?、javascript – Node.JS Mongo数据库驱动程序没有拆分批量插入?、MongoDB 批量插入和循环插入性能测试的相关信息,请在本站查询。
本文标签: