Ruby Postgresql PGconn.connect最多需要60秒才能初始化

时间:2016-10-09 00:40:54

标签: ruby-on-rails ruby performance postgresql startup

尝试在windows下做一些rails dev,我发现与postgres的初始连接最多需要60秒。我挖掘了activerecord postgresql适配器并在connect方法中添加了一些分析。

      require 'ruby-prof'
      GC::Profiler.enable
      GC.start
      RubyProf.start
      p @connection_parameters
      @connection = PGconn.connect(@connection_parameters)
      result = RubyProf.stop
      printer = RubyProf::FlatPrinter.new(result)
      printer.print(STDOUT)
      puts GC::Profiler.report
      STDOUT.flush

这给出了以下输出:

测量模式:wall_time     线程ID:7790520     光纤ID:7613460     总计:52.288858     排序方式:self_time

 %self      total      self      wait     child     calls  name
 99.94     52.258    52.257     0.000     0.001        1   PG::Connection#initialize
  0.06      0.031     0.031     0.000     0.000        1   Kernel#p
  0.00      0.001     0.001     0.000     0.000        1   Array#pop
  0.00      0.000     0.000     0.000     0.000        1   String#sub
  0.00      0.000     0.000     0.000     0.000        1   Array#each
  0.00      0.000     0.000     0.000     0.000        3   Symbol#to_s
  0.00      0.000     0.000     0.000     0.000        1   Hash#each
  0.00      0.000     0.000     0.000     0.000        1   Enumerable#map
  0.00      0.000     0.000     0.000     0.000        1   Hash#merge!
  0.00      0.000     0.000     0.000     0.000        1   Array#zip
  0.00      0.000     0.000     0.000     0.000        3   String#to_s
  0.00      0.000     0.000     0.000     0.000       36   Symbol#to_sym
  0.00      0.000     0.000     0.000     0.000        3   <Class::PG::Connection>#quote_connstr
  0.00      0.000     0.000     0.000     0.000        1   Enumerable#find
  0.00      0.000     0.000     0.000     0.000        1   Module#instance_methods
  0.00      0.000     0.000     0.000     0.000        3   String#gsub
  0.00      0.000     0.000     0.000     0.000        1   Kernel#is_a?
  0.00      0.000     0.000     0.000     0.000        1   Array#last
  0.00      0.001     0.000     0.000     0.001        1   <Class::PG::Connection>#parse_connect_args
  0.00      0.000     0.000     0.000     0.000        1   Array#join
  0.00     52.258     0.000     0.000    52.258        1   <Class::PG::Connection>#connect
  0.00      0.000     0.000     0.000     0.000        2   String#inspect
  0.00      0.000     0.000     0.000     0.000        2   Symbol#inspect
  0.00      0.000     0.000     0.000     0.000        1   Hash#inspect
  0.00      0.000     0.000     0.000     0.000        1   String#%
  0.00     52.289     0.000     0.000    52.289        1   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#connect

* indicates recursively called methods
GC 36 invokes.
Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC Time(ms)
    1              12.609             12175480             22293120               557328       125.00000000000000000000

如果我剥离其他所有内容并将确切的一些连接参数传递给PGconn.connect而不加载rails或任何其他库,我可以在2秒内连接:

$ time PGUSER=username PGPASSWORD=password ruby -rpg -rruby-prof -e "GC::Profiler.enable; GC.start; RubyProf.start; settings = {:host => 'localhost', :dbname => 'dbname_development'}; PGconn.connect(settings); r=RubyProf.stop; RubyProf::FlatPrinter.new(r).print(STDOUT); puts GC::Profiler.report; STDOUT.flush"
Measure Mode: wall_time
Thread ID: 20316120
Fiber ID: 20135520
Total: 2.675508
Sort by: self_time

 %self      total      self      wait     child     calls  name
100.00      2.676     2.676     0.000     0.000        1   PG::Connection#initialize
  0.00      0.000     0.000     0.000     0.000        1   String#sub
  0.00      0.000     0.000     0.000     0.000        3   String#to_s
  0.00      0.000     0.000     0.000     0.000        3   <Class::PG::Connection>#quote_connstr
  0.00      0.000     0.000     0.000     0.000        3   Symbol#to_s
  0.00      0.000     0.000     0.000     0.000        1   Hash#each
  0.00      0.000     0.000     0.000     0.000        1   Enumerable#map
  0.00      0.000     0.000     0.000     0.000        1   Hash#merge!
  0.00      0.000     0.000     0.000     0.000        1   Array#zip
  0.00      0.000     0.000     0.000     0.000        3   String#gsub
  0.00      0.000     0.000     0.000     0.000       46   Symbol#to_sym
  0.00      0.000     0.000     0.000     0.000        1   Array#each
  0.00      0.000     0.000     0.000     0.000        1   Enumerable#find
  0.00      0.000     0.000     0.000     0.000        1   Module#instance_methods
  0.00      0.000     0.000     0.000     0.000        1   Array#pop
  0.00      0.000     0.000     0.000     0.000        1   Kernel#is_a?
  0.00      0.000     0.000     0.000     0.000        1   Array#last
  0.00      0.000     0.000     0.000     0.000        1   <Class::PG::Connection>#parse_connect_args
  0.00      0.000     0.000     0.000     0.000        1   Array#join
  0.00      2.676     0.000     0.000     2.676        1   <Class::PG::Connection>#connect

* indicates recursively called methods
GC 14 invokes.
Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC Time(ms)
    1               0.562               895840              1338240                33456        15.62500000000000000000


real    0m3.795s
user    0m0.015s
sys     0m0.046s

随着我添加更多需要的库,连接时间增加。我认为包含本机组件的库可能会产生更大的影响,但不是100%。它使用了更多的内存,但没有达到交换,GC的时间也不多。

关于哪个兔子洞要进一步调查的任何指示?

正在运行的版本:

$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x64-mingw32]

$ gem list pg --local
pg (0.19.0 x64-mingw32)

0 个答案:

没有答案