У меня есть небольшой маленький рубиновый скрипт, в котором записано более 80 000 записей.
Загрузка процессора и памяти для каждой записи меньше, чем шары smurf, но для прохождения всех записей все равно требуется около 8 минут.В Ruby можно ли подключать базу данных по потокам?
Я бы хотел использовать потоки, но когда я дал это, у моего db закончились соединения. Конечно, это было, когда я попытался подключиться 200 раз, и действительно я мог бы ограничить это лучше, чем это. Но когда я нажимаю этот код до Героку (где у меня есть 20 связей для всех рабочих, чтобы поделиться), я не хотите случайно заблокировать другие процессы, потому что это ускорилось.
Я думал о рефакторинге кода, чтобы он соединил весь SQL, но это будет действительно очень грязно.
Так что мне интересно, есть ли трюк, позволяющий потокам обмениваться ссылками? Учитывая, что я не ожидаю, что переменная соединения изменится во время обработки, я действительно удивлен тем, что вилке потока необходимо создать новое соединение с БД.
Ну любая помощь будет супер круто (как и я) .. спасибо
SUPER надуманный Пример
Ниже 100% надуманный пример. Это показывает проблему.
Я использую ActiveRecord внутри очень простой темы. Кажется, каждый поток создает собственное подключение к базе данных. Я основываю это предположение на следующем предупреждающем сообщении.
START_TIME = Time.now
require 'rubygems'
require 'erb'
require "active_record"
@environment = 'development'
@dbconfig = YAML.load(ERB.new(File.read('config/database.yml')).result)
ActiveRecord::Base.establish_connection @dbconfig[@environment]
class Product < ActiveRecord::Base; end
ids = Product.pluck(:id)
p "after pluck #{Time.now.to_f - START_TIME.to_f}"
threads = [];
ids.each do |id|
threads << Thread.new {Product.where(:id => id).update_all(:product_status_id => 99); }
if(threads.size > 4)
threads.each(&:join)
threads = []
p "after thread join #{Time.now.to_f - START_TIME.to_f}"
end
end
p "#{Time.now.to_f - START_TIME.to_f}"
ВЫВОД
"after pluck 0.6663269996643066"
DEPRECATION WARNING: Database connections will not be closed automatically, please close your
database connection at the end of the thread by calling `close` on your
connection. For example: ActiveRecord::Base.connection.close
. (called from mon_synchronize at /Users/davidrawk/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/monitor.rb:211)
.....
"after thread join 5.7263710498809814" #THIS HAPPENS AFTER THE FIRST JOIN.
.....
"after thread join 10.743254899978638" #THIS HAPPENS AFTER THE SECOND JOIN
«Я думал о рефакторинге кода» - я подозреваю, что вам действительно понадобится - 80 000 запросов БД, как вы подразумеваете, будут медленными, что бы вы ни делали. Можете ли вы показать код? –
Если вы используете ActiveRecord, то он уже доступен. – pguardiario
Медленно все о перспективах. :) 80 000 за 8 минут было бы хорошо, если бы я не строил систему, чтобы обрабатывать пару миллионов. К сожалению, в коде нет ничего особенного. Просто небольшой скрипт для подключения и обновления записей. – baash05