Как спроектировать и протестировать _lots_ параллельных данных в рельсах? - PullRequest
0 голосов
/ 29 января 2011

Стеки приветствия.

Мы работаем над проектом, который хранит данные отслеживания за секунду для участников психологических экспериментов.В нашем текущем проекте есть Flash-клиент, который собирает пары меток времени / активности за 60 секунд, а затем отправляет данные в виде строк вместе с небольшими метаданными участника в наше приложение rails (3.0.3) / MySQL (5.1). Редактировать Мы используем vanilla Passenger / Nginx для передней панели.Rails разбивает строки меток времени / активности на параллельные массивы, генерирует один необработанный оператор вставки SQL и затем помещает все в массивную таблицу, а именно: (упрощенный код)

@feedback_data = params[:feedbackValues].split(",")
@feedback_times = params[:feedbackTimes].split(",")
inserts = []
base = "(" + @userid + "," + @studyid + ","
@feedback_data.each_with_index do |e,i|
  record = base + @feedback_times[i].to_s + ","
  record += "'" + @feedback_data[i].to_s + "')"
  inserts.push(record)
end
sql = "INSERT INTO excitement_datas (participantId, studyId, timestamp, activityLevel) VALUES #{inserts.join(", ")}"
ActiveRecord::Base.connection.execute sql

Выход:

INSERT INTO STUDY_DATA (participantId, studyId, timestamp, activityLevel)
VALUES (3,5,2011-01-27 05:02:21,47),(3,5,2011-01-27 05:02:22,56),etc.

Дизайн вызвал много споров в команде.Исследования будут иметь 10 или 100 участников одновременно.Я перешагнул 60-секундный интервал POST для каждого клиента, чтобы входящие данные распределялись более равномерно, но я все еще получаю множество предсказаний об унынии и мраке.

Что еще мы можем сделать / мы должны сделать, чтобы улучшить масштабируемость этого проекта в рельсах?

Какие инструменты / методы я могу использовать, чтобы точно предсказать, как это работает под нагрузкой?

Большое спасибо.

1 Ответ

1 голос
/ 29 января 2011

Это скорее проблема архитектуры, чем проблема кода. Ваш код выглядит вменяемым, и генерация только одного SQL-запроса является хорошим подходом. Однако какой у вас сервер приложений?

Если вы используете, скажем, один тонкий сервер, то запросы будут блокироваться, пока база данных выполняет SQL-запрос, что приводит к не отвечающему приложению.

Используя Passenger или Unicorn, вы получите увеличение параллелизма, но все еще довольно медленные SQL-запросы на запрос.

Если вы действительно беспокоитесь об этом запросе, вы можете попробовать промежуточный слой Memcache или RabbitMQ, который сохраняет задание для каждого из полученных запросов. Затем задайте фоновое задание (или многие из них) и выполните медленную вставку. Memcache и Rabbit более отзывчивы, чем Mysql, и вы имеете дело с необработанным запросом.

Это означает, что запрос будет выполнен очень быстро и перенесет тяжелую работу на ваши рабочие задачи. Задержанное задание может быть чем-то, на что можно посмотреть, или Workling, или Bunny / EventMachine for Rabbit.

Сохранение Memcache может быть проблемой для вас, поэтому я бы порекомендовал Rabbit, если вам нравится подход, основанный на очереди.

Кроме того, вы можете посмотреть на Apache Bench, чтобы увидеть, как вы на самом деле уже делаете:

http://httpd.apache.org/docs/2.0/programs/ab.html

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