Има ли шаблон за проектиране за работа с големи масиви от данни в интернет?

Търся модел на проектиране, който обработва големи набори от данни през интернет и извършва периодично актуализиране на тези обекти. Разработвам приложение, което ще показва хиляди записи в потребителския интерфейс едновременно. Освен това, различните свойства на тези обекти са доста преходни и трябва да се актуализират на клиента, за да информира потребителя за променящото се състояние на тези записи в системата. Имам няколко идеи как да подходя към този проблем, но реших, че може да има модел (или модели) на проектиране, който се справя с този тип сценарий.

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

  1. Клиентската страна за това се пише на Silverlight.
  2. Самите обекти не са много големи (около 15 свойства тип стойност и низ), но заявките за всички данни са скъпи. Около 15-те свойства съдържат данни от различни източници; никакъв умен оператор за присъединяване или индексиране няма да ускори заявката. Мисля да попълня само подмножество от свойствата при първоначално зареждане и след това да попълня по-скъпите подробности, докато потребителят увеличава мащаба на дадено групиране от обекти. Помислете за Google Maps, но вместо улици и сгради показва обектите.
  3. Ще мога да огранича частта от хилядите обекти, които се актуализират. Ще ми е необходимо обаче потребителят да може да „намалява“ контекст, който позволява детайлно актуализиране до такъв, който показва всичките хиляди обекти. Предполагам, че актуализирането ще бъде деактивирано отново за обекти, когато напуснат контекст на достатъчно мащабиране.

Идеи как да се справите с целия или част от този проблем? Както споменах, вече обмислям няколко идеи, но нищо, което съм събрал досега, не ми дава добро усещане за успеха на този проект.

Редактиране:

Мисля, че трудните части наистина се свеждат до две неща, за които може да се нуждая от два различни модела/практики/стратегии:

  1. Зареждане на голям брой записи през интернет (~5k).
  2. Поддържане на подмножество от тези обекти (~500) актуализирани през интернет.

Има няколко шаблона за проектиране, които могат да се използват за всичко останало.

Редактиране 2:

Благодаря за връзките за различни "push" реализации в Silverlight. Мога да се закълна, че гнездата бяха извадени от Silverlight, но намерих препратка към Silverlight 3 въз основа на отговор по-долу. Това наистина не беше голям проблем за мен така или иначе и нещо, което не бях прекарал много време в проучване, така че редактирам това от оригиналния текст. Независимо дали актуализациите идват чрез анкети или чрез натискане, общите проблеми с дизайна все още са налице. Хубаво е да знам, че имам опции.

Редактиране 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) Използвайте Flyweight + прокси модел.

person Buzz    schedule 04.11.2009
comment
Имах правописна грешка - приложението ще зареди около 5000 (5k) обекта, а не 5000k обекта. Вече заредих толкова много обекти в паметта и Silverlight се справя добре. Обмислям да използвам някаква версия на прокси модела, но теглото не ми печели много тук. - person Jason Jackson; 04.11.2009
comment
Всъщност в крайна сметка използвах един вид муха, като използвах beans, вместо да обслужвам богатите обектни графики на Silverlight. - person Jason Jackson; 17.11.2009

Чудя се дали бихте могли да намалите количеството данни, отиващи към екрана на клиента, на първо място? Така или иначе не можете да видите 5000 точки данни наведнъж. И ако трябва да превъртате, за да търсите важните неща, помислете за филтриране на неважните неща като начало. Обмислете някои дизайни на потребителския интерфейс (табло за управление и неща от типа на измервателния уред), така че потребителят да вижда само проблемните точки. След това те могат да пробият и да предприемат необходимите действия.

Знам, че не можете да разкривате подробности и направих много предположения и това не е директен технически отговор на въпроса ви - но може би преосмислянето на необходимия поток от данни ще ви помогне да се насочите в по-ефективна посока както за гърба, края и предния край.

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

Като цяло мисля, че отговорът на въпроса ви е, че няма един или повече дизайнерски шаблони, които наистина да решат проблема ви. Вместо това, това е чудесен пример за прилично широкомащабно приложение, което просто се нуждае от много работа по планиране и проектиране.

Когато проектирате, мисля, че ще срещнете някои DPs, които може да ви помогнат на малко ниво, но подробностите за това как трябва да работи това гигантско нещо са по-скоро общ (и интересен) проблем с дизайна.

Може би лекото изясняване на вашите въпроси може да помогне на хората да дадат съвети относно цялостния дизайн на тази система. Също така, след като сте положили малко дизайн/усилия да създадете дизайн на високо ниво за това как това трябва да работи, можете да поискате критики/предложения. Трудно е някой да измисли това изцяло като отговор на въпрос на StackOverflow. :)

person philfreo    schedule 04.11.2009

Ако разбирам правилно, тук наистина има два проблема:

  1. Състоянието на системата се представя от данни, идващи от множество източници на данни. Като резултат запитването за състояние е скъпо.
  2. Количеството данни, които описват състоянието на системата, е голямо. В резултат на това търсенето на всички данни, които описват състоянието, е скъпо.

