前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MongoDB保存数据的优化方法

MongoDB保存数据的优化方法

作者头像
小歪
发布于 2018-12-28 08:22:11
发布于 2018-12-28 08:22:11
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

这两天频繁遇到MongoDB插入数据的问题,这里记录下。

问题描述:我有多个线程在抓数据,每天数据里有含有多个文档(Document),使用Pymongo的插入方法,逐条插入。形如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def save_to_mongo(data):
    for i in data:
        db.insert_one(i)

在接收到数据后直接调用该方法即可。但是运维那边反馈,数据库压力比较大,让我修改。仔细想了想,可以使用insert_many方法。

插入可迭代的文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> db.test.count_documents({})
0
>>> result = db.test.insert_many([{'x': i} for i in range(2)])
>>> result.inserted_ids
[ObjectId('54f113fffba522406c9cc20e'), ObjectId('54f113fffba522406c9cc20f')]
>>> db.test.count_documents({})
2

有几个参数需要了解

  • documents: 可迭代文档
  • ordered :(可选)如果“True”(默认)文档将按顺序插入服务器,按提供的顺序。 如果发生错误,则中止所有剩余插入。 如果为“False”,文档将以任意顺序插入服务器,可能并行,并且将尝试所有文档插入。
  • bypass_document_validation: (可选)如果为“True”,则允许写入选择退出文档级别验证。 默认为“False”。
  • session (optional): a ClientSession.

好了最简单的方法就是把所有需要保存的数据暂时存放在列表中,最后再插入。建议加上ordered=False参数,可以防止数据保存异常。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def save_mongo():
    while True:
        while len(tmp) > 100:
            try:
                c = db[collection_name]
                c.insert_many(tmp, ordered=False)
                tmp.clear()
            except pymongo.errors.BulkWriteError:
                tmp.clear()
            except Exception as e:
                logging.error('mongodb_save insert_many: {}, {}'.format(e, tmp))
        time.sleep(3)

tmp = []
for i in data:
    tmp.append(i)


t_save = threading.Thread(target=save_mongo)
t_save.setDaemon(True)
t_save.start()

新开一个线程去不停的检查,如果列表数据大于100,则批量插入,或者等待3秒。

这里捕获pymongo.errors.BulkWriteError异常,如果在insert_many时发生错误,会产生该异常。在我这里通常是插入重复数据引起的。

还有一种情况,是在多线程情况下。多个线程共享一个列表对象,肯定是需要加锁的,如果使用Lock来管理数据插入问题,需要去给列表加锁。之前还没用过锁,去看看教程。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import threading

class SharedCounter:
    '''
    A counter object that can be shared by multiple threads.
    '''
    def __init__(self, initial_value = 0):
        self._value = initial_value
        self._value_lock = threading.Lock()

    def incr(self,delta=1):
        '''
        Increment the counter with locking
        '''
        self._value_lock.acquire()
        self._value += delta
        self._value_lock.release()

    def decr(self,delta=1):
        '''
        Decrement the counter with locking
        '''
        self._value_lock.acquire()
        self._value -= delta
        self._value_lock.release()

觉得太麻烦,可以将保存数据等方法封装成一个类对象,实例化一个列表,在每个线程中实例化一个类对象即可,这样多个线程中是不会共享列表数据的。

