Попинайте архитектуру
От: dmz Россия  
Дата: 01.11.07 11:41
Оценка:
Начальные условия

1) Есть http сервер, который является специфичным поисковым движком. В ответ на запрос он либо ищет в своей базе и выдает результат, либо обращается по HTTP к третьим сайтам (большое количество, могут тормозить, могут падать и т.п.), переадресует запрос им, собирает данные, парсит, кладет в базу, отдает пользователю

2) Результаты отдаются асинхронно, при помощи xmlhttprequest, в JSON и сортируются на клиенте (их относительно немного, десятки записей)

3) требуется обеспечить хорошую масштабируемость

Решение

Компоненты

1) Веб сервер — легкий веб-сервер (lighttpd или nginx) + fcgi приложение
2) Бекенд — отдельный демон, содержит очередь запросов и пул потоков-исполнителей
3) Диспетчер
4) База

1. Основной сценарий

1) Клиент делает HTTP запрос на поиск
2) Сервер переадресовывает запрос бекенду (какой-нибудь легкий RPC)
3) Бекенд генерирует уникальный JOB ID, отдает его серверу, ставит задание в очередь, отваливается
4) Бекенд добавляет N-количество отложенных (deferred) потоков (одновременно активно только K потоков, K — размер тредпула) исполнителей
5) Потоки исполнители лезут в базу, смотрят наличие и актуальность запрошенных данных, если нашли — пишут в очередь результатов для данного JOB ID (хэш потокобезопасных очередей), если не нашли — выполняют запрос к третьим сайтам, получают результаты, пишут в базу, отваливаются (или отваливаются по таймауту)
6) клиент периодически обращается к серверу за порцией результатов, передает JOB ID
7) сервер пытается забрать результаты у бекенда, если в очереди результатов что-то есть — отдает
8) Если все потоки отработали (допустим, храним счетчик активных задач по данному JOB ID) — то прибиваем очередь
9) Если очередь пустая — то сервер посылает клиенту скрипт, который удаляет обработчик таймера и обнуляет на клиенте JOB ID
10) клиент получает данные в JSON, добавляет их в таблицу, сортирует по заданному параметру

2. Сборка мусора

1) Работает поток, который проверяет время последнего обращения для каждого JOB-а, если интервал превышает некий таймаут — то прибивает все треды-исполнители и очередь результатов (это означает, что клиент отвалился)

либо

2) при добавлении нового задания сначала находим и убиваем просроченные задания

3. Масштабируемость

Бекенды могут быть подняты на разных серверах и смотреть в разные базы, которые реплицируются между собой (подходит и master-master и master-slave)

Бекенды стейтлесс

В случае многих бекендов существует диспетчер (библиотека, которая смотрит во что-нибудь быстрое, типа memcached или любая in-memory база) который привязывает JOB ID к конкретному бекенду и переадресует ему запрос

4. Реализация
Бекен: python + twisted, база: PostgreSQL, RPC: twisted spread


Чем плохо? Есть засады, которые я проглядел?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.