Есть ли шаблон проектирования для работы с большими наборами данных через Интернет?

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

Ограничения:

  1. Клиентская сторона для этого пишется на Silverlight.
  2. Сами объекты не очень большие (около 15 свойств типа значений и строк), но запрос всех данных стоит дорого. Примерно 15 свойств содержат данные из различных источников; никакая умная инструкция соединения или индексация не ускорит запрос. Я думаю о заполнении только подмножества свойств при начальной загрузке, а затем заполнении более дорогих деталей, когда пользователь приближает данную группу объектов. Подумайте о картах Google, но вместо улиц и зданий он показывает объекты.
  3. Я смогу ограничить часть из тысяч обновляемых объектов. Однако мне нужно, чтобы пользователь имел возможность «уменьшать масштаб» контекста, который позволяет выполнять гранулярное обновление до того, который отображает все тысячи объектов. Я предполагаю, что обновление будет снова отключено для объектов, когда они оставят достаточный контекст масштабирования.

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

Изменить:

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

  1. Загрузка большого количества записей через Интернет (~ 5к).
  2. Поддержание актуальности подмножества этих объектов (~ 500) через Интернет.

Есть несколько шаблонов проектирования, которые можно использовать для всего остального.

Изменить 2:

Спасибо за ссылки на различные реализации "push" в Silverlight. Я мог бы поклясться, что сокеты были изъяты из Silverlight, но нашел ссылку на Silverlight 3 на основе ответа ниже. В любом случае это не было большой проблемой для меня, и я не тратил много времени на исследования, поэтому я редактирую это из исходного текста. Независимо от того, поступают ли обновления в опросах или в виде push-уведомлений, общие проблемы с дизайном все еще существуют. Приятно знать, что у меня есть варианты.

Редактировать 3. Последующие действия по push-технологиям.

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

Реализация сокетов в Silverlight нарушена по нескольким причинам. Похоже, что в нашем сценарии это будет бесполезно, поскольку веб-сервер может находиться за любым клиентским брандмауэром, который не разрешает нестандартные порты, а сокеты Silverlight не будут подключаться на 80, 443 и т. Д.

Я все еще думаю об использовании подхода WCFduplex в некоторой степени, но похоже, что ответом будет опрос.

Редактировать 4. Нашел шаблон, решающий половину моей проблемы

Я нашел этот шаблон (PDF), который иллюстрирует использование шаблона итератора для получения страниц данных с сервера и представления их в виде простого итератора. В мире .Net я предполагаю, что это будет реализовано как IEnumerable (примеры кода находятся на Java и Oracle SQL). Особый интерес для меня вызвала асинхронная предварительная выборка страниц, в основном буферизация набора результатов на стороне клиента. С объектами 5k все не умещается на экране сразу, поэтому я могу использовать стратегию не получать все сразу, но при этом скрывать детали реализации из пользовательского интерфейса. Основные объекты, которые будет извлекать приложение, находятся в базе данных, тогда для полного заполнения этих объектов требуются другие поисковые запросы. Эта методология кажется хорошим подходом для быстрой передачи некоторых данных клиенту.

Теперь я подумываю использовать этот шаблон + какой-то шаблон прокси-объекта, который прослушивает дельты в наборе результатов и соответственно обновляет объект. Здесь можно воспользоваться парой стратегий. Я мог бы заранее загрузить все данные, а затем отправить дельты изменений (для этого, вероятно, потребуется дополнительный код в подсистемах для уведомления об изменениях). Возможно, это мой первый подход. Я все еще ищу. Спасибо за все идеи.


