1

나는 생산의 문제를 이해하는 실험을하고있어, 그래서 시험에 DEV에서 컨트롤러의 액션 내부의이 조각을 던져했습니다 예상대로이러한 스레드 ActiveRecord 쿼리가 동시에 실행되지 않는 이유는 무엇입니까?

start = Time.now 
num_threads = 6 
results = Queue.new 
saved_results = [] 
threads = [] 
connections = [] 
semaphore = Mutex.new 

# start threads 
(1..num_threads).each do |i| 
    threads << Thread.new do 
    #semaphore.synchronize { connections << ActiveRecord::Base.connection } # for cleanup? 

    #ActiveRecord::Base.connection.execute("select sleep(1.6);") # runs sequentially 
    sleep(1.6)             # runs concurrently 
    result = User.find_by_id(i) 
    results << [i, result] 
    end 
end 

# end option 1 - let everyone finish 
threads.each(&:join) 

# end option 2 - simulate early exit condition 
#while saved_results.count < 3 do saved_results << results.pop end 
#threads.each(&:exit) 

# cleanup/close open connections? 
#connections.select(&:active?).each(&:disconnect!) 

elapsed = Time.now - start 
render :text => [ elapsed.to_s, saved_results.size, results.size ].join(", ") 

sleep(1.6)는 약 1.6 초를 실행합니다.

그러나 ActiveRecord select sleep(1.6);은 각 스레드 *마다 독립적 인 연결이 열려 있음을 표시하는 show processlist;이라는 mysql 콘솔에도 불구하고 6 * 1.6 = 9.6 초가 걸립니다.

무슨 일 이니? ActiveRecord 쿼리가 동시에 실행되지 않는 이유는 무엇입니까? 프로덕션 콘솔에서도이 기능을 경험했습니다.

config.threadsafe!config/environment.rb으로 설정되어 있습니다. 중요한 경우 레일즈 2.3을 사용하고 있습니다.

* 이러한 연결은 수동으로 닫아야합니까? 프로덕션에는 항상 열려있는 연결이 많아 아무 것도하지 않아서 Mysql::Error: Too many connections이 발생합니다. 아마도이 문제를 다른 질문으로 제출할 것입니다.

답변

0

일부 발언 :

  • 2.3 자체를 레일 자체 AFAIK 정말 스레드, 그것이 레일 3.X 이후입니다. 그러나이 경우에는별로 중요하지 않습니다.
  • 적어도 루비 1.9를 사용해야합니다. 1.8의 "녹색 스레드"는 최적보다 적습니다. 루비 1.9에서 밟는 것이 여전히 최적이 아니라면 더 좋습니다. 실 스레딩의 경우 jruby 또는 rubinius (GIL 없음)를 확인해야합니다.
  • mysql2 보석을 사용해야합니다. mysql gem은 데이터베이스에서 응답을 기다리는 동안 GIL을 유지합니다.
+0

mysql2로 테스트 한 결과이 예제가 효과적이었습니다. 나는 최근에 또 다른 반 관련 문제를 보았습니다 : http://stackoverflow.com/questions/26001994 mysql2를 사용하면 도움이되지 않았습니다. – Kache

관련 문제