Соединения набора реплик MongoDB PHP никогда не закрываются

#php #mongodb #replication

#php #mongodb #репликация

Вопрос:

При подключении к mongo без набора реплик, например:

 new Mongo('mongodb://localhost');
  

все работает отлично, соединения закрываются, как только они выходят за пределы области видимости, а общее количество подключений к mongo составляет ~ 10.

 PRIMARY> db.serverStatus().connections;
{ "current" : 6, "available" : 19994 }
  

Однако, когда я указываю набор реплик, соединения никогда не закрываются, они просто продолжают накапливаться и закрываются только при перезапуске процесса php-fpm.

 new Mongo('mongodb://localhost', array("replicaSet" => "set"));


PRIMARY> db.serverStatus().connections;
{ "current" : 1298, "available" : 18702 }
  

Самое странное, что Mongo должен поддерживать до ~ 20 000 соединений. FPM начинает сбоить, когда я достигаю около 700 подключений к mongo.

Я написал небольшой уровень абстракции (ниже), чтобы помочь отладить проблему, в обоих случаях вызывается close() и возвращает true . Исключения никогда не генерируются. Есть мысли? Я использую PHP 5.3.8-1 (fpm) , и php-mongo-driver v1.2.7

 class MongoDBI {
  private static $_db;
  private static $_mongo;
  private static $_instance;

  private function __construct() {
    try {
      self::$_mongo = new Mongo(MONGODB_SERVER, array("replicaSet" => "set"));
      self::$_db = self::$_mongo->selectDB(MONGODB_DATABASE);
    } catch(MongoConnectionException $e) {
      log("Unable to connect to Mongo: " . $e->getMessage()  . "n");
    } catch(Exception $e) {
      log("Mongo: " . $e->getMessage()  . "n");
    }
  }

  public function __destruct() {
    try {
      $status = self::$_mongo->close();
      log("STATUS: " . $status . "n");
    } catch(Exception $e) {
      log("Mongo: " . $e->getMessage()  . "n");
    }
  }

  public static function getInstance() {
    if(!isset(self::$_db))
       self::$_instance = new MongoDBI();

    return self::$_db;
  }
}
  

редактировать: rs.status();

 PRIMARY> rs.status()
{
    "set" : "somereplicaset",
    "date" : ISODate("2011-11-02T20:33:14Z"),
    "myState" : 1,
    "members" : [
            {
                    "_id" : 0,
                    "name" : "node1:27017",
                    "health" : 1,
                    "state" : 1,
                    "stateStr" : "PRIMARY",
                    "optime" : {
                            "t" : 1320265677000,
                            "i" : 1
                    },
                    "optimeDate" : ISODate("2011-11-02T20:27:57Z"),
                    "self" : true
            },
            {
                    "_id" : 1,
                    "name" : "node2:27017",
                    "health" : 1,
                    "state" : 2,
                    "stateStr" : "SECONDARY",
                    "uptime" : 703192,
                    "optime" : {
                            "t" : 1320265677000,
                            "i" : 1
                    },
                    "optimeDate" : ISODate("2011-11-02T20:27:57Z"),
                    "lastHeartbeat" : ISODate("2011-11-02T20:33:13Z"),
                    "pingMs" : 0
            }
    ],
    "ok" : 1
}
  

Комментарии:

1. Какие еще серверы есть в вашем наборе реплик и может ли клиент PHP связаться с ними? Или, для начала, что rs.status() возвращает для вас в оболочке mongo?

2. есть два сервера, мы можем назвать их node1 и node2. Не имеет значения, указываю ли я только node1 или оба node1 и node2 при подключении («mongodb:// node1, node2»). см. Выше для редактирования, показывающего rs.status(); PHP не показывает ошибок при подключении ни к одному из них.

Ответ №1:

Оказывается, это ошибка в mongo-php-driver версии v1.2.7, понижение версии до 1.2.6 полностью устранило проблему.

Комментарии:

1. Однако теперь я бы предложил перейти на 1.4.x (последнюю версию)