Стандартните модели за решаване на тези проблеми са въвеждане на средно ниво и използване на делта за актуализиране на състоянието. напр.:

  1. Ясно е, че не искате вашите Silverlight клиенти да говорят директно с бекенд системи. Това не само, че може да не е възможно, но също така е много неефективно, тъй като всеки клиент може да попита същия източник на данни за своето състояние. За да се избегне това стандартно решение е да се въведе средно ниво, което агрегира данните, идващи от всички източници на данни в задната част, и също така предоставя общ интерфейс на клиентите. В резултат на това източниците на бекенд данни ще бъдат запитвани само толкова често, колкото е необходимо (може да се конфигурира за източник на данни в средното ниво), а освен това клиентите не трябва да се справят със спецификите на тези подкрепени източници на данни. Освен това можете да приложите индексиране на данните в средния слой, въз основа на най-често срещаните заявки за клиентите.

  2. Ако приемем, че всеки запис ще има ID, клиентът трябва да поиска само делти от последната актуализация. Един от многото модели е използването на клеймо за време. напр. когато клиентът се инициализира, той изисква състоянието на системата и средният слой изпраща това състояние с клеймо за време. Когато клиентът трябва да актуализира определени записи, той предоставя идентификатори в заявката и времевия печат на последната актуализация. Следователно средното ниво ще изпраща само промени от последното времево клеймо и само за заявените идентификатори. Ако обектът има 15 свойства и само 3 от тях са променени след последния времеви печат, тогава актуализацията ще съдържа само стойности на тези 3 свойства.

Що се отнася до push срещу анкета - 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. Използвам зърна, за да представя тази голяма графика с данни. Това премахна много XML предаване. Така или иначе съм загрижен само за подмножество от данни, въпреки че е доста значително подмножество. Чрез изравняване на данните в зърно мисля, че съм намалил размера на моя сериализиран обект до около 20 - 25% от оригиналната графика на обекта.
  2. Почти всички данни в задната част вече ще имат поле за последната им промяна. Успях да получа това за всички големи данни. Има няколко части от данни, които няма да имат това, но истинските проблеми с производителността на заявките и агрегирането на данни бяха решени с това. Като общо решение за други, изглежда, че това е доста лесно за прилагане в редица СУБД.
  3. Пиша нови API за извличане на данни, които са били актуализирани след предоставен DateTime. Това ми позволява да правя заявки само за нови и променени обекти от задната система (това е уеб услугата, която извиква тези API, а Silverlight извиква уеб услугата).
  4. Агрегирайте промените в уеб услугата и открийте дали част от графиката на данни се е променила. За простота просто изпращам цялата графика с данни, ако нещо се е променило. Това всъщност беше най-трудната част за разгадаване. Част от графиката с данни може да има ново актуализирано време, но основният обект на графиката не е актуализиран. В крайна сметка трябваше да напиша API, за да търся промените на подобектите, а след това API, за да намеря основните обекти въз основа на тези подобекти (ако са били променени). Обектна графика може да бъде върната с основен обект (и всъщност голяма част от обектната графика), който не е актуализиран от последното проучване. Логиката на уеб услугата прави заявки за малък брой промени, така че въпреки че заявките не са евтини поотделно, те потенциално ще се изпълняват само няколко пъти на анкета. Дори при много големи инсталации на нашия продукт, този цикъл на заявка ще се изпълнява само 10 или 20 пъти на цикъл на анкета (вижте за моето решение за анкета по-долу). Въпреки че нашите системи са много динамични, не толкова се променят много за 30 секунди. Извикването на уеб услугата, което обработва всичко това, реагира по същия начин на първоначално извикване на зареждане, както прави анкета. Всичко, с което се занимава, е извличане на данни, по-нови от даден момент.
  5. Написах колекция, която наследява от ObservableCollection, която обработва заявките и анкетите. Клиентският код, използващ тази колекция, предоставя делегат, който отправя запитвания към данните. Датата се връща асинхронно и в страници. Не съм се спрял на размера на страницата. Той продължава да прави повторни заявки за страници, докато сървърът върне страница, която е по-малка от максималния размер на страницата. Колекцията също така предоставя информация как да определите най-новата дата на най-новия обект в колекцията. Проучва периодично за актуализации, които са по-нови от най-новия елемент в колекцията. В действителност тази „последна дата“ всъщност е обект, съдържащ няколко дати на различни части от оригиналната графика на обекта. Ако даден елемент се върне от сървъра, който съществува в колекцията, елементът в колекцията се актуализира с тези върнати данни. Направих това, вместо да вмъкна новия елемент и да премахна стария, защото работи в ситуации, свързани с повече данни.

Този модел може да бъде подобрен. Мога да изпратя само делти на Silverlight за промени. Все още мога да опитам да използвам някаква технология за натискане. Но това решение ми дава едно извикване на уеб услуга, което може да върне данни за различни случаи. Проучването също е много просто и има само едно нещо, което извършва цялото извличане на данни. Няма много движещи се части. Това обработва промените в състоянието на обекта както по време на първоначалното зареждане на данни, така и по време на запитване, чрез същия механизъм. Това също изглежда се мащабира добре. Първоначалното обаждане изглежда най-скъпо, а следващите разговори протичат все по-бързо. Предполагам, че това е така, защото данните, които остават в задната част, стават все по-малки с всяко преминаване.

Все още имам един въпрос относно моята реализация на това, което Публикувах тук.

Благодаря за всички предложения. Въпреки че не се вслушах в всички съвети, няколко идеи или директно ми помогнаха, или накараха ума ми да помисля по различен начин как да накарам това да работи.

person Jason Jackson    schedule 17.11.2009
comment
Можете ли да изясните/обяснете какво имате предвид под боб. - person Buzz; 08.12.2009
comment
Bean е често срещан термин за постоянен клас, който е предназначен за използване на UI. Стандартните бизнес/моделни класове може да са тромави за използване на UI, така че bean се попълва с техните стойности и се използва от UI. В моя случай бизнес ниво на сървъра имаше различни моделни обекти, които имат някои доста богати графики на обекти. Превеждам ги на зърна за консумация на Silverlight. - person Jason Jackson; 09.12.2009