Обработка сотен одновременных запросов в рельсах
Я пишу приложение ruby on rails, и одной из самых важных особенностей сайта является голосование в реальном времени. Мы полностью ожидаем, что мы получим 10 тысяч запросов на голосование всего за 1 минуту. Наряду с другими запросами это означает, что мы могли бы получить тонну запросов.
Моя первоначальная идея состоит в том, чтобы настроить сервер на использование apache + phusion, однако, для голосования, в частности, я думаю о написании php-скрипта на стороне и записи / считывании информации в memcached. Данные должны сохраняться только около 15 минут, поэтому запись в базу данных 10000 раз за 1 минуту кажется бессмысленной. Нам также нужно пометить ip пользователя, чтобы он не голосовал дважды, что усложняет работу в memcached.
Если у кого-то есть какие-либо предложения или идеи, чтобы сделать эту работу как можно лучше, пожалуйста, помогите.
1 ответ
Если вы разрабатываете приложение для такого массового притока, вам необходимо сократить его основные компоненты до абсолютного минимума.
Использование полного стека Rails для такой интенсивности не очень практично и не необходимо. Было бы гораздо лучше создать очень тонкий слой Rack, который будет обрабатывать голосование, делая прямые вызовы из БД, пропуская даже ORM, по сути являясь оберткой вокруг INSERT
заявление. В этом может помочь Синатра и Сиквел, которые служат эффективным генератором запросов.
Вы также должны быть уверены, что настроили свою базу данных должным образом, плюс запустите множество нагрузочных тестов, чтобы убедиться, что она работает должным образом, со здоровым запасом для более высокой загрузки.
Выполнение 10000 вызовов БД за минуту - это не проблема, каждый вызов займет всего лишь долю миллисекунды в правильно настроенном стеке. Memcached может предложить более высокую производительность, особенно если результаты не предназначены для того, чтобы быть постоянными. Memcached имеет атомарный инкрементный оператор, который именно то, что вы ищете, просто подсчитывая голоса. Redis также очень способный временный магазин.
Другая идея состоит в том, чтобы полностью удалить БД и написать постоянный процесс сервера, который говорит на простом протоколе на основе JSON. Eventmachine отлично подходит для объединения этих вещей, если вы привержены Ruby, как и NodeJS, если вы хотите создать специализированный подсчетный сервер на JavaScript.
10000 операций в минуту легко достижимо даже на скромном оборудовании, использующем специализированные серверные процессы без дополнительных затрат на полный стек БД.
Вам просто нужно быть уверенным, что ваша область очень хорошо определена, чтобы вы могли протестировать и жестоко злоупотребить своей реализацией перед ее развертыванием.
Поскольку то, что вы описываете, по сути является чем-то эквивалентным поиску хеша, основной код просто:
contest = @contest[contest_id]
unless (contest[:voted][ip])
contest[:voted][ip] = true
contest[:votes][entry_id] += 1
end
Выполнять это несколько сотен тысяч раз в секунду вполне практично, поэтому единственными издержками будет наложение вокруг него слоя JSON.