SaaSArchitektura Multitenant
Michał MacArchitektMCPD Win Developer, MCITP DBA, Developer
Agenda
Agenda
Długi ogon/SaaSReguły biznesoweRozszerzalność danychPojemnik na dane
Sql Server
Długi ogon
Jak zrealizować ideę długiego ogona w IT?
Najwięksi klienci
$ / Klient
Typowi klienci
Rynek (aktualnie) poza zasięgiemNowy rynek >> aktualny rynek
Co jeśli obniżymy koszt wyprodukowania i dostarczenia oprogramowania?
Za co płaci klient?
Za co płaci klient?
Sprzęt Ludzie Software0
1
2
3
4
5
6
7
Sprzęt u dostawcy: efekt skali
Dostawca może zainwestować w olbrzymie Data-Center
Sprzęt u dostawcy: efekt skali
Microsoft Data Center (Chicago, IL) Koszt inwestycji $500m, wielkość 10 boisk football
SaaS – zyski użytkownika
Nie kupuje sprzętuNie instaluje oprogramowaniaNie ponosi dużego kosztu na starcie
Model abonamentowyReklamy
SaaS – zyski producenta
Ciągłe i stałe przychodyLepsza ochrona własności intelektualnejAktualizacje aplikacji odbywają się centralnie
Za co płaci klient?
Sprzęt Ludzie Software0
1
2
3
4
5
6
7
Za co płaci klient?
Sprzęt Ludzie Software0
1
2
3
4
5
6
7
SaaS – modele dojrzałości
SaaS – modele dojrzałości
SaaS – modele dojrzałości
SaaS – modele dojrzałości
SaaS – modele dojrzałości
3 własności
KonfigurowalnośćMultitenancySkalowalność
SaaS
Przykładowa aplikacja
Założenia
Wymienialne reguły biznesoweRozszerzalny model danychKonfigurowalny interfejsMultitenancy
DEMO
Założenia
Wymienialne reguły biznesoweRozszerzalny model danychKonfigurowalny interfejsMultitenancy
Reguły biznesowe
DEMO
Różne wymagania biznesowe
Total = Quantity * ProductPrice
Stacja benzynowaQuantity = Total / ProductPrice
(z dokładnością do obsługi dzielenia przez 0)
Reguły biznesowe
ReużywalneAutomatyczna detekcja zależności
Expression TreesReguły walidacyjneMożliwość dodawania z zewnątrzProsty tekstowy język – Formula
Antlr + Expression Trees
Rozszerzalność danych
Rozszerzalność danych
RealizacjaSłownikExpandoObject - .Net 4.0
Dynamiczny interfejs użytkownikaMetadane per tenant
Same dane nie wystarczą. Wymagana możliwość używania w regułach biznesowychBaza danych – w następnej części
Warstwa danych
Baza danych
Osobne bazy
Osobne bazy
Prosta rozszerzalnośćProsta strategia backupówBezpieczeństwo, izolacja
Bankowość, branża medycznaWiększe koszty – zużyte zasoby
Auto close może zwiększyć ten limit, ale pogarsza czas dostępu
Premiun approach
Baza danych
Wspólna baza, osobne schematy
Wspólna baza, osobne schematy
Łatwa implementacja i rozszerzalnośćŚredni poziom izolacjiUtrudniony backup/restoreNiższe koszty, bo więcej tenantów na jednej bazieOperacje DDL, które blokują katalog systemowy
Baza danych
Wspólna baza, wspólny schemat
Wspólna baza, wspólny schemat
Najniższe koszty sprzętu per tenantMożliwość dostarczenia drogich mechanizmów wysokiej dostępności po korzystnych cenach.
Problemy z backupe/restoremWiększe koszty produkcji aplikacji
Należy zapewnić bezpieczeństwo, nawet w przypadku nieprzewidzianego błędu
Tenant Data EncryptionTenant View Filter
Możliwość partycjonowania per tenant
Porównanie
Warstwa danych
Realizacja
Wymagania
Framework agnosticTransparentnośćBezpieczeństwo
Ewentualny błąd programisty nie może ujawnić danych innego
Używanie pooli połączeńWydajność
Baza danych
CREATE USER TenantA WITHOUT LOGIN WITH DEFAULT_SCHEMA = Secured;
GRANT SELECT, EXECUTE, INSERT, UPDATE, DELETEON SCHEMA::[Secured] TO TenantA;
Baza danych
CREATE TABLE Products(
ProductId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL REFERENCES Warehouses,
);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL REFERENCES Warehouses,
);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL REFERENCES Warehouses,
);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1),PRIMARY KEY(TenantId, ProductId),Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL REFERENCES Warehouses,
);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1),PRIMARY KEY(TenantId, ProductId),Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL REFERENCES Warehouses,
);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1),PRIMARY KEY(TenantId, ProductId),Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL,FOREIGN KEY ( TenantId, WarehouseId )
REFERENCES Warehouses);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1),PRIMARY KEY(TenantId, ProductId),Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL,FOREIGN KEY ( TenantId, WarehouseId )
REFERENCES Warehouses);
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1),PRIMARY KEY(TenantId, ProductId),Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL,FOREIGN KEY ( TenantId, WarehouseId )
REFERENCES Warehouses);CREATE VIEW Secured.vProductsAS
SELECT ProductId, Name, Price, WarehouseIdFROM ProductsWHERE TenantId = DATABASE_PRINCIPAL_ID();
Baza danych
CREATE TABLE Products(
TenantId INT NOT NULL DEFAULT (DATABASE_PRINCIPAL_ID()),
ProductId INT NOT NULL IDENTITY(1,1),PRIMARY KEY(TenantId, ProductId),Name NVARCHAR(64) NOT NULL,Price DECIMAL(19,4) NOT NULL,WarehouseId INT NOT NULL,FOREIGN KEY ( TenantId, WarehouseId )
REFERENCES Warehouses);CREATE VIEW Secured.vProductsAS
SELECT ProductId, Name, Price, WarehouseIdFROM ProductsWHERE TenantId = DATABASE_PRINCIPAL_ID();
Baza danych
EXECUTE AS USER = 'TenantA';
SELECT * FROM vProducts;INSERT vProducts VALUES('Basketball', 55, 2);
Baza danych
CREATE PROC Secured.GetProductsWithState@State INT
ASBEGIN...END
DEMO
Rozszerzalność Modelu Danych
Rozszerzalność danych
Dodawanie kolumn
Dodawanie kolumn
Tylko osobne bazy/osobny schematProstotaOperacje DDLNie potrzeba metadanych, ale może być trudniejsze do realizacji po stronie aplikacji
Osobne codebase’y
Rozszerzalność danych
Zaalokowane pola
Zaalokowane pola
Predefiniowane polanp. 3 stringi 2 liczby
Niepotrzebne zużycie miejsca, gdy któryś z tenantów nie używa pola
SPARE ColumnsA co gdy tenant potrzebuje 4 stringi?Wariacje:
Trzymanie danych jako string + metadane typu
Skomplikowane, ale podobnego mechanizmu używa SalesForce
Rozszerzalność danych
Klucz wartość
Klucz wartość
Dane trzymane są nie w jednym wierszu, ale w kilku
brak ograniczenia na liczbę dodatkowych pól
Gorsza wydajność, niż w Zaalokowanych polach
występuje dużo randomowych operacji w bazie danych
Rozszerzalność danych
Xml
Xml
Słabe wsparcie narzędzi, np. raportówDobre, gdy konfiguracja jest wymagana na poziomie instancji encjiDobre dla danych „rzadkich”Prosta implementacja
SalesForce
Poza SaaS
PaaS - Platform As A ServiceHaaS - Hardware As A ServiceIaaS - Infrastructure As A Service“Blue Cloud” by IBMSimple Storage Service (Amazon S3),Elastic Computing Cloud (Amazon EC2)Google computing servicesMicrosoft Azure
Podsumowanie
SaaSWymaga obniżenia kosztu produkcji4 modele dojrzałościWyzwania dla architektury:
Konfiguracja – reguły, elastyczny model danychMultitenancy – jedna instancja, wielu klientówSkalowalność
Pytania
Linki
http://www.sztronka.com http://code.google.com/p/businessframework/http://www.salesforce.com/au/assets/pdf/Force.com_Multitenancy_WP_101508.pdfhttp://msdn.microsoft.com/en-us/library/aa479086.aspxhttp://www.antlr.org/