Я разрабатываю серверный демон для проекта, который должен принимать большое количество одновременных запросов и обрабатывать их асинхронно.Я знаю о масштабности такого проекта, но я серьезно к этому отношусь и пытаюсь составить четкий план и план, прежде чем идти дальше.
Вот список моих целей:
- Масштабируемость - должна иметь возможность распараллеливать архитектуру на нескольких процессорах или даже на нескольких серверах.
- Способность справляться с огромным количеством параллельных соединений.
- Не должна вызывать блокировкупроблемы, если обработка одного запроса занимает много времени.
- Время обработки запроса должно быть минимальным.
- Построен на основе .NET Framework (будет писать это в C #)
Моя предложенная архитектура и процесс довольно сложны, поэтому вот диаграмма моего начального дизайна:
(и здесь это на tinypic на случай, если он плохо изменяет размер)
Идея состоит в том, что запросы поступают через сеть (хотя я еще не решил, будет ли лучше использовать TCP или UDP) и сразу же передаются высокоскоростной загрузке.балансировкаэ.Затем балансировщик нагрузки выбирает очередь запросов (RQ) для размещения запроса, используя генератор взвешенных случайных чисел.Веса выводятся из размера каждой очереди.Причина использования взвешенного ГСЧ, а не просто помещения запросов в наименее загруженную очередь, заключается в том, что она предотвращает блокировку всего сервера пустой, но заблокированной очередью (из-за зависшего запроса).Если все RQ превышают определенный размер, балансировщик нагрузки отбрасывает запрос и помещает ответ «сервер слишком занят» в очередь вывода (OPQ) - эта часть не показана на диаграмме .
Каждая очередь соответствует потоку, сходство которого установлено на одно ядро ЦП на сервере.Эти потоки являются частью параллельного процессора запросов, который потребляет запросы из каждой очереди.Запросы подразделяются на три типа:
Немедленно - Немедленные запросы, как следует из названия, обрабатываются немедленно.
Отложенный - Отложенные запросы считаются низко приоритетными.Они обрабатываются немедленно во время низкой нагрузки или помещаются в очередь отложенных запросов (DRQ), если нагрузка высокая.Балансировщик нагрузки извлекает эти отложенные запросы из DRQ, отмечает их как немедленные, а затем помещает обратно в соответствующие RQ.
Timed - синхронизированные запросы помещаются вочередь запросов по времени (TRQ) вместе с их целевой меткой времени.Эти запросы часто генерируются в результате другого запроса, а не отправляются явно клиентом.При превышении отметки времени запроса следующий доступный поток процессора запросов использует ее и обрабатывает.
Когда запрос обрабатывается, данные могут быть получены из кэша пар ключ / значение в памятикеш пары ключ / значение либо на диске, либо с выделенного сервера баз данных SQL.Кэшированные значения будут BSON, а индекс будет строкой.Я имею в виду использование Dictionary<T1,T2>
для реализации этого в памяти и btree (или аналогичного) для дискового кэша.
Ответ создается по завершении обработки и помещается в очередь вывода(OPQ).Затем цикл принимает ответы от OPQ и передает их клиенту по сети.Если OPQ достигает 80% своего максимального размера, одна четверть потоков процессора запросов останавливается.Если OPQ достигает 90% своего максимального размера, половина потоков процессора запросов останавливается.Если OPQ достигает своего максимального размера, все потоки процессора запросов останавливаются.Это будет достигнуто с помощью семафора, который также должен предотвращать блокировку потоков отдельных запросов и оставление устаревших запросов.
Мне нужны предложения по нескольким областям:
- Есть ли какие-то серьезные недостатки в этой архитектуре, которые я пропустил?
- Что-то, что я должен рассмотреть, чтобы изменить по соображениям производительности?
- Будет ли TCP или UDP более подходящим для запросов?Было бы очень полезно иметь «доказательство доставки», которое предлагает TCP, но привлекательный характер UDP тоже привлекателен.
- Есть ли какие-то особые соображения, о которых мне следует подумать при работе с одновременными соединениями 100k +на сервере Windows?Я знаю, что стек TCP Linux хорошо работает, но я не очень уверен в Windows.
- Есть ли еще вопросы, которые я должен задать?Я забыл обдумать что-нибудь?
Я знаю, что это было много, чтобы прочитать, и, вероятно, довольно много, чтобы спросить тоже, так что спасибо за ваше время.* Обновленная версия диаграммы здесь .