person Jason Jackson    schedule 03.11.2009    source источник
comment
Очень интересная проблема! Я бы с удовольствием когда-нибудь поработал над чем-то подобным ... Могу я спросить о деталях того, что вы строите?   -  person andyp    schedule 04.11.2009
comment
Это проприетарная система, которую мы еще не выпустили (очевидно), и из-за этого я запутал некоторые детали. В общем, это способ отслеживать, что происходит в приложении, которое управляет большим набором устройств (текущая самая большая установка около 5k). Этот инструмент позволит администратору посмотреть на сеть устройства в целом и выявить проблемы, а затем принять меры в проблемных областях. Извините, я не могу уточнить детали. Когда мы выпустим, я могу вам это показать!   -  person Jason Jackson    schedule 04.11.2009


Ответы (8)


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

person monksy    schedule 03.11.2009
comment
Я думаю, что этот общий шаблон может работать, но моя проблема заключается в том, чтобы немного больше болтов и гаек. Тем не менее, это дает мне идею хранить все объекты в кэше где-нибудь на сервере и обновлять их там, а затем предоставлять дельты для прокси, сидящих на клиенте, когда клиент опрашивает ... - person Jason Jackson; 04.11.2009
comment
Чтобы быть более понятным, прокси в этом случае по своей природе должен быть отключен и, следовательно, должен сохранять какое-то состояние. Я не уверен, что лучше всего использовать для обновления или начальной загрузки. Я обсуждал проблему с коллегами, и идея заключалась в том, чтобы вывести объект на сервер с использованием шаблона репозитория / фабрики, и этот объект будет действовать как прокси, аннулируя свои собственные данные и вызывая обратно в репозиторий (и, следовательно, на сервер) на регулярной основе. цикл. - person Jason Jackson; 04.11.2009

2 предложенных решения могут быть

1) сожмите вашу коллекцию и распакуйте ее после передачи.

2) Используйте шаблон «Легковес + прокси».

person Buzz    schedule 04.11.2009
comment
У меня была опечатка - приложение будет загружать около 5000 (5k) объектов, а не 5000k объектов. Я уже загрузил такое количество объектов в память, и Silverlight отлично с этим справляется. Я подумываю использовать какую-нибудь версию шаблона прокси, но легковес не сильно мне здесь помогает. - person Jason Jackson; 04.11.2009
comment
Я действительно в конечном итоге использовал своего рода легковес, используя bean-компоненты вместо того, чтобы обслуживать графы богатых объектов в Silverlight. - person Jason Jackson; 17.11.2009

Интересно, можно ли вообще уменьшить объем данных, поступающих на экран клиента? В любом случае вы не можете увидеть сразу 5 000 точек данных. И если вам нужно прокрутить для поиска важных вещей, подумайте о том, чтобы для начала отфильтровать неважные. Рассмотрим некоторые варианты дизайна пользовательского интерфейса (приборная панель и элементы типа датчика), чтобы пользователь видел только проблемные места. Затем они могут углубиться в детали и предпринять необходимые действия.

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

person Doug L.    schedule 05.11.2009
comment
Пользовательский интерфейс должен быть чем-то вроде интерфейса Google Maps, поэтому нам определенно нужны все отображаемые точки данных. Вы правы, и я думаю о загрузке данных с экрана в последнюю очередь или о ленивой загрузке. - person Jason Jackson; 06.11.2009

Здесь я нашел статью, которая, кажется, объясняет, как создавать сокеты в Silverlight 2 Silverlight 2 и System.Net.Sockets.Socket

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

Здесь руководство по каналу 9 Silverlight с использованием сокета

Я надеюсь, это поможет

person FrenchData    schedule 03.11.2009
comment
Я довольно много исследовал сокеты в Silverlight. Есть некоторые серьезные ограничения, которые мешают мне их использовать. Одно ограничение заключается в том, что существует очень маленький диапазон портов, в котором они будут работать, что мне кажется глупым. - person Jason Jackson; 17.11.2009

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

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

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

person philfreo    schedule 04.11.2009

Если я правильно понял, здесь действительно две проблемы:

  1. Состояние системы представлено данными, поступающими из нескольких источников данных. В результате запрос состояния обходится дорого.
  2. Объем данных, описывающих состояние системы, велик. В результате запрашивать все данные, описывающие состояние, дорого.

