MongoDB事实:商品硬件上每秒插入80000次以上

在尝试一些时间序列集合时,我需要一个大数据集来检查我们的聚合查询在增加数据负载的情况下不会成为瓶颈。 我们解决了5000万份文档,因为超出此数目我们仍然会考虑分片。

每次事件如下所示:

{"_id" : ObjectId("5298a5a03b3f4220588fe57c"),"created_on" : ISODate("2012-04-22T01:09:53Z"),"value" : 0.1647851116706831
}

当我们想要获取随机值时,我们考虑使用JavaScript或Python生成它们(我们可以在Java中进行尝试,但是我们希望尽可能快地编写它)。 我们不知道哪个会更快,所以我们决定对其进行测试。

我们的第一次尝试是通过MongoDB Shell运行一个JavaScript文件。

看起来是这样的:

var minDate = new Date(2012, 0, 1, 0, 0, 0, 0);
var maxDate = new Date(2013, 0, 1, 0, 0, 0, 0);
var delta = maxDate.getTime() - minDate.getTime();var job_id = arg2;var documentNumber = arg1;
var batchNumber = 5 * 1000;var job_name = 'Job#' + job_id
var start = new Date();var batchDocuments = new Array();
var index = 0;while(index < documentNumber) {var date = new Date(minDate.getTime() + Math.random() * delta);var value = Math.random();var document = {		created_on : date,value : value};batchDocuments[index % batchNumber] = document;if((index + 1) % batchNumber == 0) {db.randomData.insert(batchDocuments);}index++;if(index % 100000 == 0) {	print(job_name + ' inserted ' + index + ' documents.');}
}
print(job_name + ' inserted ' + documentNumber + ' in ' + (new Date() - start)/1000.0 + 's');

这是我们运行它的方式以及所获得的:

mongo random --eval "var arg1=50000000;arg2=1" create_random.js
Job#1 inserted 100000 documents.
Job#1 inserted 200000 documents.
Job#1 inserted 300000 documents.
...
Job#1 inserted 49900000 documents.
Job#1 inserted 50000000 in 566.294s

好吧,这已经超出了我的期望(每秒88293次插入)。

现在轮到Python了。 您将需要安装pymongo才能正确运行它。

import sys
import os
import pymongo
import time
import randomfrom datetime import datetimemin_date = datetime(2012, 1, 1)
max_date = datetime(2013, 1, 1)
delta = (max_date - min_date).total_seconds()job_id = '1'if len(sys.argv) < 2:sys.exit("You must supply the item_number argument")
elif len(sys.argv) > 2:job_id = sys.argv[2]	documents_number = int(sys.argv[1])
batch_number = 5 * 1000;job_name = 'Job#' + job_id
start = datetime.now();# obtain a mongo connection
connection = pymongo.Connection("mongodb://localhost", safe=True)# obtain a handle to the random database
db = connection.random
collection = db.randomDatabatch_documents = [i for i in range(batch_number)];for index in range(documents_number):try:			date = datetime.fromtimestamp(time.mktime(min_date.timetuple()) + int(round(random.random() * delta)))value = random.random()document = {'created_on' : date,	'value' : value,	}batch_documents[index % batch_number] = documentif (index + 1) % batch_number == 0:collection.insert(batch_documents)		index += 1;if index % 100000 == 0:	print job_name, ' inserted ', index, ' documents.'		except:print 'Unexpected error:', sys.exc_info()[0], ', for index ', indexraise
print job_name, ' inserted ', documents_number, ' in ', (datetime.now() - start).total_seconds(), 's'

我们运行它,这是我们这次得到的:

python create_random.py 50000000
Job#1  inserted  100000  documents.
Job#1  inserted  200000  documents.
Job#1  inserted  300000  documents.
...
Job#1  inserted  49900000  documents.
Job#1  inserted  50000000  in  1713.501 s

与JavaScript版本(每秒插入29180次)相比,它要慢一些,但不要气lets。 Python是一种功能齐全的编程语言,因此如何利用我们所有的CPU内核(例如4个内核)并为每个内核启动一个脚本,每个脚本插入总文档数的一小部分(例如12500000)。

