2014-09-13 4 views
2

Мне нужно управлять несколькими подключениями к базе данных MongoDb с помощью клиента casbah scala. У меня есть приближение, которое работает , но откройте сотни соединений.Почему несколько соединений mongodb с Casbah?

Я хочу, чтобы сохранить Map [String, MongoDB], который сохраняет соединение для каждой базы данных (которая является ключом. Я использую это в Спарке Streaming с кластером два узлов, так я думаю, что это сериализация проблема, но я не знаю, как это исправить.

Посмотрите мой класс.

abstract class AbstractMongoDAO(@transient val config: Config) extends Closeable with Serializable { 

     @transient private val mongoConfig = config.getConfig(CONFIG_KEY) 
     private val host = mongoConfig.getString(CONFIG_KEY_HOST) 

     @transient private var _mongoClient: MongoClient = MongoClient(host) 
     private var _dbs: mutable.HashMap[String, MongoDB] = mutable.HashMap() 

     protected def dbs(): mutable.HashMap[String, MongoDB] ={ 
     if(_dbs == null) 
      _dbs = mutable.HashMap() 
     _dbs 
     } 

     def mongoClient: MongoClient = { 
     if (_mongoClient == null) { 
      _mongoClient = MongoClient(host) 
     } 
     _mongoClient 
     } 

     def db(dbName: String):MongoDB = { 
     if (dbs.get(dbName) == None) { 
      _dbs += (dbName -> mongoClient.getDB(dbName)) 
     } 
     _dbs.get(dbName).get 
     } 

     override def close() = { 
     Option(_mongoClient).foreach(_.close()) 
     } 

    } 

    private object AbstractMongoDAO { 
     val CONFIG_KEY = "mongo" 
     val CONFIG_KEY_HOST = "host" 

    } 

а то у меня есть еще один класс, который расширяет AbstractMongoDao

class MongoDAO (override val config : Config) 
    extends AbstractMongoDAO(config) with Serializable 

И я получаю соединение db с этим простым кодом. appName - это переменная база данных.

val _db = db(appName) 

Что я делаю неправильно?

ответ

4

Casbah построен на официальном Java driver. MongoClient представляет собой внутренний пул соединений db с кластером MongoDB. Если вы используете один и тот же кластер и меняете имя базы данных, а не хост, вам не нужно создавать несколько MongoClient s, одного будет достаточно для всего приложения.

Для настройки MongoClient отметьте this документацию и соответствующую информацию options. Если у вас есть несколько хостов DB или хотите использовать несколько MongoClient сек, то вы можете создать свои варианты и создать MongoClient вроде этого:

val options = MongoClientOptions.builder() 
      .connectionsPerHost(1) 
      // add other options if needed 
      .build(); 

val _mongoClient = MongoClient(host, options) 

В вашем случае, поскольку только дб имя neeeds изменить и не дб хозяин, я бы измените метод, который получает db:

def db(dbName: String):MongoDB = 
    mongoClient.getDB(dbName) // db will be created in Mongo on the fly if not exist 

И вам больше не нужна карта.

+1

Я сделал то, что вы мне сказали, но все же создает несколько подключений ... Я установил соединения в сопутствующем объекте с вашими монголевыми приложениями и теперь работает правильно. Спасибо. – gasparms

 Смежные вопросы

  • Нет связанных вопросов^_^