Python 比较MongoDB和DB大容量插入性能

Python 比较MongoDB和DB大容量插入性能,python,mongodb,python-2.7,rethinkdb,nosql,Python,Mongodb,Python 2.7,Rethinkdb,Nosql,这是我在这里的第一个正式问题;我欢迎任何/所有对我的帖子的批评,这样我就可以学习如何成为一个更好的so公民 我正在检查非关系型数据库管理系统是否存储了可能较大的电子邮件选择退出列表,倾向于使用MongoDB或RejectDB,使用它们各自的Python客户端库。我的应用程序的难点是批量插入性能,因此我设置了两个Python脚本,将20000条记录以5000条为一批插入MongoDB和RejectDB集合 MongoDB python脚本mongo_insert_test.py: NUM_LINE

这是我在这里的第一个正式问题;我欢迎任何/所有对我的帖子的批评,这样我就可以学习如何成为一个更好的so公民

我正在检查非关系型数据库管理系统是否存储了可能较大的电子邮件选择退出列表,倾向于使用MongoDB或RejectDB,使用它们各自的Python客户端库。我的应用程序的难点是批量插入性能,因此我设置了两个Python脚本,将20000条记录以5000条为一批插入MongoDB和RejectDB集合

MongoDB python脚本mongo_insert_test.py:

NUM_LINES = 20000
BATCH_SIZE = 5000

def insert_records():
    collection = mongo.recips
    i = 0
    batch_counter = 0
    batch = []
    while i <= NUM_LINES:
        i += 1
        recip = {
            'address': "test%d@test%d.com" % (i, i)
        }
        if batch_counter <= BATCH_SIZE:
            batch.append(recip)
            batch_counter += 1
        if (batch_counter == BATCH_SIZE) or i == NUM_LINES:
            collection.insert(batch)
            batch_counter = 0
            batch = []

if __name__ == '__main__':
    insert_records()
NUM_LINES = 20000
BATCH_SIZE = 5000

def insert_records():
    i = 0
    batch_counter = 0
    batch = []
    while i <= NUM_LINES:
        i += 1
        recip = {
            'address': "test%d@test%d.com" % (i, i)
        }
        if batch_counter <= BATCH_SIZE:
            batch.append(recip)
            batch_counter += 1
        if (batch_counter == BATCH_SIZE) or i == NUM_LINES:
            r.table('recip').insert(batch).run()
            batch_counter = 0
            batch = []

if __name__ == '__main__':
    insert_records()
在相同的环境中,RejectionDB脚本执行速度要慢得多,在2分钟内插入20000条记录:

$ time python rethink_insert_test.py
real    2m2.502s
user    0m3.000s
sys     0m0.052s
关于这两个DBMS的工作方式,我是否遗漏了一些重要的东西?为什么这个测试的表现如此糟糕


我的dev机器有大约1.2GB的可用内存用于这些测试。

RejectDB目前通过在服务器上一次执行一个插入来实现批量插入。因为Reinspect将所有记录刷新到磁盘(因为它的设计考虑到了安全第一),这对像这样的工作负载有着非常坏的影响

我们正在做两件事来解决这个问题:

  • 大容量插入将通过服务器上的大容量插入算法实现,以避免一次执行一个插入
  • 如果您愿意,我们将为您提供放宽耐久性约束的选项,以允许高速缓存吸收高通量插入(作为不经常同步到磁盘的交换)
  • 这将绝对是固定在4-12周(如果你需要这个尽快,请随时拍摄我的电子邮件到)slava@rethinkdb.com我会看看我们是否能重新确定优先顺序)

    以下是相关的github问题:


    希望这有帮助。如果您需要帮助,请随时联系我们。

    撇开咖啡豆发布的内容:

  • 根据您使用的驱动程序版本以及如何配置与mongodb的连接,服务器甚至可能不会确认这些插入。如果您使用的是最新版本的Python驱动程序,那么这些操作只是等待服务器的接收确认(这并不意味着数据已经写入内存)。有关我所指内容的更多详细信息,请查看

  • 在RejectDB的情况下,可以通过并行插入来提高速度。基本上,如果您运行多个进程/线程,您将看到速度提高。在Mongo的情况下,由于涉及锁,并行性将没有帮助

  • 也就是说,RejectDB可以提高写入速度


    附言:我为《反思》工作,但是以上几点都是基于我对这两个系统的公正了解。

    Pymongo开发者-如果您没有这样做,请确保您使用的是最新的Pymongo版本和
    MongoClient
    MongoRepicaSetClient
    ,这样您的写入操作将得到确认,而不会被触发和遗忘。正如@Alex所说,它们很可能就是你所需要的


    我需要考虑的其他问题是:这是数据库的主要用例还是核心难点?您可能需要考虑其他数据模式,查询数据,使用方便和可维护性,然后做出决定。

    < P>请原谅类比-但这使我的观点清晰。 把值钱的东西锁在保险箱里不需要花太多时间,但可以随意锁上几千次。如果你把钱寄到银行的金库里,考虑一下你的价值在你的银行旅程中不安全的时间;那个包裹可能会和其他许多包裹一起堆放——来自志同道合的储户。有人会抽出时间打开你的包裹,然后把它和其他东西堆放在一起,放在一个安全的保险库里


    这就是定期将数据提交到磁盘与批处理或延迟将数据写入磁盘之间的区别。这是在更高的数据完整性和更高的写性能之间的折衷。如果数据丢失不那么重要,那么就完全可以不那么频繁地同步到磁盘,批量或延迟地写入更新。做出错误的选择总有一天会让你痛苦不堪,所以明智地选择吧

    与pymongo的并行性也应该有一些改进,因为在线时间会减少阻塞。我将更新我的mongo测试脚本,以使用MongoClient来解决此ack问题。当我有机会这样做的时候,我会编辑我的帖子。是的,我意识到在我做了测试之后,我使用的是一个相当过时的mongo客户端;谢谢你指出这一点。我将Postgres db用于一般的Django关系存储,将nosql用于电子邮件列表存储,导入(大容量插入)和清理(某种映射/减少比较列表)是nosql db的两个主要用例。谢谢@coffeemug,这回答了我的问题。我将密切关注github,以便知道这一问题何时得到解决,因为我很高兴尝试重新思考。@njyunis:1.5最近推出了更快的批量插入:。标题说明了一切;)@FabianoPS,我并不是真的想要什么科学的东西;我只是想知道为什么在Rejection中做与MongoDB相同的操作要花费一个数量级的时间。我不认为网络/磁盘延迟起了多大作用(如果有的话)。Rejection发表了一篇更新文章,希望能以一种有意义的(非肤浅的)方式解决这个问题。嗨@njunis,这篇文章的核心信息非常有趣:有很多是为了解释写作速度,这是一个评论,不是一个评论answer@njyunis你能用最新版本再试一次,让我们知道区别吗?
    $ time python rethink_insert_test.py
    real    2m2.502s
    user    0m3.000s
    sys     0m0.052s