2012-01-14 3 views
8

Tôi hiện đang làm việc trên một số thử nghiệm cá nhân và điểm chuẩn để so sánh quy trình làm việc và hiệu quả giữa việc sử dụng MongoDB và MySQL với dữ liệu ví dụ thế giới thực.Mở và đóng 16000 trường hợp Mongo DB trong PHP

Để thiết lập dữ liệu trong mỗi cơ sở dữ liệu, tôi đang thực hiện vài nghìn vòng và tạo ngẫu nhiên các đối tượng dữ liệu để chèn vào cơ sở dữ liệu.

Tuy nhiên tôi đang gặp một số vấn đề khi sử dụng lớp Mongo trong PHP mà tôi không thể giải quyết. Vấn đề là như vậy:

Tôi có một vòng lặp tạo ra một cá thể và kết nối Mongo mới, chèn một mảng nhỏ vào một bộ sưu tập và sau đó đóng kết nối. Vòng lặp này sẽ chạy 20000 lần. Tuy nhiên nó luôn luôn thất bại xung quanh vòng 16300nd (với một phút 16200 và tối đa 16350 tôi muốn nói sau một vài lần chạy) khi nó cố gắng tạo ra cá thể/tạo kết nối.

Mã trong vòng lặp là dưới đây:

$data = get_random_user_data(); 

$mongo = new Mongo('mongodb://admin:[email protected]: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() chỉ trả về một mảng kết hợp đơn giản.

Các lỗi tôi nhận được là:

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

Trên dòng:

$mongo = new Mongo('mongodb://admin:[email protected]:27017/test'); 

Bất kỳ ý tưởng? Có điều gì đó cơ bản tôi đang thiếu như một số bảo mật hoặc phòng chống spam?

Xin cảm ơn trước.

thêm thông tin:

Các kịch bản chết vào khoảng 114,9797 giây. Nó không phải là một bộ nhớ PHP hoặc thời gian dựa trên vấn đề như tất cả các giới hạn được nâng lên và tôi chạy tiêu chuẩn MySQL của tôi ngày hôm qua chèn 120000 hàng (với cùng một phương pháp looping mở kết nối, chèn, đóng kết nối) trong khoảng một giờ không có vấn đề.

Chạy PHP Version 5.3.5

phpinfo thông tin 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 
+1

Hmm, thú vị. Bạn có thể tái sử dụng kết nối không? Có lẽ đó là một điều cho mỗi quá trình? Điều gì sẽ xảy ra nếu bạn thử cùng một thứ trong, ví dụ, Python? Bạn đã grepped nguồn MongoDB (và/hoặc trình điều khiển PHP) cho 'Unknown error'? Nếu bạn ngủ một chút giữa các kết nối thì sao? – Cameron

+0

Không thể thực sự tái sử dụng kết nối vì đó là một điều tôi muốn đưa vào điểm chuẩn. Tại thời điểm nhận xét này, ai đó đã nói rằng họ gặp vấn đề tương tự với trình điều khiển Ruby của họ. Không nhìn vào nguồn gốc, nhưng tôi sẽ có cơ hội. Cảm ơn vi đa trả lơi. :) – Chrisui

+0

Vâng, tôi hiểu về điểm chuẩn, tôi chỉ tự hỏi nếu đó là nhiều kết nối đang gây ra vấn đề (có vẻ như câu trả lời của Ramesh) – Cameron

Trả lời

6

Hệ điều hành của bạn có số lượng giới hạn ổ cắm sẵn sàng mở. Khi bạn mở một ổ cắm và sau đó đóng nó, hệ điều hành không ngay lập tức đưa nó trở lại trong "có sẵn" hồ bơi, nó treo ra trong một thời gian trong "thời gian chờ đợi" nhà nước, rằng Nat đề cập đến in his answer.

Bạn có thể tăng số lượng ổ cắm hệ điều hành của mình sẽ mở, xem http://www.mongodb.org/display/DOCS/Too+Many+Open+Files (mỗi ổ cắm là một "tệp" mở).

Ngoài ra, bạn đang sử dụng phiên bản trình điều khiển khá cũ, bạn có thể muốn xem xét nâng cấp.

+0

Cảm ơn sự giúp đỡ! – Chrisui

3

Tôi xác nhận rằng đây là hành vi tương tự từ ruby ​​lái xe quá. Tôi đã sao chép trường hợp tương tự với ruby ​​mongo, chèn 20000 bản ghi bằng cách mở/đóng cá thể mongo mỗi lần. Và nó tiếp tục thất bại giữa 14110 đến 14200.

Đây là thông báo lỗi

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

đây là stack trace hoàn

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' 

Cũng như @Chrisui nói, i am cũng không gặp bất kỳ bộ nhớ nào rơi xuống.

Đây là kịch bản tôi đã cố gắng

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

benchmark của bạn không có ý nghĩa.Không tiếp tục mở/đóng kết nối. Bạn nên sử dụng lại kết nối liên tục thay vì mở/đóng mỗi lần. Nếu bạn mở và đóng ổ cắm một cách nhanh chóng, bạn sẽ có quá nhiều ổ cắm trong trạng thái chờ thời gian vẫn sử dụng các bộ mô tả tập tin

+0

Nó có ý nghĩa. Toàn bộ ý tưởng là chuẩn mực thời gian cần để mở một kết nối, làm điều gì đó và đóng lại. I E. Nhân rộng một yêu cầu nhanh chóng hàng ngàn lần. Bạn có thể giải thích "trạng thái chờ thời gian" này được không? – Chrisui

+0

xem http://stackoverflow.com/questions/1803566/what-is-the-cost-of-many-time-wait-on-the-server-side – Nat