当然也可以使用另外一种数据结构:Queue队列。Queue是线程安全的,自带锁,使用的时候,不用对队列加锁操作。可以将数据暂时存入queue,然后用列表取出来,数量大于100则插入,并清空列表。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与算法进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python爬虫入门教程 3-100 美空网数据爬取
从今天开始,我们尝试用2篇博客的内容量,搞定一个网站叫做“美空网”网址为:http://www.moko.cc/, 这个网站我分析了一下,我们要爬取的图片在 下面这个网址
梦想橡皮擦
2019/01/22
1.5K1
Python爬虫入门教程 3-100 美空网数据爬取
Python 并发编程(一)之线程
常用用法 t.is_alive() Python中线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程) 这些线程将由操作系统来全权管理。线程一旦启动,将独立执行直到
coders
2018/01/04
7850
Python 并发编程(一)之线程
Ruby 操作 MongoDB(2)
下面这张表是在不同版本 Ruby 语言,不同版本的 MongoDB 中此 Ruby Driver (mongo 2.2.5) 是否兼容的列表
franket
2021/10/19
4550
聊聊 Python 中的同步原语,为什么有了 GIL 还需要同步原语
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2024/05/01
1900
python操作MongoDB
文章目录 1. python操作MongoDB 1.1. 前言 1.2. 综合应用 python操作MongoDB 前言 下面推荐本人写的MongoDB的基本操作博文,介绍的还是比较详细的,喜欢的朋友可以去看看 MongoDB干货篇之安装 MongoDB干货篇之查询数据 MongoDB干货篇之更新数据 综合应用 下面是自己写的一个简单的操作,分别对应了增删改查,虽然不太全面,但是只是简单的示范了一下,当然更多的功能还是需要自己去完善的,因为代码中都有注释,这里就不再详细的说了 # codi
爱撒谎的男孩
2019/12/31
5170
Python操作MongoDB的工具类
windows离线安装python3.6.8环境:https://blog.csdn.net/qq262593421/article/details/111309116
静谧星空TEL
2022/01/05
1K0
Python操作MongoDB的工具类
[Python数据可视化]通过分析胸罩销售记录 发现了惊人的秘密
首先我们需要在搜索页面获取商品的id,为下面爬取用户评价提供productId。key_word为搜索的关键字,这里就是【胸罩】
龙哥
2019/07/30
7040
[Python数据可视化]通过分析胸罩销售记录 发现了惊人的秘密
Python操作MongoDB
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
菲宇
2019/10/22
5060
《MongoDB极简教程》第二章 MongoDB 基本命令(Shell)
MongoDB的所有请求都以命令的形式发出,支持的命令列表参考Database Commands
一个会写诗的程序员
2018/08/20
5500
爬虫(105)pymongo, 这一篇文章够了,值得收藏
学了那么多的爬虫库,怎么能没有数据库这个东东呢?在开发过程中,数据是必不可少的,数据库也是应运而生了,数据和数据库这两个兄弟是缺一不可的
公众号---人生代码
2020/05/16
1.6K0
MongoDB 介绍和操作
MongoDB 和 Redis 一样均为 key-value 存储系统,它具有以下特点:
IT茂茂
2020/03/05
4.5K0
MongoDB 介绍和操作
py3_cookbook_notes_03
并发编程 启动与停止线程 # Code to execute in an independent thread import time def countdown(n): while n > 0: print('T-minus', n) n -= 1 time.sleep(5) # Create and launch a thread from threading import Thread t = Thread(target=countdown,
jeremyxu
2018/05/10
9840
python操作mongodb数据库
(6) $push: 和 $ pushAll 都是向数组属性添加元素。# 好像两者没啥区别
bear_fish
2018/09/20
1.8K0
读者投稿:使用redis和mongodb下载小说,并用pytest做测试
周末为了熟悉mongodb和redis,写了一个抓取《白夜行》小说的程序,并且用pytest测试框架做单元测试, 使用了线程池加快下载速度:
青南
2019/01/23
7690
Python 基于pymongo操作Mongodb学习总结
如果连接用户名和密码包含诸如':', '/', '+' 及'@'保留字符,则使用前应该先进行编码,如下:
授客
2024/01/29
4920
MongoDB与python交互1.Pymongo2.安装3.使用4.mongoDB其它操作5.Mongodb与python交互6.完成命令行项目:学生信息管理(基于Python2.7)
PyMongo是Mongodb的Python接口开发包,是使用python和Mongodb的推荐方式。
Python攻城狮
2018/08/23
1.1K0
MongoDB与python交互1.Pymongo2.安装3.使用4.mongoDB其它操作5.Mongodb与python交互6.完成命令行项目:学生信息管理(基于Python2.7)
MongoDB使用小结:一些常用操作分享
本文整理了一年多以来我常用的MongoDB操作,涉及mongo-shell、pymongo,既有运维层面也有应用层面,内容有浅有深,这也就是我从零到熟练的历程。
拓荒者
2019/09/06
2.1K0
Python也能操作MongoDB数据库
作为非关系数据库的代表--Mongo,可以说是让人又爱又恨,让人爱的是它的便捷性,让人恨的是它的配置,实在是坑多。那么今天我们就来深入剖析它吧。
Python进阶者
2021/08/20
7230
挑战30天学完Python:Day27 Python mongodb
Python是一种后端技术,它可以连接到不同的数据库应用程序。它可以连接到SQL和noSQL数据库。
MegaQi
2023/10/21
2420
挑战30天学完Python:Day27 Python mongodb
Python操作MongoDB看这一篇就够了
MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档、数组及文档数组,非常灵活。在这一节中,我们就来看看Python 3下MongoDB的存储操作。 1. 准备工作 在开始之前,请确保已经安装好了MongoDB并启动了其服务,并且安装好了Python的PyMongo库。 2. 连接MongoDB 连接MongoDB时,我们需要使用PyMongo库里面的MongoClient。一般来说,传入MongoDB的
崔庆才
2018/06/25
23K0
推荐阅读
相关推荐
Python爬虫入门教程 3-100 美空网数据爬取
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验