Заранее извиняюсь за большой текст, но уж больно много вопросов стоит. Буду очень признателен, если хотя бы на часть вопросов получу ответ.
Постановка задачи
Есть WEB-сайт с большим количеством посетителей (написан с использованием ZOPE). Есть отдельный сервер, на котором должна крутиться программа (которую нужно написать), которая выдает некоторую информацию из БД посетителям сайта. Решено разместить эту программу на отдельном сервере из-за соображений масштабируемости/отказоустойчивости. К программе предъявляются высокие требования по производительности, она должна обслуживать около 200 запросов в секунду. Поскольку информация из БД обновляется относительно редко, то при каждом запросе клиента обращаться к БД нет надобности (да и не получилось бы при таких требованиях к производительности), т.е. информация из БД должна загружаться по мере обновления и сидеть где-то в памяти. Платформа, на которой будет стоять программа, — Linux (пока не решено какой, но в принципе без разницы), БД – MySQL (это уже точно). Язык программирования – С++.
Мое видение решения
Программа представляет собой постоянно запущенный демон. Демон прослушивает какой-либо TCP порт. На сайте, при заходе клиента создается сокет, который посылает определенный сигнал с параметрами запроса на машину с демоном. Демон получает параметры запроса, создает отдельный поток, в котором обрабатывается запрос и выдается результат клиенту. Кроме того, при обновлении БД в режиме on-line демону будут посылаться специальные запросы с требованием обновить кэш в памяти (либо всю информацию, либо только часть). Эти запросы будут посылаться с использованием тех же сокетов. Кэш в памяти должен обновляться без прерывания нормальной работы программы.
Вопросы 1. Общая архитектура системы
Как по вашему мнению, способна такая архитектура (сокеты+потоки) обеспечить требуемую производительность (200 запросов в секунду)? Может какую-нибудь CORBA использовать?
2. Требования к аппаратной части
Нужны ли какие-то особые аппаратные ресурсы для данной архитектуры (например, что-то вроде этого: «для поддержки 200 сокетов одновременно нужно как минимум 1 Гб RAM»)?
3. Требования к программной среде
Есть ли какая-то определенная ОС *nix (возможно платная), на которой именно эта архитектура работала бы наиболее оптимизировано? Например, я слышал, что в некоторых ОС потоки и сокеты работаю более оптимизировано.
4. Требования к системе разработки
Поскольку я до этого писал в основном только для Win-платформ, то хотелось бы писать код на Win2K, в Visual Studio, а окончательно компилировать его уже на Linux. В связи с этим вопрос: можно ли программу для Unix написать и получить какой-то промежуточный build целиком на Win-платформе (хотя бы для проверки ошибок компиляции), учитывая то, что в программе используются Linux-специфичные операторы? Рассмотрим к примеру fork для функционирования в режиме демона. Понятно, что ни о каком fork-е Windows и не слышал, и при компиляции ругнется, но может можно как-то переписать заголовочные файлы с Linux на Windows, или же как-то написать какие-то заглушки (а может уже готовые есть)? Или же лучше писать код сразу на Linux?
5. Выбор среды разработки, если писать код на Linux машине
Пока смотрю в сторону Anjuta. Возможно посоветуете другую среду?
Обязательные требования:
— Бесплатна
— Поддержка проектов (чтобы из множества с-файлов получить один исполняемый без возни с параметрами g++)
— Пошаговый отладчик
— Автозаполнение и подсвечивания кода
— Простота освоения (есть ограничения по времени разработки)
Желательные требования:
— Механизм автодокументирования кода
— Отсутствие в необходимости дополнительно ставить на Linux какую-либо GUI подсистему (KDE, GNOM и т.п.)
6. Механизм взаимодействия Web-сервера и демона
Пока остановился на механизме сокетов, с точки зрения производительности демона этот выбор оправдан? Какие еще есть механизмы взаимодействия двух программ на разных компьютерах (на обоих Linux)?
7. Выбор протокола обмена информацией между Web-сервером и демоном
Остановился на TCP-соединениях, по идее UDP протокол быстрее работать должен, из-за отсутствии относительно долгого этапа установления соединения, может использовать UDP?
8. Механизм распараллелирования обработки запросов
После получения запроса демон создает отдельный поток для обработки каждого запроса. Не будет ли проблем с производительностью при наличии одновременно 200 выполняющихся потоков? Как лучше организовать многопоточность: каждый раз создавать новый или как-то использовать существующие неиспользованные (т.е. использовать пул потоков)? Какие механизмы реализации многопоточности наиболее эффективны?
9. Управление демоном
Какими механизмами можно управлять демоном, т.е., например, если потребуется перезагрузить демон, как это лучше сделать, чтобы демон знал, что его перегружают и успел сохранить свои несохраненные данные?
10. Реализация кэша с данными в памяти
Предполагается хранить около десяти небольших по объему таблиц БД в памяти. Как это реализовать хранение, с помощью массивов/списков? Есть ли наиболее эффективные с точки зрения производительности динамические массивы в с++? Где лучше расположить кэш, я слышал, что есть какая-то «Shared Memory», надо располагать его там? Или может просто обойтись одним классом-синглетоном?
11. Механизмы блокировки данных кэша при многопоточности
Есть ли какие-либо встроенные механизмы блокировок в *nix-ах (как, например, mutex-ы в Win32)? Как наиболее эффективно организовать блокировку данных при многопоточности?
12. Пример такого рода программы
Желательно не приводить код какого-либо монстра типа Apache, а увидеть что-нибудь небольшое, чтобы можно было легко разобраться, реализирующее какие-либо части из представленных вопросов.
Просто замечание
имхо, при тех нагрузках которые ты планируешь написание демона частично дублирующего функционал СУБД абсолютно бесполезно.
MySQL и так "неплохо" разогнан — http://www.mysql.com/it-resources/benchmarks/eweek.html — первая ссылка из гугл(mysql benchmarks)
JJO>имхо, при тех нагрузках которые ты планируешь написание демона частично дублирующего функционал СУБД абсолютно бесполезно. JJO>MySQL и так "неплохо" разогнан — http://www.mysql.com/it-resources/benchmarks/eweek.html — первая ссылка из гугл(mysql benchmarks)
Дело в том, что только на соединение с БД уходит уйму времени, к тому же никаких сложных операций в демоне делать не нужно, фактически дублируется только несколько SELECT-ов
Здравствуйте, xdfvjm, Вы писали:
X>Заранее извиняюсь за большой текст, но уж больно много вопросов стоит. Буду очень признателен, если хотя бы на часть вопросов получу ответ.
> Дело в том, что только на соединение с БД уходит уйму времени, к тому же > никаких сложных операций в демоне делать не нужно, фактически дублируется > только несколько SELECT-ов
Держи пул соединений с БД. 200 запросов в секунду — это действительно не так
много
Тебе уже советовали смотреть на что-то кэширующее.
IMHO это правильный путь.
Попробуй поискать в google IMDB (in memory data base).
Собственно, если ты найдешь приемлемый для тебя вариант,
то он будет "архитектурообразующим" и большая часть заданных
вопросов отпадет.
Да, действительно, 200 _простых_ запросов в секунду это немного,
но только при условии, что на базу нет никакой другой нагрузки и
дальнейший рост не планируется.
Re: Помогите с проектированием программы
От:
Аноним
Дата:
31.03.05 17:16
Оценка:
X>4. Требования к системе разработки
Лучше сразу на Linux — есть ещё множество специфики, которую на Win-платформе невозможно учесть. А на прописывание "заглушек"/"аналогов" в хидерах уйдет немало времени и головной боли.
X>5. Выбор среды разработки, если писать код на Linux машине X>Пока смотрю в сторону Anjuta. Возможно посоветуете другую среду?
KDevelop последний. Лучше сvs-версию. Очень взрослая вещь, намного мощней Анюты. Из перечисленных требований есть все. Единственное — завязан на KDE-библиотеках(но это не значит, что необходимо работать в KDE!).
X>6. Механизм взаимодействия Web-сервера и демона X>Пока остановился на механизме сокетов, с точки зрения производительности демона этот выбор оправдан? Какие еще есть механизмы взаимодействия двух программ на разных компьютерах (на обоих Linux)?
Имхо сокеты — единственный подходящий метод . Но реализовывать их можно по разному. Очень рекомендую достать книгу Стивенса "UNIX. Разработка сетевых приложений". Не пугайся размера, всю читать не обязательно — но там ты найдешь оптимальный способ реализации сетевой части для твоей задачи.
X>7. Выбор протокола обмена информацией между Web-сервером и демоном X>Остановился на TCP-соединениях, по идее UDP протокол быстрее работать должен, из-за отсутствии относительно долгого этапа установления соединения, может использовать UDP?
Имхо, TCP лучше во-первых из-за надежности доставки пакетов, а во-вторых из-за того, что лучше держать соединение — ведь веб-сервер должен получать ответ. Установил соединение, послал запрос, подождал ответ, закрыл соединение. А при UDP придется ещё и распознавать кто кому что послал, помечать запросы, проверять доставку пакета и тп. Тоесть вряд ли это оправдает лишние три пакета хендшейкинга в TCP
X>9. Управление демоном X>Какими механизмами можно управлять демоном, т.е., например, если потребуется перезагрузить демон, как это лучше сделать, чтобы демон знал, что его перегружают и успел сохранить свои несохраненные данные?
Управлять с web-сервера или вообще? Если речь идет о локальном управлении, то обычно такое делается путем перехвата сигналов. Ну а если с веб-сервера — то пусть парсит команды, и реагирует соответственно на команду перезагрузки
X>11. Механизмы блокировки данных кэша при многопоточности X>Есть ли какие-либо встроенные механизмы блокировок в *nix-ах (как, например, mutex-ы в Win32)? Как наиболее эффективно организовать блокировку данных при многопоточности?
Опять-же — ещё одна хорошая книга Стивенса "UNIX. Взаимодействие процессов.". Это, как говорится, The One True Book по сетевому и IPC программированию.
Книги тебе скорее всего таки придется взять Их выпускает издательство "Питер", серия "Мастер-Класс".
Здравствуйте, xdfvjm, Вы писали:
X>Заранее извиняюсь за большой текст, но уж больно много вопросов стоит. Буду очень признателен, если хотя бы на часть вопросов получу ответ.
Да ниче . Я вот тоже с подобной проблемой возился недавно...
X>Постановка задачи X>... К программе предъявляются высокие требования по производительности, она должна обслуживать около 200 запросов в секунду. Поскольку информация из БД обновляется относительно редко, то при каждом запросе клиента обращаться к БД нет надобности (да и не получилось бы при таких требованиях к производительности), т.е. информация из БД должна загружаться по мере обновления и сидеть где-то в памяти. Платформа, на которой будет стоять программа, — Linux (пока не решено какой, но в принципе без разницы), БД – MySQL (это уже точно). Язык программирования – С++.
Посмотри вот здесь. Может подойдет для кеширующей БД.
Is the WEB API implementation pretty stable?
It was implemented long time ago and have used by a number of users. So I thought that it is stable enough. Certainly its reliability, flexibility, stability can not be compared with real HTTP Servers (such as Apache). But it provides convenient API with GigaBASE, so if you are not going to implement Web portal which should serve 1000 requests per second, I think WWWApi+GigaBASE is good choice.
X>5. Выбор среды разработки, если писать код на Linux машине
Тут я не оригинален . Я использую Xemacs. По этому ничего советовать не буду
X>6. Механизм взаимодействия Web-сервера и демона X>Пока остановился на механизме сокетов, с точки зрения производительности демона этот выбор оправдан? Какие еще есть механизмы взаимодействия двух программ на разных компьютерах (на обоих Linux)?
Может лучше кеширующий демон локально вывесить? Т.е. на каждом вебе (когда их будет много) есть локальный кеш который по shared memory отдает данные? Или через FastDB. Это будет в разы быстрее чем городить огород с удаленным коннектом (не забываем он SYN/SACK/ACK/Send/Recv/...). Эффективнее будет, если кэш будет по требованию ходить в базу и забирать что надо, а запросы будут выполняться локально.
X>7. Выбор протокола обмена информацией между Web-сервером и демоном X>Остановился на TCP-соединениях, по идее UDP протокол быстрее работать должен, из-за отсутствии относительно долгого этапа установления соединения, может использовать UDP?
Shared memory/FastDB и никаких сокетов... Лишний гимморой.
X>8. Механизм распараллелирования обработки запросов X>После получения запроса демон создает отдельный поток для обработки каждого запроса. Не будет ли проблем с производительностью при наличии одновременно 200 выполняющихся потоков? Как лучше организовать многопоточность: каждый раз создавать новый или как-то использовать существующие неиспользованные (т.е. использовать пул потоков)? Какие механизмы реализации многопоточности наиболее эффективны?
Тут честно не понял нафиг? Т.е. это уже не просто кеширующий демон, а целый сервер приложений? Тогда может он и нафиг не нужен? Базу все-таки не дураки писали... сам будешь очень долго ваять и оптимизировать. Да и зачем?
X>10. Реализация кэша с данными в памяти
Выше ссылку давал.
Здравствуйте, aka50, Вы писали:
X>>7. Выбор протокола обмена информацией между Web-сервером и демоном X>>Остановился на TCP-соединениях, по идее UDP протокол быстрее работать должен, из-за отсутствии относительно долгого этапа установления соединения, может использовать UDP? A>Shared memory/FastDB и никаких сокетов... Лишний гимморой.
Демон в постановке задачи находится на отдельном сервере. Shared memory не подходит .
Здравствуйте, divan0, Вы писали:
D>Здравствуйте, aka50, Вы писали:
X>>>7. Выбор протокола обмена информацией между Web-сервером и демоном X>>>Остановился на TCP-соединениях, по идее UDP протокол быстрее работать должен, из-за отсутствии относительно долгого этапа установления соединения, может использовать UDP? A>>Shared memory/FastDB и никаких сокетов... Лишний гимморой. D>Демон в постановке задачи находится на отдельном сервере. Shared memory не подходит .
Я просто не уточнил. Это немного другой вариант исполнения:
1. Кеширующий демон с вебом на одном сервере
2. База данных на другом.
3. Демон самостоятельно забирает кешируемые данные используя Mysql клиента.
4. Веб забирает данные через Shared Memory.(ну или любой другой локальный метод вплоть до тех же сокетов)
Какие плюсы:
1. Запросы кешируемых данный забираются демоном по готовому протоколу (достаточно шустрому).
2. Кешируемые запросы не гоняются по сети. Кол-во веб серверов может быть большим, при этом
до некоторого предела будет достаточно одного Mysql сервера.
3. Защита от сбоев:
а) упал демон, перестал отвечать один из веб серверов, а не все сразу.
б) упал линк до базы, будут некоторое время отдаваться старые данные (если
это конечно возможно для данной задачи)
в) недоступен сервер MySQL, аналогично б)
г) безопасность: ничего велосипедного не торчит из серверов. Только MySQL порт из серевера БД.
Минусы:
1. Веб сервера требуют больше памяти, чем если бы кеш жил на отдельном сервере. Но память нынче дешева .
2. Синхронизация кешей. Т.е. если используется кросссайтинг, то могут возникнуть проблемы (например по ссылке
с одного сервера клиент отправляется на другой сервер. Но на том сервере данные еще не обновились и клиент не
сможет получить информацию соответсвующую запрошенной ссылке.