如何configurationMongoDB Java驱动程序MongoOptions以供生产使用?

我一直在寻找networking寻找configurationMongoDB Java驱动程序MongoOptions的最佳实践,我还没有拿出比API更多的东西。 这个search开始后,我遇到了“com.mongodb.DBPortPool $ SemaphoresOut:出信号量来获取数据库连接”错误,并通过增加连接/乘数我能够解决这个问题。 我正在寻找链接或configuration这些生产选项的最佳做法。

2.4驱动程序的选项包括: http : //api.mongodb.org/java/2.4/com/mongodb/MongoOptions.html

  • autoConnectRetry
  • connectionsPerHost
  • connectTimeout
  • maxWaitTime
  • 了socketTimeout
  • threadsAllowedToBlockForConnectionMultiplier

较新的驱动程序有更多的select,我也有兴趣听到这些。

更新到2.9:

  • autoConnectRetry只是意味着驱动程序会在意外断开连接后自动尝试重新连接到服务器。 在生产环境中,您通常需要将此设置为true。

  • connectionsPerHost是单个Mongo实例(它是单例,所以通常每个应用程序有一个)可以build立到mongod / mongos进程的物理连接数量。 在编写的时候,即使实际的查询吞吐量很低,Java驱动程序也会build立这个连接数量。(换句话说,在mongostat中,“conn”统计值会一直上升到每个应用程序服务器达到这个数字为止)。

    在大多数情况下,不需要设置高于100,但是这个设置就是那些“testing并看到”的东西之一。 请注意,您必须确保将其设置得足够低,以便连接到服务器的总数不超过

    db.serverStatus().connections.available

    在生产中,我们现在有这个在40。

  • connectTimeout 。 如名称build议的毫秒数,驱动程序将在连接尝试中止之前等待。 设置超时时间(15-30秒),除非有一个现实的,预期的机会,这将成为其他成功的连接尝试。 通常,如果连接尝试花费的时间超过几秒,则您的networking基础结构无法实现高吞吐量。

  • maxWaitTime 。 线程将等待连接池上可用的连接数的毫秒数,如果不及时发生,则会引发exception。 保持默认。

  • socketTimeout 。 标准套接字超时值。 设置为60秒(60000)。

  • threadsAllowedToBlockForConnectionMultiplier 。 connectionsPerHost的乘数,表示如果池当前耗尽,允许等待连接变为可用的线程数。 这是会导致“com.mongodb.DBPortPool $ SemaphoresOut:Out of semaphores获取db连接”exception的设置。 一旦这个线程队列超过threadsAllowedToBlockForConnectionMultiplier值,它将抛出这个exception。 例如,如果connectionsPerHost为10,并且此值为5,则在引发上述exception之前,最多可有50个线程阻塞。

    如果您预期吞吐量的大峰值可能导致大队列暂时增加此值。 我们目前在1500年就是这个原因。 如果你的查询负载一直超过服务器,你应该相应地改善你的硬件/扩展情况。

  • readPreference(更新,2.8+)用于确定默认读取首选项,并取代“slaveOk”。 通过其中一个类工厂方法设置ReadPreference。 最常见的设置的完整说明可以在这篇文章的末尾find

  • w(UPDATED,2.6+)这个值决定了写的“安全性”。 当这个值是-1时,写入不会报告任何错误,不pipenetworking或数据库错误。 WriteConcern.NONE是适当的预定义WriteConcern为此。 如果w是0,那么networking错误会使写入失败,但是mongo错误不会。 这通常被称为“火灾和遗忘”写道,应该在性能比一致性和耐久性更重要时使用。 对此模式使用WriteConcern.NORMAL。

    如果将w设置为1或更高,则写入被认为是安全的。 安全写入执行写入操作,然后通过向服务器发送请求来确保写入操作成功或者在没有写入操作的情况下检索错误值(换句话说,在写入操作后发送getLastError()命令)。 请注意,直到此getLastError()命令完成连接被保留。 由于这一点和附加的命令,吞吐量将显着低于w <= 0的写入。aw值恰好为1时,MongoDB保证写入实例的写入成功(或可validation失败)。

    在副本集的情况下,您可以使用更高的值,以便告诉MongoDB在返回之前将写入至less发送到副本集的“w”个成员(或者更准确地说,等待写入到“w”成员的复制)。 您还可以将w设置为string“majority”,它告诉MongoDB执行写入大部分副本集成员(WriteConcern.MAJORITY)的操作。 典型的,你应该把它设置为1,除非你需要原始性能(-1或0)或复制写入(> 1)。 高于1的值对写入吞吐量有相当大的影响。

  • fsync 。 持久性选项强制mongo在每次写入后刷新到磁盘。 我从来没有任何与写入积压有关的耐久性问题,所以我们在生产中有这个错误(默认)。

  • j * (NEW 2.7+) *。 布尔值,当设置为true时,会强制MongoDB在返回之前等待成功的日记组提交。 如果您启用了日记function,则可以启用此function以获得更多耐用性。 请参阅http://www.mongodb.org/display/DOCS/Journaling ,了解日志可以获取什么(以及为什么您可能需要启用此标志)。