import sys
import pymongo
import time
import subprocess
import multiprocessingfrom datetime import datetimecpu_count = multiprocessing.cpu_count()# obtain a mongo connection
connection = pymongo.Connection('mongodb://localhost', safe=True)# obtain a handle to the random database
db = connection.random
collection = db.randomDatatotal_documents_count = 50 * 1000 * 1000;
inserted_documents_count = 0
sleep_seconds = 1
sleep_count = 0for i in range(cpu_count):documents_number = str(total_documents_count/cpu_count)print documents_numbersubprocess.Popen(['python', '../create_random.py', documents_number, str(i)])start = datetime.now();while (inserted_documents_count < total_documents_count) is True:inserted_documents_count = collection.count()if (sleep_count > 0 and sleep_count % 60 == 0):	print 'Inserted ', inserted_documents_count, ' documents.'		if (inserted_documents_count < total_documents_count):sleep_count += 1time.sleep(sleep_seconds)	print 'Inserting ', total_documents_count, ' took ', (datetime.now() - start).total_seconds(), 's'

运行并行执行Python脚本是这样的:

python create_random_parallel.py
Job#3  inserted  100000  documents.
Job#2  inserted  100000  documents.
Job#0  inserted  100000  documents.
Job#1  inserted  100000  documents.
Job#3  inserted  200000  documents.
...
Job#2  inserted  12500000  in  571.819 s
Job#0  inserted  12400000  documents.
Job#3  inserted  10800000  documents.
Job#1  inserted  12400000  documents.
Job#0  inserted  12500000  documents.
Job#0  inserted  12500000  in  577.061 s
Job#3  inserted  10900000  documents.
Job#1  inserted  12500000  documents.
Job#1  inserted  12500000  in  578.427 s
Job#3  inserted  11000000  documents.
...
Job#3  inserted  12500000  in  623.999 s
Inserting  50000000  took  624.655 s

即使仍然比第一次JavaScript导入还要慢,这确实非常好(80044次插入/秒)。 因此,让我们修改最后一个Python脚本,以通过多个MongoDB Shell运行JavaScript。

由于我无法提供所需的参数给mongo命令,也无法提供给主要python脚本启动的子进程,因此我提出了以下替代方案:

for i in range(cpu_count):documents_number = str(total_documents_count/cpu_count)script_name = 'create_random_' + str(i + 1) + '.bat'script_file = open(script_name, 'w')script_file.write('mongo random --eval "var arg1=' + documents_number +';arg2=' + str(i + 1) +'" ../create_random.js');script_file.close()subprocess.Popen(script_name)

我们动态生成shell脚本,然后让python为我们运行它们。

Job#1 inserted 100000 documents.
Job#4 inserted 100000 documents.
Job#3 inserted 100000 documents.
Job#2 inserted 100000 documents.
Job#1 inserted 200000 documents.
...
Job#4 inserted 12500000 in 566.438s
Job#3 inserted 12300000 documents.
Job#2 inserted 10800000 documents.
Job#1 inserted 11600000 documents.
Job#3 inserted 12400000 documents.
Job#1 inserted 11700000 documents.
Job#2 inserted 10900000 documents.
Job#1 inserted 11800000 documents.
Job#3 inserted 12500000 documents.
Job#3 inserted 12500000 in 574.782s
Job#2 inserted 11000000 documents.
Job#1 inserted 11900000 documents.
Job#2 inserted 11100000 documents.
Job#1 inserted 12000000 documents.
Job#2 inserted 11200000 documents.
Job#1 inserted 12100000 documents.
Job#2 inserted 11300000 documents.
Job#1 inserted 12200000 documents.
Job#2 inserted 11400000 documents.
Job#1 inserted 12300000 documents.
Job#2 inserted 11500000 documents.
Job#1 inserted 12400000 documents.
Job#2 inserted 11600000 documents.
Job#1 inserted 12500000 documents.
Job#1 inserted 12500000 in 591.073s
Job#2 inserted 11700000 documents.
...
Job#2 inserted 12500000 in 599.005s
Inserting  50000000  took  599.253 s