Стандартные шаблоны для решения этих проблем заключаются в том, чтобы ввести средний уровень и использовать дельты для обновления состояния. Например.:

  1. Ясно, что вы не хотите, чтобы ваши клиенты Silverlight напрямую общались с серверными системами. Это не только невозможно, но и очень неэффективно, поскольку каждый клиент может запросить один и тот же источник данных о своем состоянии. Чтобы избежать этого стандартного решения, необходимо ввести средний уровень, который объединяет данные, поступающие из всех внутренних источников данных, а также предоставляет общий интерфейс для клиентов. В результате внутренние источники данных будут опрашиваться только по мере необходимости (может быть настроено для каждого источника данных на среднем уровне), а также клиентам не придется иметь дело с особенностями этих поддерживаемых источников данных. Кроме того, вы можете реализовать индексацию данных на среднем уровне на основе запросов, наиболее распространенных для клиентов.

  2. Предполагая, что каждая запись будет иметь идентификатор, клиент должен запрашивать только дельты с момента последнего обновления. Один из многих шаблонов - использовать временную метку. Например. при инициализации клиент запрашивает состояние системы, а средний уровень отправляет это состояние с отметкой времени. Когда клиенту необходимо обновить определенные записи, он предоставляет идентификаторы в запросе и отметку времени последнего обновления. Поэтому средний уровень будет отправлять только изменения с последней отметки времени и только для запрошенных идентификаторов. Если объект имеет 15 свойств, и только 3 из них были изменены с момента последней отметки времени, то обновление будет содержать только значения этих 3 свойств.

Что касается push vs. poll - push автоматически не является лучшим решением. На самом деле все сводится к вопросу о компромиссе между частотой обновления клиента и объемом трафика между клиентом / средним уровнем. Например. если изменение состояния происходит часто, но редко (например, влияет только на несколько свойств за раз) и нет необходимости немедленно обновлять состояние клиента, клиент может предпочесть, чтобы изменения накапливались, а не получали каждое обновление, поэтому опрос будет предпочтительнее.

person PL.    schedule 04.11.2009
comment
Я согласен с тем, что отслеживание дельт на среднем уровне будет иметь решающее значение для производительности этого приложения. У нас действительно есть средний уровень, очень похожий на то, что вы описываете в пункте 1, но в основном он не имеет гражданства. - person Jason Jackson; 04.11.2009

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

person andyp    schedule 03.11.2009
comment
Я думал об этом, но на самом деле это не толчок (хотя, вероятно, это сработает) и на самом деле не решает мою проблему дизайна. Серверная система не знает, что обновления готовы, пока не запросит подсистемы, что в любом случае означает опрос на стороне сервера. Я могу кэшировать результаты на сервере, чтобы ускорить его ... спасибо за ссылку. - person Jason Jackson; 04.11.2009
comment
Продолжение: я гораздо больше читал об этом дуплексном классе опроса. Похоже, у него настоящие проблемы с масштабированием. - person Jason Jackson; 17.11.2009