ReadPreference ReadPreference类允许您configurationmongod实例查询路由到哪些副本集。 以下选项可用:

  • ReadPreference.primary() :所有读取仅转到repset主要成员。 如果您要求所有查询返回一致的(最近写入的)数据,请使用此方法。 这是默认的。

  • ReadPreference.primaryPreferred() :如果可能,所有读取都转到repset主要成员,但如果主要节点不可用,则可以查询次要成员。 因此,如果主服务器变得不可用,则读取变得最终一致,但只有当主服务器不可用时。

  • ReadPreference.secondary() :所有读取都转到次级repset成员,主要成员仅用于写入。 只有在最终一致读取的情况下才能使用它。 额外的repset成员可以用来扩大读取性能,尽piperepset可以拥有(投票)成员的数量是有限制的。

  • ReadPreference.secondaryPreferred() :如果其中任何一个可用,则所有读取都转到次级repset成员。 主要成员专门用于写入,除非所有次要成员变得不可用。 除了回读主要成员读取以外,它与ReadPreference.secondary()相同。

  • ReadPreference.nearest() :读取到数据库客户端可用的最近的repset成员。 只有最终一致的读取是可接受的,才使用 最近的成员是客户端和各种重新设置成员之间具有最低延迟的成员。 由于忙碌的成员最终会有更高的延迟,这也应该自动平衡阅读负载,尽pipe在我的经验中,如果成员延迟相对一致,secondary(Preferred)看起来会更好。

注意:上面所有的都有相同方法的标签启用版本,而是返回TaggableReadPreference实例。 副本集标签的完整描述可以在这里find: 副本集标签

MongoDB驱动程序为Mongo客户端提供了几个选项来处理在使用过程中可能发生的不同networking超时错误。 选项因驱动程序版本和语言而异。 我强烈build议您阅读驱动程序的MongoClient类文档。 在生产中,为这些选项设置正确的值是非常重要的,以避免在应用程序stream程中意外暂停。 以智能方式连接到数据库服务器可以提高您的应用程序性能。

以下是MongoClient的一些重要选项,您可以在生产环境中连接到MongoDB服务器时设置它们。

ServerSelctionTimeOut :服务器select超时是mongo驱动程序在放弃并引发错误之前等待为操作select服务器的毫秒数。Mongo驱动程序使用30秒作为服务器select超时的默认值。 根据使用情况,我们可以增加或减less这个阈值。

连接超时 :连接超时是驱动器在新的连接尝试中止之前等待的毫秒数。连接超时的默认值取决于驱动程序的版本和语言。 Mongo Java和Ruby最新的驱动程序版本有10秒的默认超时连接机构,而NodeJs驱动程序没有超时。如果超时太高,你可能会拖延你的应用程序。 如果超时太低,可以放弃太快。 最好使用不同的值进行testing,以便为应用程序find正确的超时值。

SocketTimeout :套接字超时是一个套接字发送或接收超时之前的毫秒数。Mongo Java&Nodejs Driver的默认套接字超时时间为0,这意味着基本上没有超时。 Ruby提供5s套接字超时。 你不想限制这个超时,因为不同的操作需要可变的时间来操作。

了解MongoDB客户端超时选项有详细的描述,以更多地了解这些选项。