Как вы реагируете на отсутствие события в распределенной системе? - PullRequest
3 голосов
/ 28 апреля 2011

У меня есть система, которая собирает данные сеанса.Сеанс состоит из нескольких отдельных событий, например, «сессия запущена» и «действие Х выполнено».Невозможно определить, когда заканчивается сеанс, поэтому вместо этого события сердцебиения отправляются с регулярными интервалами.

Это главное осложнение: без способа определить, закончился ли сеанс, единственный способ - попытатьсяреагировать на отсутствие события, то есть не больше сердцебиения.Как я могу сделать это эффективно и правильно в распределенной системе?

Вот еще один фон для проблемы:

Затем события должны быть собраны в объекты, представляющие сеансы.Позднее объекты сеанса обновляются дополнительными данными из других систем, и в конечном итоге они используются для вычисления таких вещей, как количество сеансов, средняя продолжительность сеанса и т. Д.

Система должна масштабироваться горизонтально, поэтому имеется несколько серверовкоторые получают события, и несколько серверов, которые их обрабатывают.События, принадлежащие одному сеансу, могут отправляться и обрабатываться разными серверами.Это означает, что нет никакой гарантии, что они будут обработаны по порядку, и есть дополнительные сложности, которые означали, что события могут дублироваться (и всегда есть риск, что некоторые из них будут потеряны, либо до того, как они достигнут наших серверов, либо при обработке).

Большая часть этого уже существует, но у меня нет хорошего решения, как эффективно и правильно определить, когда сеанс закончился.Теперь я делаю это, периодически просматривая коллекцию «незавершенных» объектов сеанса, отыскивая объекты, которые не были обновлены, за промежуток времени, равный двум тактам, и перемещая их в другую коллекцию с помощью «завершенных» сеансов.Эта операция отнимает много времени и неэффективна, и она плохо масштабируется по горизонтали.По сути, она состоит из сортировки таблицы по столбцу, представляющему последнюю метку времени, и отфильтровывания любых строк, которые недостаточно стары.Звучит просто, но трудно распараллелить, и если вы будете делать это слишком часто, вы больше ничего не будете делать, база данных будет занята фильтрацией ваших данных, если вы не будете делать это достаточно часто, каждый запуск будет медленным, потому что естьслишком много для обработки.

Я бы хотел отреагировать на то, что сессия не была обновлена ​​какое-то время, а не опрашивать каждую сессию, чтобы узнать, обновлялась ли она.

Обновление: Просточтобы дать вам чувство масштаба;в любое время действуют сотни тысяч сессий, и в конечном итоге их будут миллионы.

Ответы [ 2 ]

2 голосов
/ 28 апреля 2011

Одна возможность, которая приходит на ум:

В вашей таблице базы данных, которая отслеживает сеансы, добавьте поле метки времени (если у вас его еще нет), которое записывает последний раз, когда сеанс был «активным». Обновляйте отметку времени всякий раз, когда вы получаете биение.

Когда вы создаете сеанс, запланируйте «событие таймера» для запуска после некоторой подходящей задержки, чтобы проверить, не истек ли сеанс. Когда происходит событие таймера, проверьте метку времени сеанса, чтобы увидеть, было ли больше активности в течение интервала ожидания таймера. Если это так, сеанс все еще активен, поэтому запланируйте другое событие таймера, чтобы проверить позже. Если нет, время сеанса истекло, поэтому удалите его.

Если вы используете этот подход, у каждого сеанса всегда будет один сервер, отвечающий за проверку того, истек ли он, но разные серверы могут отвечать за разные сеансы, поэтому рабочая нагрузка может быть распределена равномерно. Когда поступает пульс, не имеет значения, какой сервер его обрабатывает, потому что он просто обновляет временную метку в базе данных, которая (предположительно) используется всеми серверами.

По-прежнему существует некоторый опрос, поскольку вы будете получать периодические события таймера, которые заставят вас проверить, истек ли сеанс, даже если он еще не истек. Этого можно было бы избежать, если бы вы могли просто отменить ожидающее событие таймера каждый раз, когда поступает пульс, но с несколькими хитрыми серверами: сервер, который обрабатывает пульс, может быть не тем, на котором запланирован таймер. В любом случае, запрос к базе данных является легковесным: просто поиск одной строки (записи сеанса) по первичному ключу, без сортировки или сравнения неравенства.

0 голосов
/ 29 апреля 2011

Итак, вы собираете сердцебиение;Я задаюсь вопросом, мог ли бы у вас быть пакетный процесс (или что-то), который проходил бы по собранным пульсам в поисках паттернов, которые подразумевали конец сеанса.и как часто вы сканируете собранные сердцебиения.

Преимущество заключается в том, что вы обрабатываете все пульсы с помощью одного механизма (в одном месте - вам не нужно опрашивать каждый пульс самостоятельно), чтобы иметь возможность масштабирования - если это была база данныхориентированное решение, которое должно быть в состоянии справиться с большим количеством данных, верно?

Возможно, есть более элегантное решение, но мой мозг сейчас немного полон:)

...