Я проголосовал за пару хороших ответов, но нашел решение с некоторыми изменениями в серверных данных и новым способом получения данных из Silverlight. Вот что делается для решения этой проблемы:

  1. Я использую beans для представления этого большого графа данных. Это удалило много передачи XML. В любом случае меня интересует только часть данных, хотя это довольно значительная часть. Сглаживая данные в bean-компонент, я думаю, что сократил размер сериализованного объекта примерно до 20-25% от исходного графа объекта.
  2. Почти все данные на бэкенде теперь будут иметь поле, когда оно было изменено в последний раз. Я смог получить это для всех больших данных. Есть несколько фрагментов данных, в которых этого не будет, но с его помощью были решены реальные проблемы с производительностью запросов и агрегацией данных. В качестве общего решения для других, похоже, это довольно просто реализовать в ряде СУБД.
  3. Я пишу новые API для получения данных, которые были обновлены после указанного DateTime. Это позволяет мне запрашивать только новые и измененные объекты из серверной системы (это веб-служба, вызывающая эти API, а Silverlight вызывает веб-службу).
  4. Обобщите изменения в веб-службе и определите, изменилась ли часть дейтаграфа. Для простоты я просто отправляю весь датаграф, если что-то изменилось. На самом деле это было сложнее всего понять. У части датаграфа могло быть новое обновленное время, но основной объект графика не был обновлен. В итоге мне пришлось написать API-интерфейсы для поиска изменений подобъектов, а затем API-интерфейсы для поиска корневых объектов на основе этих подобъектов (если они были изменены). Граф объектов может быть возвращен с корневым объектом (и фактически большей частью графа объекта), который не обновлялся с момента последнего опроса. Логика веб-службы запрашивает небольшое количество изменений, поэтому, хотя запросы не из дешевых по отдельности, они потенциально могут выполняться только несколько раз за опрос. Даже в очень больших установках нашего продукта этот цикл запроса будет выполняться только 10 или 20 раз за цикл опроса (см. О моем решении для опроса ниже). Хотя наши системы очень динамичны, не так меняется за 30 секунд. Вызов веб-службы, который обрабатывает все это, реагирует на вызов начальной загрузки так же, как и на опрос. Все, что его интересует, - это получение данных более свежих, чем заданное время.
  5. Я написал коллекцию, унаследованную от ObservableCollection, которая обрабатывает запросы и опросы. Клиентский код, использующий эту коллекцию, предоставляет делегата, который запрашивает данные. Дата возвращается асинхронно и в страницах. Я еще не остановился на размере страницы. Он продолжает запрашивать страницы до тех пор, пока сервер не вернет страницу, размер которой меньше максимального размера страницы. В коллекции также предоставляется информация о том, как определить последнюю дату самого нового объекта в коллекции. Он периодически опрашивает обновления, которые новее, чем самый новый элемент в коллекции. На самом деле эта «последняя дата» на самом деле является объектом, содержащим несколько дат различных частей исходного графа объектов. Если элемент возвращается с сервера, который существует в коллекции, элемент в коллекции обновляется с помощью этих возвращенных данных. Я сделал это вместо того, чтобы вставить новый элемент и удалить старый, потому что он работает в большем количестве ситуаций с привязкой к данным.

Этот шаблон можно улучшить. Я мог отправлять в Silverlight только дельты для изменений. Я все еще мог бы попытаться использовать какую-то технологию push. Но это решение дает мне один вызов веб-службы, который может возвращать данные для различных случаев. Опрос также очень прост, и извлечение данных выполняет только одна вещь. Движущихся частей не так много. Это обрабатывает изменения состояния объекта как во время начальной загрузки данных, так и во время опроса с помощью одного и того же механизма. Это тоже хорошо масштабируется. Первоначальный вызов кажется самым дорогостоящим, а последующие вызовы выполняются все быстрее и быстрее. Я бы предположил, что это связано с тем, что данные, оставшиеся на сервере, становятся все меньше и меньше с каждым проходом.

У меня все еще есть один вопрос о моей реализации этого, что Я разместил здесь.

Спасибо за все предложения. Хотя я не прислушивался ко всем советам, несколько идей либо напрямую помогли мне, либо заставили меня задуматься о другом пути, как заставить это работать.

person Jason Jackson    schedule 17.11.2009
comment
Не могли бы вы прояснить / объяснить, что вы имеете в виду под бобами. - person Buzz; 08.12.2009
comment
Бин - это общий термин для постоянного класса, который предназначен для использования пользовательского интерфейса. Стандартные классы бизнес-модели / модели могут быть громоздкими для использования пользовательского интерфейса, поэтому компонент заполняется их значениями и используется пользовательским интерфейсом. В моем случае бизнес-уровень на сервере имел множество объектов модели с довольно богатыми графами объектов. Я перевожу их в beans для использования Silverlight. - person Jason Jackson; 09.12.2009