У меня есть глобально распределенный набор реплик MongoDB (для тестирования) с 3 серверами. Надо priority = 1
другие имеют priority = 0
поэтому они никогда не станут первичными.
Эта настройка используется для распространения файлов на реплицированные серверы путем добавления их непосредственно на основной сервер с использованием GridFS. Распределение работает нормально.
Я создал простой скрипт php watcher, который выполняется на вторичных серверах с использованием предпочтений чтения. \MongoClient::RP_NEAREST
, Я хотел определить метку времени, когда реплицированные получили все файлы с первичной.
Я хотел убедиться, что скрипт php на вторичных серверах использует экземпляр mongodb на своем сервере (а не на основном), и поэтому я остановил основной сервер mongodb. После этого оба сервера сохраняют свою второстепенную роль.
Если основной сервер недоступен, я все еще мог выполнять такие запросы, как count()
а также find()
на регулярных коллекциях (также fs.files
коллекция).
Но вызовы, использующие GridFS, MongoConnectionException: No candidate servers found
исключение.
Я создал небольшой скрипт, с помощью которого вы сможете воспроизвести ошибку.
$serverList = '...';
$conn = new \MongoClient(
'mongodb://'.$serverList,
array(
'replicaSet' => 'r0',
'readPreference' => \MongoClient::RP_NEAREST,
'username' => 'bat',
'password' => '',
'db' => 'bat'
)
);
$db = $conn->selectDB('bat');
echo 'works fine...';
$files = $db->selectCollection('fs.files');
$documentsCount = $files->count();
$documents = $files->find();
foreach($documents as $document) {
echo $document['filename'] . ', ';
}
echo 'throws exception...';
$gridfs = $db->getGridFS();
$documentsCount = $gridfs->find()->count();
$documents = $gridfs->find();
foreach($documents as $document) {
echo $document->getFilename();
}
Если основной сервер недоступен, строки после echo 'works fine...';
будет работать нормально, а строка после echo 'throws exception...';
выбросит исключение.
Может быть, это связано с проблемой в драйвере Java JAVA-401, была похожая проблема с использованием вторичных серверов и gridfs. Может быть, gridfs пытается обеспечение показателей если коллекция fs.files содержит менее 1000 файлов, что невозможно на вторичном компьютере.
Я разобрался с проблемой, это была просто неправильная строка $gridfs->find()->count()
, Если вы выполните $gridfs->count()
или же $gridfs->find()
это работает отлично.
Так что вам придется использовать
$gridfs->count()
вместо$gridfs->find()->count()
,
Я не знаю почему $gridfs->find()->count()
работает правильно (и только правильно), если доступен основной сервер.
Других решений пока нет …