如何配置MongoDB Java驱动程序MongoOptions以供生产使用?

Dan*_*tes 100 production-environment mongodb database-performance database-tuning

我一直在网上搜索为MongoDB Java驱动程序配置MongoOptions的最佳实践,除了API之外,我还没有提出太多其他方法.这个搜索在我遇到"com.mongodb.DBPortPool $ SemaphoresOut:Out of semaphores to get db connection"错误并且通过增加连接/乘数我能够解决该问题后开始.我正在寻找为生产配置这些选项的链接或最佳实践.

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

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

较新的司机有更多的选择,我也有兴趣听到这些.

Rem*_*iet 159

更新至2.9:

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

  • connectionsPerHost是单个Mongo实例(它的单例,因此通常每个应用程序有一个)可以建立到mongod/mongos进程的物理连接数.在编写本文时,即使实际查询吞吐量较低,java驱动程序也会最终建立此连接数量(按顺序,您将看到mongostat中的"conn"统计信息上升,直到它达到每个应用服务器的此数量).

    在大多数情况下,没有必要将此值设置为高于100,但此设置是"测试并查看"事物之一.请注意,您必须确保将其设置得足够低,以便与服务器的连接总量不会超过

    db.serverStatus().connections.available

    在生产中,我们现在有40个.

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

  • maxWaitTime.线程将等待连接在连接池上变为可用的ms数,如果不及时发生则引发异常.保持默认.

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

  • threadsAllowedToBlockForConnectionMultiplier.connectionsPerHost的乘数表示如果池当前已用尽,则允许等待连接变为可用的线程数.这个设置将导致"com.mongodb.DBPortPool $ SemaphoresOut:Out of semaphores获取数据库连接"异常.一旦此线程队列超过threadsAllowedToBlockForConnectionMultiplier值,它将抛出此异常.例如,如果connectionsPerHost为10且该值为5,则在抛出上述异常之前,最多可以阻塞50个线程.

    如果您预计吞吐量中的大峰值可能会导致大队列暂时增加此值.出于这个原因,我们现在已经在1500年了.如果您的查询负载始终超过服务器,则应该相应地改善硬件/扩展情况.

  • readPreference.(更新,2.8 +)用于确定默认读取首选项并替换"slaveOk".通过类工厂方法之一设置ReadPreference.有关最常见设置的完整说明,请参阅本文末尾

  • w.(更新,2.6 +)此值确定写入的"安全性".当此值为-1时,无论网络或数据库错误如何,写入都不会报告任何错误.WriteConcern.NONE是适当的预定义WriteConcern.如果w为0,那么网络错误将使写入失败,但mongo错误不会.这通常被称为"即发即忘"写入,并且应该在性能比一致性和持久性更重要时使用.将WriteConcern.NORMAL用于此模式.

    如果将w设置为1或更高,则认为写入是安全的.安全写入执行写入并通过对服务器的请求进行跟进,以确保写入成功或检索错误值(如果不成功)(换句话说,它在写入后发送getLastError()命令).请注意,在此getLastError()命令完成之前,将保留连接.作为其中的一个结果和所述额外命令的吞吐量将signficantly低于以w <= 0写入随着正好1的MongoDB AW值保证写入成功(或失败的核查的)上你发送的写到该实例.

    在副本的情况下,将可以使用更大的值用W whcih告诉MongoDB中的写入发送到至少"W"返回(或者更准确地说之前设置副本的成员,等待你写为"W"成员的复制).您还可以将w设置为字符串"majority",它告诉MongoDB执行对大多数副本集成员的写入(WriteConcern.MAJORITY).除非您需要原始性能(-1或0)或复制写入(> 1),否则应将此值设置为1.大于1的值会对写入吞吐量产生相当大的影响.

  • fsync.Durability选项,在启用每次写入后强制mongo刷新到磁盘.我从来没有遇到与写入积压相关的任何持久性问题,所以我们在生产中使用false(默认).

  • j*(新2.7+)*.布尔值,当设置为true时,强制MongoDB在返回之前等待成功的日记组提交.如果启用了日记功能,则可以启用此功能以获得额外的持久性.请参阅http://www.mongodb.org/display/DOCS/Journaling以查看日志记录带给您的内容(以及您可能希望启用此标志的原因).

ReadPreference ReadPreference类允许您配置在使用副本集时如何路由查询的mongod实例.可以使用以下选项:

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

  • ReadPreference.primaryPreferred():如果可能,所有读取都将转到repset主成员,但如果主节点不可用,则可以查询辅助成员.因此,如果主要变为不可用,则读取最终会一致,但仅在主要不可用时才会变为一致.

  • ReadPreference.secondary():所有读取都转到辅助repset成员,主要成员仅用于写入.只有在最终一致读取时才能使用此选项.尽管对repset可以拥有的(投票)成员数量有限制,但可以使用其他repset成员来扩展读取性能.

  • ReadPreference.secondaryPreferred():如果其中任何一个可用,则所有读取都将转到辅助repset成员.除非所有辅助成员都不可用,否则主要成员专门用于写入.除了回读读取的主要成员之外,这与ReadPreference.secondary()相同.

  • ReadPreference.nearest():读取到最近的数据库客户端可用的repset成员.仅在最终一致读取可接受时使用.最近的成员是客户端和各种repset成员之间具有最低延迟的成员.由于忙碌的成员最终会有更高的延迟,这也应该自动平衡读取负载,尽管根据我的经验,如果成员延迟相对一致,次要(首选)似乎会更好.

注意:以上所有都具有相同方法的标记启用版本,而不是返回TaggableReadPreference实例.可以在此处找到副本集标记的完整描述:副本集标记

  • 将socketTimeout和connectTimeout保留为默认值(无限)是不是很危险?如果由于某种原因连接挂起,您的应用程序(或至少该线程)将永远陷入困境.这些只是设置得非常高(连接30秒,插座2分钟)? (6认同)
  • 似乎是一个非常受欢迎的答案.如果有人对我有兴趣更新这个以反映最新驱动程序的变化,请告诉我 (2认同)