java - mongodb 2.6+中的批量操作可以用作缓冲区/队列吗?

标签 java multithreading mongodb

MongoDB从2.6版本开始引入Bulk(),我检查了API,对我来说似乎很棒。

在使用此API之前,如果需要批量插入,则必须将文档存储在列表中,它们使用insert()插入整个列表。在多线程环境中,还应考虑并发性。

  • 批量API内是否实现了队列/缓冲区?每次我
    在execute()之前放入一些东西,数据存储在int中
    他排队/缓冲,对吗?
  • 因此,我不需要编写自己的队列/缓冲区,只需使用Bulk.insert()Bulk.find().update(),对吗?
  • 有人可以告诉我更多有关队列的信息。我仍然需要关注并发问题吗?
  • 因为像db.collection.initializeUnorderedBulkOp()一样创建了Bulk,所以如果不释放Bulk实例,它将保持与MongoDB服务器的连接,对吗?
  • 最佳答案

    从“是否需要存储自己的列表?”这个基本思想出发,然后不是真的,但是我想这一切实际上取决于您在做什么。

    对于Bulk Operations API下发生的事情的内部原理的基本了解,最好的查看方法是查看每个type of operation的单独命令格式。因此,相关的手册部分为here

    因此,您可以将"Bulk"接口(interface)视为添加到该接口(interface)的所有操作的列表或集合。而且,您可以根据需要(在一定的内存和实际限制条件下)添加尽可能多的内容,并考虑此“队列”的“排水”方法是 .execute() 方法。

    如此处的文档所述,无论您“排队”多少次操作,实际上最多一次最多只能以1000个操作为一组发送到服务器。要记住的另一件事是,没有任何治理可确保这1000个操作请求实际上符合16MB BSON限制。因此,对于MongoDB来说,这仍然是一个硬性限制,并且您只能在一次发送到服务器时,有效地形成一个“请求”,其总大小小于该数据大小的限制。

    因此,一般而言,每1000个或更少的条目向服务器发出一次自己的“执行/排出”请求通常更为实用。里程可能会有所不同,但是在此有一些注意事项。

    对于“有序”或“无序”操作请求,在前一种情况中,如果在发送的批处理中生成错误,则所有排队的操作都将中止。当然的含义当然,所有操作在之后发生时遇到错误。

    在后一种情况下,对于“无序”操作,不会报告致命错误,但是在返回的WriteResult中,除了“无序”操作外,您还会获得遇到的任何错误的“列表”,这意味着该操作是不一定以任何特定顺序“应用”,这意味着在应用该操作之前,您不能“排队”依赖于正在处理的“队列”中其他内容的操作。

    因此,您担心要获得多大的WriteResult,以及实际上如何在应用程序中处理该响应。如前所述,里程数可能会有所不同,因为这是对较小且可管理的响应的非常大的响应。

    就并发而言,这里确实需要考虑一件事。即使您在一次调用中向服务器发送了许多指令,而没有等待单独的转移和确认,它实际上仍然只能一次处理
    一次指令。这些可以是initialize方法所隐含的排序的,也可以是“un-ordered”(在选择了该方法的情况下),然后操作可以像在服务器上一样“并行”运行,直到批次被耗尽为止。

    但是在“批处理”完成之前没有“锁定”,因此它不能替代“事务”,因此请不要以该错误为设计要点。同样的MongoDB规则适用,但是这里的好处是“一个写入服务器”和“一个响应返回”,而不是每个操作一个。

    最后,关于API是否在此处保留了一些“服务器连接”,答案是而不是。正如查看命令内部结构的最初要点所指出的那样,此“队列”构建纯粹是“仅客户端”。在调用.execute()方法的
    之前,不以任何方式与服务器通信。这是“设计使然”,实际上只有一半,因为主要是我们不想在每次添加操作时都将数据发送到服务器。一次完成。

    因此,“批量操作”是“客户端队列”。一切都存储在客户端中,直到.execute()“拖入”队列并将所有操作立即发送到服务器。然后,服务器会给出一个响应,其中包含您可以根据需要处理的所有发送操作结果。

    同样,一旦.execute()被调用,就不能再将操作“排队”到批量对象,并且.execute()都不能再次被调用。根据实现的不同,您可以进一步检查“批量”对象和结果。但是一般情况是,您需要发送更多的“批量”操作,然后像大多数队列系统一样重新初始化并重新开始。

    加起来:

  • 是的。对象有效地“排队”操作。
  • 您不需要自己的列表。这些方法本身就是“列表生成器”
  • 操作按顺序是“有序的”或“无序的”,但是所有操作均由服务器根据常规MongoDB规则进行单独处理。没有交易。
  • “初始化”命令不直接与服务器通信,也不自己“保持连接”。实际与服务器“交谈”的唯一方法是.execute()

  • 因此,它是一个非常好的工具。您可以从旧版命令实现中获得更好的写入操作。但是不要期望它提供的功能超出了MongoDB的基本功能。

    关于java - mongodb 2.6+中的批量操作可以用作缓冲区/队列吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25803220/

    相关文章:

    java - 如何访问 User.getAddresses() 和 User.getPhones() 返回的 Java 对象中的数据?

    python - wxPython 与长时间运行的进程卡住动画 gif

    ruby-on-rails - Mongoid 中的字段别名

    javascript - Mongodb:如何在上限集合上创建 `tail -f` View ?

    mongodb - 如何在没有类型的情况下将 mongo 导出为 json

    java - spring boot 中不使用嵌入式 Tomcat Servlet 容器时收到异常

    java - 循环遍历 XML 子节点

    java - 即使绘制新文本,也设置一次 swing 应用程序的默认字体

    c++ - 关键部分或互斥体应该是真正的成员变量还是什么时候应该是?

    multithreading - 线程共享的Perl