Открытие и закрытие 16000 экземпляров Mongo DB в PHP - PullRequest
8 голосов
/ 15 января 2012

В настоящее время я работаю над некоторыми личными тестами и тестами, чтобы сравнить рабочий процесс и эффективность между использованием MongoDB и MySQL с примерами реальных данных.

Чтобы настроить свои данные в каждой базе данных, я делаю несколько тысяч циклов ислучайное создание объектов данных для вставки в базу данных.

Однако у меня возникают некоторые проблемы с использованием класса Mongo в PHP, которые я не могу решить.Проблема такова:

У меня есть цикл, который создает новый экземпляр Mongo и соединение, вставляет небольшой массив в коллекцию и затем закрывает соединение.Этот цикл должен выполняться 20000 раз.Однако при попытке создать экземпляр / установить соединение он всегда завершается ошибкой в ​​цикле 16300 (с минимальным значением 16200 и максимальным значением 16350, я бы сказал, после этого).

Код вцикл находится ниже:

$data = get_random_user_data();

$mongo = new Mongo('mongodb://admin:password@localhost:27017/test');

    if ($mongo->test->users->insert($data)) {
        $users[] = array('id' => $data['_id'], 'name' => $data['username']);
    echo $i." - Added user: ".$data['username'].'<br/>';
    }

$mongo->close();

get_random_user_data () просто возвращает простой ассоциативный массив.

Я получаю ошибку:

Fatal error: Uncaught exception 'MongoConnectionException' with message 'Unknown error'

В строке:

$mongo = new Mongo('mongodb://admin:password@localhost:27017/test');

Есть идеи?Есть ли что-то фундаментальное, чего мне не хватает, например защиты от спама?

Заранее спасибо.

Дополнительная информация:

Скрипт умирает наоколо 114,9797 секунд.Это не проблема с памятью или временем на PHP, так как все ограничения сняты, и я вчера проверил свои тесты MySQL, вставив 120000 строк (с тем же методом зацикливания открытого соединения, вставки, закрытия соединения) в течение часа без проблем.

Запуск PHP версии 5.3.5

phpinfo Информация о Mongo:

MongoDB Support enabled
Version 1.2.0-
Directive   Local Value Master Value
mongo.allow_empty_keys  0   0
mongo.allow_persistent  1   1
mongo.auto_reconnect    1   1
mongo.chunk_size    262144  262144
mongo.cmd   $   $
mongo.default_host  localhost   localhost
mongo.default_port  27017   27017
mongo.long_as_object    0   0
mongo.native_long   0   0
mongo.no_id 0   0
mongo.utf8  1   1

Ответы [ 3 ]

6 голосов
/ 18 января 2012

Ваша операционная система имеет ограниченное количество сокетов, которые она готова открыть. Когда вы открываете сокет, а затем закрываете его, ОС не сразу помещает его обратно в пул «доступных», она на некоторое время зависает в состоянии «ожидания времени», о котором Нат упоминает в своем ответе .

Вы можете увеличить количество сокетов, которые откроет ваша ОС, см. http://www.mongodb.org/display/DOCS/Too+Many+Open+Files (каждый сокет является открытым "файлом").

Кроме того, вы используете довольно старую версию драйвера, возможно, вы захотите обновить ее.

3 голосов
/ 15 января 2012

Я подтверждаю, что это то же самое поведение и с драйвером ruby.Я повторил аналогичный случай с ruby ​​mongo, который вставляет 20000 записей, открывая / закрывая экземпляр mongo каждый раз.И он продолжает сбой между 14110 и 14200.

Это сообщение об ошибке

 uncaught throw #<Mongo::ConnectionFailure: Failed to connect to host localhost and port 27017: Cannot assign requested address - connect(2)>

Это полная трассировка стека

Failed to connect to host localhost and port 27017: Cannot assign requested address - connect(2)
["/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/pool.rb:171:in `rescue in checkout_new_socket'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/pool.rb:166:in `checkout_new_socket'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/pool.rb:267:in `block (2 levels) in checkout'", "<internal:prelude>:10:in `synchronize'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/pool.rb:259:in `block in checkout'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/pool.rb:252:in `loop'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/pool.rb:252:in `checkout'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/connection.rb:496:in `checkout_writer'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/networking.rb:34:in `send_message'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/collection.rb:948:in `block in insert_documents'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/util/logging.rb:28:in `instrument'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/collection.rb:944:in `insert_documents'", "/home/ramesh/.rvm/gems/ruby-1.9.2-p290/gems/mongo-1.5.2/lib/mongo/collection.rb:343:in `insert'", "/home/ramesh/Desktop/load_test.rb:15:in `block in load_test'", "/home/ramesh/Desktop/load_test.rb:6:in `times'", "/home/ramesh/Desktop/load_test.rb:6:in `load_test'", "(irb):2:in `irb_binding'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/workspace.rb:80:in `eval'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/workspace.rb:80:in `evaluate'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/context.rb:254:in `evaluate'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:159:in `block (2 levels) in eval_input'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:273:in `signal_status'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:156:in `block in eval_input'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:243:in `block (2 levels) in each_top_level_statement'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:155:in `eval_input'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:70:in `block in start'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:69:in `catch'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:69:in `start'", "/home/ramesh/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'"]
ArgumentError: uncaught throw #<Mongo::ConnectionFailure: Failed to connect to host localhost and port 27017: Cannot assign requested address - connect(2)>
    from /home/ramesh/Desktop/load_test.rb:21:in `throw'
    from /home/ramesh/Desktop/load_test.rb:21:in `rescue in block in load_test'
    from /home/ramesh/Desktop/load_test.rb:7:in `block in load_test'
    from /home/ramesh/Desktop/load_test.rb:6:in `times'
    from /home/ramesh/Desktop/load_test.rb:6:in `load_test'

Также, как сказал @ChrisuiЯ также не испытываю никаких падений памяти.

Это скрипт, который я пробовал

require 'mongo'

def load_test
    start = Time.now
    puts 'starting at :' + start.to_s 
    20000.times do |i|    
            begin
                puts i      
            doc = {"name" => "MongoDB", "type" => "database", "count" => 1,"info" => {"x" => 203, "y" => '102'}}
            con = Mongo::Connection.new("localhost")
            db   = con['bulktest']
            coll = db['test']
            coll.insert(doc)
            con.close
                con,db,coll=nil,nil,nil
        rescue Exception => e  
            puts e.message  
            puts e.backtrace.inspect  
            throw e 
        end

    end
    stop = Time.now
    puts 'stoping at :' + stop.to_s 
    puts 'elapsed time is ' + (stop-start).to_s + ' seconds'
end
1 голос
/ 17 января 2012

Ваш тест не имеет смысла. Не держите открытое / закрытое соединение. Вы должны повторно использовать постоянное соединение вместо открытия / закрытия каждый раз. Если вы быстро откроете и закроете сокет, у вас будет слишком много сокетов в состоянии ожидания по времени, которые все еще используют дескрипторы файлов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...