这也很快(83437次插入/秒),但仍然无法击败我们的第一次尝试。

结论

我的PC配置与众不同,唯一的优化是我有运行MongoDB的SSD驱动器。

vlad_pc

第一次尝试产生了最佳结果,并且监视CPU资源后,我意识到MongoDB甚至可以在单个Shell控制台中利用所有这些资源。 在所有内核上运行的Python脚本也足够快,并且如果需要,它具有的优势是允许我们将该脚本转换为可完全运行的应用程序。

  • 代码可在GitHub上获得 。

参考: MongoDB事实:我们的JCG合作伙伴 Vlad Mihalcea在Vlad Mihalcea的Blog博客上对商品硬件的插入/每秒80000次以上 。

翻译自: https://www.javacodegeeks.com/2013/12/mongodb-facts-80000-insertssecond-on-commodity-hardware.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scala-jdbc-scalike操作jdbc数据库

1, 引入maven依赖 <!-- 使用 sclaikeJDBC --><dependency><groupId>org.scalikejdbc</groupId><artifactId>scalikejdbc_2.11</artifactId><version>3.3.1</version></dependency><dependency><groupId>org…

day 17python 面对对象之继承

一&#xff1a;什么面向对象的继承&#xff1f; 比较官方的说法就是&#xff1a; 继承&#xff08;英语&#xff1a;inheritance&#xff09;是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B&#xff0c;就把这个A称为“B的子类别”&#xff0c;而把B称…

js 人民币小写金额转换为大写

