Настройка приложения Rails 2.3.x на EC2 для легкой масштабируемости
Я запускаю простой стек рельсов на одной выделенной машине. Мы достигли своей полной мощности и у нас нет абсолютно никакой настройки для масштабирования, только одно приложение на одной машине. Я провел небольшое исследование и нашел потенциальный стек для масштабируемости. Я не профессиональный админ, но у меня есть несколько мыслей о том, что нам делать с EC2. Я все еще немного не уверен в совместном использовании файловой системы, вот где мой главный вопрос. Во-первых, вот с чем я имею дело.
Текущий стек:
- рельсы 2.3.11
- PostgreSQL
- пассажир + Nginx
- delayed_job
- сфинкс + думающий сфинкс
- imagemagick (тяжелая обработка изображений)
- Джексер (объясню)
Что делает наше приложение:
Наше приложение много загружает и обрабатывает изображения с помощью ImageMagick. Это также говорит с Jaxer для длинных преобразований холста в изображение. Все это в отложенной работе. Мы хотели бы убедиться, что этот материал может масштабироваться особенно. Итак, мы говорим о быстро растущих потребностях в хранилищах файлов и интенсивной обработке изображений в фоновых заданиях.
Мои решения пока:
- использовать резиновый камень для помощи в развертывании / администрировании
- перейти от delayed_job к redis/resque для упрощения разделения работников (клиент / сервер), нескольких очередей и веб-интерфейса sinatra
- иметь роли, такие как app, db, web, redis, resque, со всем сначала на одном экземпляре ec2, но вскоре разделить материал redis/resque на отдельный экземпляр и, возможно, еще больше
Вопросы:
Главный актуальный вопрос: что происходит со всеми файлами? Если я решу разделить роль приложения на несколько экземпляров, как мне получить доступ к общей файловой системе?
Кроме того, было бы здорово услышать некоторые мысли о моей настройке в целом.
1 ответ
Таким образом, большая часть того, что у вас есть, довольно просто масштабировать. PgSQL на свою собственную машину, чтобы уменьшить кучу ресурсов процессора / дискового ввода-вывода / памяти в качестве первого шага. Сфинкс тоже в свой маленький мир. Определенно переключитесь на resque, чтобы обеспечить легкое горизонтальное масштабирование ваших работников.
Но файлы... да, файлы сложные. Они всегда сложны. И ваши варианты опасно тонки.
Некоторые люди порекомендуют маршрут кластерной файловой системы, либо магическое сверхскопление (GFS2/OCFS2), либо вариант с немного более скудным поведением, например, GlusterFS. Я запустил много систем (более 1000), использующих GFS, и никогда, никогда не буду делать это снова. (Это может даже не работать в сети EC2, на самом деле). GFS2/OCFS2 - это путаница движущихся частей, которые недостаточно документированы, слишком усложнены и подвержены сбивающим с толку режимам отказа, которые просто создают проблемы простоя. Он также не работает, особенно в среде с интенсивной записью - он просто падает, разрушая весь ваш кластер и занимая 10-30 минут работы на уровне гуру, чтобы запустить его снова и снова. Избегайте этого, и ваша жизнь станет намного проще. Я никогда не запускал GlusterFS, но это потому, что меня это никогда особо не впечатляло. Все, что вы можете с этим сделать, обычно все равно есть лучший способ сделать это.
На мой взгляд, лучшим вариантом является почтенный NFS-сервер. Одна машина с большим (или не очень большим) томом EBS и работающим демоном NFS, и каждый монтирует его. У него есть свои ошибки (на самом деле это не файловая система POSIX, поэтому не рассматривайте ее как таковую), но для простой операции "я это исправил" в 99% случаев это неплохо. По крайней мере, это может стать временным промежутком, пока вы работаете над лучшим решением, которое...
Используйте свои знания о приложении, чтобы распределить хранилище. Именно такой подход я выбрал совсем недавно (масштабирующий Github), и он прекрасно работал. По сути, вместо того, чтобы рассматривать файловое хранилище как файловую систему, вы рассматриваете его как службу - предоставляете интеллектуальный API-интерфейс для частей приложения, использующих хранилище файлов, для выполнения того, что вам нужно. В вашем случае вам может понадобиться просто сохранять и извлекать изображения по заранее выделенным идентификаторам (например, PK для вашей таблицы "images" в БД). Для этого не нужна целая файловая система POSIX, просто нужна пара супероптимизированных HTTP-методов (POST должны обрабатываться динамически, но если вы действительно умны, вы можете заставить GET сойти с диска в виде статических файлов), Черт, вы, вероятно, предоставляете эти изображения прямо клиентам, поэтому отрежьте посредника и сделайте этот сервер общедоступным сервером ресурсов, пока вы на нем.
Рабочий процесс может быть примерно таким:
- Фронтенд-сервер получает изображение
- Помещает его в файловый сервер
- Добавляет работу для обработки изображения
- (С другой стороны, POST для файлового сервера заставляет его распознавать необходимость задания постобработки, и он сам создает задание)
- Работник получает работу по обработке изображений
- Получает изображение с файлового сервера
- Изображение процессов
- Отправляет обработанное изображение обратно на файловый сервер
- Веб-страница должна включать изображение в веб-страницу
- Записывает URL на сервер изображений в HTML
- веб-браузер идет и получает изображение напрямую
Вам не обязательно использовать HTTP POST для размещения изображений на сервере - например, Github общается со своими файловыми серверами, используя Git-over-SSH, который прекрасно работает для них. Ключ, однако, заключается в том, чтобы уделять больше внимания тому, где должна быть выполнена работа, и избегать ненужного использования ограниченных ресурсов (сетевой ввод-вывод для запроса NFS-сервера), вместо этого торгуя за более ограниченный набор вариантов использования ("Вы можете только запросите целые файлы атомарно!"), которые работают для вашего приложения.
Наконец, вам нужно учитывать фактор масштабируемости. Если вы используете интеллектуальный транспорт, однако, это легко - добавьте (небольшое количество) логику, необходимую для определения, с каким файловым сервером вам нужно общаться в каждом месте, которое обращается к файловому серверу, и вы в основном получаете бесконечную масштабируемость, В вашей ситуации вы можете понять, что ваш первый файловый сервер будет заполнен, скажем, 750 000 изображений. Итак, ваше правило "Поговорите с файловым сервером с именем хоста fs#{image_id / 750_000}
", который не трудно кодировать везде.
Я всегда веселилась с этой частью моей работы...