View
63
Download
0
Category
Preview:
DESCRIPTION
Organizacja dostępu do danych w aplikacjach WWW. Tomasz Kopacz. Architect | Microsoft. Agenda. Definicja problemu Odczyt danych (dane relacyjne) AJAX,RSS i dane Zapis danych „Inne” typy danych Enterprise Library Rozproszona pamięć podręczna ( Velocity ) Uwagi o budowie warstwy DAL. - PowerPoint PPT Presentation
Citation preview
Organizacja dostępu do danych w aplikacjach WWW
Tomasz KopaczArchitect | Microsoft
Agenda Definicja problemu Odczyt danych (dane relacyjne) AJAX,RSS i dane Zapis danych „Inne” typy danych Enterprise Library Rozproszona pamięć podręczna
(Velocity) Uwagi o budowie warstwy DAL
Definicja problemu
Aplikacje WWW - problemy Dużo użytkowników Nieznana liczba zapytań
I częstotliwość zapytań Skalowalność bazy zawsze skończona Użytkownik niezadowolony
Odejdzie, pójdzie do konkurencji, nie kupi Opisze na blogu…
Dane to też pliki, XML, usługi…
„Klasyczna 3 warstwowa aplikacja”
•Przeglądarka (JavaScript + HTML) i serwer WWWWarstwa prezentacji
•Serwer WWW + DLL•Serwer aplikacyjny (WCF)Warstwa logiki
•Serwer WWW + DLL•Serwer aplikacyjny (WCF)
Warstwa dostępu do danych
Cel Podział odpowiedzialności w kodzie Niezależne testowanie Możliwość ponownego użycia
Całości, koncepcji lub komponentów
Wymagania odnośnie DAL Elastyczność Ujednolicone i JEDYNE API; niezależne od
„typu” danych Różne bazy Źródła nierelacyjne; Pliki; kolekcje Konfiguracja i wdrażanie…
Czasami SZYBKOŚĆ/SKALOWALNOŚĆ najważniejsza Wtedy elegancja i elastyczność mniej
istotna
Odczyt(dane relacyjne)
(Podstawy ADO.NET) SqlConnection (OleDBConnection)
Wybór bazy, użytkownika Pula i konsekwencje Opcje (trzeba JAWNIE włączyć):
Asynchroniczne MARS
SqlCommand (OleDbCommand) Niezarządzalny a zarządzalny provider Lokalizacja serwera DB a serwera WWW SQL 200x: User Instance i WWW – zły pomysł
C# 3.0 VB 9.0 Inne
.NET Language Integrated Query
LINQ toObjects
LINQ toDataSets
LINQ toSQL
LINQ toEntities
LINQ toXML
Obiekty
<book> <title/> <author/> <year/> <price/></book>
XMLDane
relacyjne
(Projekt LINQ)
gridCategories.DataSource = from category in db.Production.ProductSubcategory where category.Group==„Żywność” orderby category.ProductSubcategoryID select new { CategoryID = category.ProductSubcategoryID, Name = category.Name };
Proste strony ASP.NET Sposoby wywołań
Stored Procedure ASPX + kod inline; podobnie kreator LINQtoEDM LINQtoSQL
Binding do kontrolek – koszt pomijalny Uwaga na ViewState
Rozmiar strony
01 (Krótko) – przegląd klasycznych opcji zadawania zapytań
Wyniki wydajnościSposób wywołania Czas Do najszybsz.
Procedura składowana 0,766 100%
Kreator, LinqToSQL 0,808 95%
Asynchroniczne ASP.NET (1 SqlDataReader) 1,120 68%
Inline SQL + OLEDB 1,179 65%
Inline SQL + kod zarządzalny 1,247 61%
Kreator, LinqToEDM 1,593 48%
Kreator, SqlDataSource 1,595 48%
Inline SQL + DataSet 1,601 48%
Przewaga SP wzrasta ze „skomplikowaniem” zapytania
Mars a lokalny cache
Sposób wywołania Czas Do najszybsz.
MARS 0,493 100%
Cache w List<int> 0,605 81%
Iteracja po 2 recordsetach, średnia z 10 minut, 3 równoległych użytkowników
Sposób wywołania Czas Do najszybsz.
MARS 27,1 100%
Cache w List<int> 110 24%
Iteracja po 2 recordsetach, średnia z 10 minut, 100 równoległych użytkowników
Sposób wywołania Czas Do najszybsz.
MARS 201 97%
Cache w List<int> 195 100%
Iteracja po 2 recordsetach, średnia z 10 minut, 500 równoległych użytkowników
Typy elementów asynchronicznych w ASP.NET Asynchroniczne ASP.NET poprawia
skalowalność przy dużym I/O Można użyć
Strony asynchroniczne (najlepiej PageAsyncTask) Asynchroniczne handlery HTTP
(IHttpAsyncHandler) Narzędzia w bibliotekach .NET
Asynchroniczne ADO.NET (BeginExecuteReader) Asynchroniczne proxy WebServices (w WCF trzeba
jawnie wygenerować)
Asynchroniczne ASP.NET Jednostkowo strona
MOŻE być wolniejsza
Lepsza skalowalność, ale większe zasoby
PreInit
Init
InitComplete
PreLoad
LoadComplete
PreRender
PreRenderComplete
SaveState
SaveStateComplete
Render
PreInit
Init
InitComplete
PreLoad
LoadComplete
PreRender
Begin
End
PreRenderComplete
SaveState
SaveStateComplete
Render
SynchroniczneAsynchroniczne
Asynchroniczne ASP.NET v 1protected void Page_Load([…]) {if (!IsPostBack) {AddOnPreRenderCompleteAsync( new BeginEventHandler (BAO1), new EndEventHandler (EAO1));AddOnPreRenderCompleteAsync(new BeginEventHandler(BAO2), new EndEventHandler(EAO2));[…]IAsyncResult BAO1 (object sender, EventArgs e, AsyncCallback cb, object state) {cmd1 = new SqlCommand(…);return cmd1.BeginExecuteReader(cb,state);}[…]void EAO1(IAsyncResult ar) { datareader1= cmd1.EndExecuteReader(ar); gv1.DataSource = dr1; gv1.DataBind();}
AddOnPreRenderCompleteAsync Jeden wątek!
Kilka po kolei Nie ma dostępu do
stanu strony Uwaga! Zawsze
kosztem wątków roboczych w puli Coś za coś…
Asynchroniczne ASP.NET v 2protected void Page_Load([…]) {if (!IsPostBack) {RegisterAsyncTask(new PageAsyncTask(new BeginEventHandler(BeginAsyncOperation1),new EndEventHandler(EndAsyncOperation1),new EndEventHandler(Timeout1),null,true));RegisterAsyncTask(new PageAsyncTask(new BeginEventHandler(BeginAsyncOperation2),new EndEventHandler(EndAsyncOperation2),new EndEventHandler(Timeout1),null,true));
ExecuteRegisteredAsyncTasks();
RegisterAsyncTask PageAsyncTask
Dowolna ilość wątków
(IHttpModule) IHttpAsyncHandler
BeginProcessRequest EndProcessRequest
02 Strony asynchroniczne
Porównanie wydajnościAsynchroniczne, AddOnPreRenderCompleteAsync :Minimalny czas odpowiedzi: 30,3 sŚredni: 159 sMaksymalny: 298 s
Synchroniczne:Minimalny czas odpowiedzi: 153 sŚredni: 221 sMaksymalny: 298 s
Przyrost 50 – 950 użytkowników
Przyrost 50 – 950 użytkowników
Asynchroniczne,PageAsyncTask :Minimalny czas odpowiedzi: 9,7 sŚredni: 150 sMaksymalny: 297 s
Porównanie wydajności IIZa duża liczba użytkowników
To kiedy używać DataSet? Możliwości
Offline SZYBKA synchronizacja i ponowne połączenie Porównanie wersji, przesłanie różnic
DiffGram
Scenariusz S+S / SmartClient A nie strona WWW
Uwaga – DataSet i Cache Czasami w warstwie DAL/BLL jako obiekt
pomocniczy
W scenariuszu aplikacji WWW
WCALE
To kiedy używać DataSet?
AJAX, RSS i dane
AJAX (bazuje na XMLHttpRequest) Możliwości
Częściowy rendering strony (UpdatePanel) Obejmuje standardowe kontrolki (nawet Web Parts) Zamienia PostBack na wywołania AJAX-owe
Ajax Control Toolkit / Extendery Web Services zwracające JSON Script Framework
Asynchroniczne po stronie klienta Dane – Web Service; JSON(P)/XML
ASMX dla AJAXKod ASMX:[System.Web.Script.Services.ScriptService]public class ZipCodeService :[…][System.Web.Services.WebMethod]public string[] GetBank(string z)
Strona ASPX:<asp:ScriptManager ID="ScriptManager1" Runat="server"><Services><asp:ServiceReference Path=“BankService.asmx" /></Services></asp:ScriptManager>
Dodatkowy atrybut do normalnych funkcji Web Service
Referencja = automatyczne Intellisense + struktury do wywołania kodu
Też „PageMethods” WCF
Atrybut WebGet i UriTemplate
Wywołanie serwisuBankService.GetBank(“781060[…]7", onCompleted, onFailed);[…]function onCompleted (result){ window.alert(result);}
function onFailed (err, context, methodName){ window.alert(err.get_message());}
Używane XMLHttpRequest
Cross-Domain – problem Rozwiązanie: klasa
proxy po stronie serwera WWW
Zabawy z IFrame... Serializacja XML/JSON Uwaga na duże zbiory
danych…
03 AJAX i dostęp do danych03b RSS jako źródło danych
Zapis
„Zapis normalny” Synchroniczne Zapis asynchroniczny – nie ma sensu Zawsze schemat – request / response
Pokaż stronę po zmianach Scenariusz
„Wyślij formularz” „Dziękujemy za przesłanie formularza”
A najlepiej potwierdzić w jeszcze inny sposób: mail, SMS
Wykrywanie konfliktów Niestety optymistyczny
Ostatni ma rację Rozwiązania
Wersja rekordu w bazie TimeStamp do ViewState
Nie zalecana sesja ViewState „żyje” dłużej i jest po stronie klienta
Niebezpieczeństwo zafałszowania, ale….
Uwaga – przechowując wersje, mechanizmy EDM/LinqtoSql – przydatne
04 Konflikty i „normalny” zapis
Service Broker Problem: duża (za duża) ilość poleceń Rozwiązanie: kolejka
Przechowanie żądań Inne możliwości Service Broker: routowanie
pomiędzy serwerami/bazami danych A wszystko w kontekście transakcyjnym!
Konfiguracja Service Broker1. Schemat komunikatu (typ XML)2. Typ komunikatu (dla Request i Response)3. Kontrakt (jaki komunikat wysyłany a jaki
odbierany)4. Definicja kolejki5. Definicja serwisu (para – kolejka i kontrakt)6. Związanie z kolejką procedury SP wołanej po
przyjściu komunikatu I określenie limitu liczby wywołań
7. Ew. odesłanie informacji zwrotnej
05 Zapis i Service Broker
Długie transakcje Scenariusze: Koszyk; dokument wielostronicowy
(kilka operacji Postback) Rozwiązania
ViewState pomiędzy stronami Ciastko + guid + znakowanie transakcji
Ew. sesja Potem proces „czyszczący”
Problemy
Workflow Foundation Klasa jako pojemnik na gromadzone informacje Odmiana – Page Flow z Web Client Software Factory
„Inne” typy danych(wykorzystując SQL 2008)
HierarchyId Wbudowane metody do manipulacji hierarchiami
Na przykład: GetAncestor , GetDescendant , GetLevel INSERT #Hierarchy VALUES ('Debbie Walker','/1/2/')
Indeksy depth-first i breadth-first Nadal jest to baza RELACYJNA Nie ma typów w Entity Framework / LinqToSql /
DataSet itp…
XML• 2 zastosowania:
- Mapowanie XML <-> relacyjne- Baza „hierarchiczna” w bazie
relacyjnej• Klient:
- SqlXml (System.Data.SqlTypes)- XmlReader z sqlxml.CreateReader()- DataSet – typ pola XPathDocument- Usługa Web itp.
• Typ kolumny/zmiennej- Dokument XML 1.0 lub fragment- Przechowywane:
• Jako LOB (2 GB), binarnie• Zakodowane w UTF-16
- W3CSchema / bez schematu• Ładnie się łączy z SQL!
- Też SP: sql:variable(“@xml”)
• CAST/CONVERT• Indeksy
- CREATE PRIMARY XML INDEX idx_1 ON docs (xDoc)
- Dodatkowe indeksy na wartościach, (VALUE), ścieżkach (PATH), właściwościach (PROPERTY)
• Lax validation (anyType), xs:DateTime…
• XQuery- query(), value(), exist()
• SELECT id, xDoc.query ('for $s in /doc[@id = 123]//section…FROM docs
- let $count :=count($invoice/Items/Item)
- modify() (XML DML)• UPDATE docs SET xDoc.modify('insert
<section num=''2''>…• after (/doc/section[@num=1])[1]‘)
06 XML, parametry i zwracanie wartości
SQL 2008 - FilestreamCREATE DATABASE [MTS2008] ON PRIMARY ( NAME = N'MTS2008', FILENAME = N‘[…] MTS2008.mdf' , […]), FILEGROUP [FileStreamGroup1] CONTAINS FILESTREAM DEFAULT ( NAME = N'Arch3', FILENAME = N'C:\SQL2008ENTRTM\MTS2008' ) LOG ON ( NAME = N'MTS2008_log', FILENAME = N‘[…]' , […])
CREATE TABLE [dbo].[tPictInFilestream]([id] [int] IDENTITY(1,1) NOT NULL,[gid] [uniqueidentifier] ROWGUIDCOL NOT NULL,[name] [nvarchar](50) NOT NULL,[pict] [varbinary](max) FILESTREAM NULL)
INSERT INTO [tPictInFilestream] ([name],pict) VALUES (@name,cast('' as varbinary(max)))
SELECT id,pict.PathName() from tPictInFilestream
FileStream - klient1. Otworzyć transakcję2. Pobrać
GET_FILESTREAM_TRANSACTION_CONTEXT3. Pobrać .PathName() do pliku4. Stworzyć fs=new
SqlFileStream(path, tx, tryb otwarcia)
5. Operacje na fs jak na normalnym strumieniuAlbo (tylko lokalny serwer):3.5 : Przetworzyć ścieżkę z udziału sieciowego na adres lokalny (C:/...)4 – 5: Pracować z normalnymi strumieniami .NETTracimy część transakcyjności!„Tricky” – wersjonowanie; niezalecane (chyba że początkowy wsad danych)
07 FileStream i hostowanie obrazów w serwisie
Enterprise LibraryData
Caching Policy Injection
Zadania Enterprise Library: Zbiór „bloków”
ułatwiających wykonywanie pewnych zadań, tu: Data Access Application Block Caching Application Block Policy Injection Application Block I oczywiście - konfiguracja
Konfiguracja Delta (Environments)
Zmiany Merge do
„nowego” .config Także dla „zwykłych”
wpisów Też linia poleceń:
DAAB - Scenariusze Ułatwienie w warstwie DAL Dodatkowa izolacja od typu źródła
Z dokładnością do składni SQL… Konfiguracja w jednym miejscu Krótszy kod - jednolinijkowce
Naprawdę krótszy! Łatwiej mieć niezależność od bazy
Zwłaszcza – przy używaniu procedur Automat zarządzający czasem życia połączenia
+ Pula (jako mechanizm dodatkowy)
DAAB - Operacje Komunikacja za pośrednictwem ADO.NET:
Używa DBConnection/DBCommand SQL Server, ODBC,OleDBB,OracleClient,SqlServerCe
Operacje: Wywołanie SQL/SP Zwrócenie DataReader, DataSet, XML, wyniku polecenia
Cache metadanych -> SZYBKO DZIAŁA Transakcje
Sensownie używa TransactionScope Bez niepotrzebnej eskalacji do DTC
Aktualizacje Model DataSet/DataAdapter UpdateBehavior UpdateDataset ma paramert updateBatch
Caching Application Block Cel – przechowanie danych w pamięci podręcznej Pojemniki:
Null – pamięć Isolated Storage DAAB (zwykle lokalny SQL)
Zwykle – element ma czas życia ICacheItemExpiration
Własne reguły wygaszania ICacheItemRefreshAction
Co się dzieje gdy element wygaśnie WWW: jest też HttpRuntime.Cache
Policy Injection Block[CachingCallHandler(0, 0, 30)] public decimal GetSavingsBalance(int accountNumber)
Lub
[Tag("MyCache")] public decimal GetSavingsBalance(int accountNumber)
[…]OrderTrans orders = PolicyInjection.Create<OrderTrans>();
„Wstrzykiwanie” funkcjonalności
Modyfikuje tworzenie obiektów Dodaje pewne
„zachowania” za pośrednictwem handlerów: Logging, Validation, Caching…
Reguła określa kiedy handlery są stosowane
08 DAAB i Cache Application Block
Rozproszona pamięć podręczna
Velocity Problem – cache w farmie
Duże witryny Rozwiązanie na dziś
Klaster SQL i specjalna postać danych Replikacja, Service Broker, inne…
Velocity Rozproszony serwer pamięci podręcznej
Skalowalny Replikacja
Zastosowanie: głównie DAL Zakładamy – dane w chmurze
Ujednolicony widok pamięci podr.
Co to Velocity? Rozproszona infrastruktura zapewniająca cache (in-memory)
dla dowolnych typów danych (obiekty CLR, XML, binarne itp.) Łączy„pamięć" pomiędzy maszynami w ujednoliconą
przestrzeń cacheAplikacje klienckie
rozproszone pomiędzy
procesy/maszyny
Klinet widzi cache jako JEDEN obszar
Warstwa Cache rozprasza dane
pomiędzy usługi
Zastosowanie Velocity
Warstwa AppASP.NET, serwis .NET Apps
Warstwa CacheVelocity
Warstwa danychSQL Server, SSDS, itp.
KlientDesktop, Mobilne, itp.
Klient WebAJAX, Silverlight itp.
1. Host- Fizyczne urządzenie hostujące instancję
Velocity.2. Nazwany Caches
- Może obejmować więcej niż jedną maszynę
- Definiowany w pliku konfiguracyjnym
3. Region- Fizyczny pojemnik na elementy- Tworzony automatycznie lub jawnie
4. Element cache- Key, Payload (Obiekt), Tagi, TTL,
Timestamp, wersja
Obiekty w cache VelocitySerwer 2Serwer 3
Cache Host ACache Host A Cache Host BCache Host B Cache Host C Cache Host C Serwer 3
Cache Host DCache Host D
Nazwane cache: Product Catalog
Nazwane Cache : Electronics Inventory
RegionyRegion A
Key Payload Tags Key Payload Tags 121 xxxx “Toy” “Child”
123 yyyy “Toy” “Chair”..
Serwer -> Host Cache -> Nazwany Cache -> Region -> Element cache -> Obiekt
Przykłady kodu VelocityCacheFactory fac = new CacheFactory();
Cache catalog = fac.GetCache("catalogcache");
catalog.Put("toy-101", new Toy("thomas", .,.));
Toy toyObj = (Toy)catalog.Get("toy-101");
catalog.CreateRegion("toyRegion");
catalog.Put("toyRegion", "toy-101", new Toy( .,.));
Toy toyObj = (Toy)catalog.Get("toyRegion", "toy-101");
1. Inicjalizacja
2. Nazwany katalog
3. Włożony element
4. Odczyt
5. Region w cache
6. Zapis do regionu
7. Odczyt z regionu
Typy cache Rozproszona konfiguracja
Partycjonowanie Dane podzielone pomiędzy wszystkie węzły w nazwanym cache
Routing Layer „znajduje” komputer z wartością. Duża pojemność cache
Używany też w celu większej dostępności
Replikacja Dane replikowane po wszystkich węzłach w nazwanym cache Używane do przyspieszenia czasu odczytu
Lokalny cache Cache in-proc Obiekty dla lokalnej aplikacji
Inne możliwości Velocity Integracja z sesją ASP.NET Blokady:
Optymistyczna (wersjonowanie) Pesymistyczna
Spójność cache Silna/synchroniczna Słaba/asynchroniczna (ale szybka)
Dostepność: CTP1 – czerwiec 2008 CTP2 – październik 2008 (PDC) RTM – pierwsza połowa 2009 roku
Budowa DAL
Narzędzia LinqToEdm (ew. LinqToSQL)
Polecam: Entity Framework Query Samples WCF – warstwa komunikacyjna; elastyczny dobór
protokołu (binarny / SOAP / REST) Przydatne słowo kluczowe Var Linq a procedury składowane Wydajność LINQ a „innych” technik:
Czas odczytu/zapisu zależny od ZŁOŻONOŚCI grafu Liczba FK, klucze, relacje itp.
WWW: Utwórz obiekt, pobierz, wyświetl, skasuj LinqToEdm – elastyczne / LinqToSQL – proste
DAL - warto cache
DAL, WCF i cache<endpointBehaviors><behavior name="NewBehavior"> <PolicyInjectionEndpointBehavior /></behavior></endpointBehaviors>[...]<extensions><behaviorExtensions><add name="PolicyInjectionEndpointBehavior" type=„PInjectionBehaviors.PI, PIBehaviors, [...]" />[…][Tag("MyCache")]public News GetNews(int id) {[…]<policyInjection><policies><add name="MyPolicy"><matchingRules><add match="MyCache" ignoreCase="true" type="[...]</matchingRules><handlers><add expirationTime="00:05:00" order="0" type="[...]" name="Caching Handler" />
Cache na poziomie usług – atrybut do metody
Własny „Behavior”
Definicja ApplyDispatchBehavior
Tworzenie przez PolicyInjection.Create
09 Kilka uwag o DALWCF, Policy Injection, Cache
Astoria - DataServices Przeznaczenie – „data-centric application” Sposób postępowania:
Model EDM public class NorthwindService : DataService< NorthwindEntities >
Automatycznie generowana warstwa usług Można też obiekty „ręczne”
Klasa ma: public IQueryable<User> Users I np. obsługa kolekcji, własnych zbiorów itp
Klient Astorii może przekazywać definicję zapytania A nie dane!
Data Services (aka Astoria) - architektura
10 DataServices i „ręczne” dane
Astoria i IQueryable
Podsumowanie Najszybsze – Stored Procedures
Ale wygoda… Enterprise Library – gdy potrzeba „niezależności” od
DB Ale – var + „podmiana” elementów DAL…
LinqToEdm Wystarczająco szybkie Bardzo elastyczne
Dużo technik dodatkowych Cache, Velocity
WCF (i Astoria) potężne narzędzie
© 2008 Microsoft Corporation. Wszelkie prawa zastrzeżone. Microsoft, Windows oraz inne nazwy produktów są lub mogą być znakami towarowymi lub zastrzeżonymi znakami towarowymi firmy Microsoft w Stanach Zjednoczonych i innych krajach. Zamieszczone informacje mają charakter wyłącznie informacyjny. FIRMA MICROSOFT NIE UDZIELA ŻADNYCH GWARANCJI (WYRAŻONYCH WPROST LUB DOMYŚLNIE), W TYM TAKŻE USTAWOWEJ RĘKOJMI ZA WADY FIZYCZNE I PRAWNE, CO DO INFORMACJI ZAWARTYCH W TEJ PREZENTACJI.
Recommended