function smalltoBIG(n) {var fraction [角, 分];var digit [零, 壹, 贰, 叁, 肆, 伍, 陆, 柒, 捌, 玖];var unit [[元, 万, 亿],[, 拾, 佰, 仟]];var head n < 0 ? 欠 : ;n Math.abs(n);var s ;for (var i 0; i < fraction.length; i ) {s (digit[Math.floor…

mybatis源码_Mybatis源码之SqlSession

SqlSession简介Mybatis是一个强大的ORM框架&#xff0c;它通过接口式编程为开发者屏蔽了传统JDBC的诸多不便&#xff0c;以简单的方式提供强大的扩展能力。其中的接口式编程就是指日常使用的Mapper接口&#xff0c;Mybatis借助动态代理实现了sql语句与Mapper的接口的动态绑定&a…

r语言kmodes_聚类分析——k-means算法及R语言实现

我们知道『物以类聚&#xff0c;人以群分』&#xff0c;这里并不是分类问题&#xff0c;而是聚类问题。两者主要区别在于&#xff0c;分类是将一组数据根据不同的类区分&#xff0c;已经知道有哪些类&#xff0c;也就是数据已经有了类的标签。而聚类是一种事先不知道有多少类&a…

VSCode安装jshint插件报错

Mac电脑上使用VSCode安装jshint插件时提示如下错误&#xff1a; Failed to load jshint library. Please install jshint in your workspace folder using npm install jshint or globally using npm install -g jshint and then press Retry. 按照提示&#xff0c;使用np…

按小时分组mysql 补齐_分组记录按小时或按天白天和mysql的

生成单列dates_hours表&#xff0c;该表包含在合理范围内(例如从1900到2200)的所有日期和小时数。 然后从此表执行LEFT JOIN到您当前的查询。对于这种技术要正确执行&#xff0c;你可能需要对索引列添加到您的表&#xff0c;它包含转换后的时间戳(你copied_timestamp转换为DATE…

项目学生:Spring数据的持久性

这是Project Student的一部分。 其他职位包括带有Jersey的Webservice Client&#xff0c;带有Jersey的 Webservice Server和业务层 。 RESTful webapp onion的最后一层是持久层。 持久层有两种哲学。 一个阵营将数据库视为一个简单的存储&#xff0c;并希望保持这一层非常薄。…

集合框架总结

2019作为新的一年开始&#xff0c;我也着手面试的准备。这篇的博客的主角集合--面试中都会出现的&#xff0c;所以今天特作此总结&#xff0c;也算是复习的成果的一个展示。在查看了许多的博客和源码后我决定将其分成3部分来总结。 三个部分分别是&#xff1a;集合的分类、各个…

python中自定义模块导入飘红_hadoop streaming 中跑python程序,自定义模块的导入

今天在做代码重构&#xff0c;以前将所有python文件放到一个文件夹下&#xff0c;上传到hadoop上跑&#xff0c;没有问题&#xff1b;不过随着任务的复杂性增加&#xff0c;感觉这样甚是不合理&#xff0c;于是做了个重构&#xff0c;建了好几个包存放不同功能的python文件&…

js 提取某()特殊字符串长度

// 提取特殊字符串长度&#xff08;scrstr 源字符串 armstr 特殊字符&#xff09; getStrCount: function(scrstr, armstr) {var count 0;while (scrstr.indexOf(armstr) > 1) {scrstr scrstr.replace(armstr, "")count ;}return count; } 更多专业前端知识&am…

运行jar包使用外部依赖

nohup java -Dloader.path"lib/" -Dfile.encodingutf-8 -jar test.jar > test.out 2>&1 & 转载于:https://www.cnblogs.com/hqzmss/p/9719380.html

调查内存泄漏第2部分–分析问题

这个小型系列的第一个博客介绍了如何创建一个非常泄漏的示例应用程序&#xff0c;以便我们可以研究解决服务器应用程序上基于堆的问题的技术。 它展示了Producer-Consumer模式的一个大问题&#xff0c;即消费者代码必须能够至少与生产者一样快&#xff08;如果不是更快&#xf…

es6 语法 (Decorator)

修饰器是一个函数&#xff0c;用来修改类的行为&#xff08;注意&#xff1a;1、函数 2、修改行为 3、对类进行操作&#xff09;{//修饰器函数定义 target:类本身&#xff0c;name名称&#xff0c;descriptor描述let readonly function(target, name, descriptor) {descript…

11小时 python自动化测试从入门到_从设计到开发Python接口自动化测试框架实战,资源教程下载...

课程名称从设计到开发Python接口自动化测试框架实战&#xff0c;资源教程下载课程简介&#xff1a;课程从接口基础知识入门&#xff0c;从抓包开始&#xff0c;到接口工具的运用&#xff0c;再到常见接口库、接口开发、Mock服务、unittest框架的运用&#xff0c;再讲解接口测试…

在Objc项目中调用Swift

之前的文字中记录了在Swift项目中调用OC的相关代码&#xff0c;比较简单直接 传送门 但是在OC中调用swift代码则不是那么的和谐&#xff0c;网络上很多文章业已经有点陈旧。记录步骤如下&#xff1a; 1.创建OC项目 (1)启动 xcode -> 创建singleView新项目 -> 命名为: obj…

「SDOI2014」数数 解题报告

「SDOI2014」数数 题目描述 我们称一个正整数 \(N\) 是幸运数&#xff0c;当且仅当它的十进制表示中不包含数字串集合 \(S\) 中任意一个元素作为其子串。 例如当 \(S(\)22, 333, 0233\()\) 时&#xff0c;233 是幸运数&#xff0c;2333、20233、3223 不是幸运数。 给定 \(N\) 和…

pymssql mysql_Python利用pymssql访问mysql数据库

#codingutf8#!/usr/bin/env python#-------------------------------------------------------------------------------# Name: pymssqlTest.py# Purpose: 测试 pymssql库&#xff0c;该库到这里下载&#xff1a;http://www.lfd.uci.edu/~gohlke/pythonlibs/#pymssql## Author…

调查内存泄漏第1部分–编写泄漏代码

前几天&#xff0c;我发现了这个小问题&#xff1a;该服务器运行了一段时间&#xff0c;然后掉下来了。 然后通过启动脚本重新启动&#xff0c;整个过程重复进行。 这听起来并不那么糟糕&#xff0c;尽管对数据的损失很大&#xff0c;但对业务的重要性并不重要&#xff0c;因此…

js正整数正则表达式

function testNumber(){ var yourinputValue$("#yourinputId").val();var reg /^[1-9]\d*$/;alert(reg.test(yourinputValue))} 更多专业前端知识&#xff0c;请上 【猿2048】www.mk2048.com