|
Solutia optima pentru aplicatie distribuita.
Last post 10-29-2008, 2:24 PM by fgbogdan. 24 replies.
-
10-06-2008, 1:46 PM |
-
fgbogdan
-
-
-
Joined on 09-27-2008
-
Timisoara
-
db_datawriter
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
5-95 ... mda ... in momentul in care se mareste numarul de servere raportul se va modifica prin mecanismul pe care il propun.
Stiu ca este complicat (altfel ... fara suparare) era un simplu addon la sql server si nu ne mai bateam niciunul capul.
Sunt convins ca nu o sa pot sa ajung la o solutie in care sa pot pune oricate servere ... dar daca ajung sa fac o implementare cu 3 in inel ... m-am scos.
Cand o sa mai am timp de "experimentari" o sa definitivez si partea de offline si o sa va prezint solutia completa.
conditia aia de while ... mi-a furat-o clipboardul ... care nu vrea sa scrie (mai mic)(egal)(coada de maimuta)LastColumnID
www.fagadar.ro
|
|
-
10-06-2008, 3:13 PM |
-
rremus
-
-
-
Joined on 11-16-2006
-
-
sysadmin
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
Nu cred ca am inteles care sint avantajele sa pui serverele in inel. Potzi sa le explici?
http://rusanu.com
|
|
-
10-06-2008, 4:44 PM |
-
fgbogdan
-
-
-
Joined on 09-27-2008
-
Timisoara
-
db_datawriter
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
pai ... decat sa se sincronizeze fiecare cu fiecare, asa o sa fie o directie de sincronizare. Ceea ce ziceam si la inceputul postului. Din punct de vedere al numarului de operatii e acelasi lucru in online dar in offline se complica treaba.
www.fagadar.ro
|
|
-
10-06-2008, 5:53 PM |
-
rremus
-
-
-
Joined on 11-16-2006
-
-
sysadmin
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
Dar in felul asta introduci artificial puncte de failure. Daca in 'mesh' un nod e cazut, el numai primeste updaturile pina nu revine online. In cerc, daca un nod e cazut blocheaza pe toata lumea eventual (toate updaturile se opresc la el).
Ca sa intzeleg mai bine, ceea ce propui tu este asa: S1 primeste un update. In trigger el se conecteaza la un linked server S2, promoveaza tranzactia locala in DTC, apoi updateaza remote S2. Batch-ul din S1 este blocat asteptind rezultatul de la linked server. S2 face update, apoi ruleaza trigger-ul sau. In trigger se conecteaza la linked server S3, adauga si pe S3 la DTC-ul care-l are cu S1 face update-ul pe S3. Batchul de pe S1 este acum blocat asteptind batch-ul de pe S2 care este acuma blocat asteptind batch-ul de pe S3. Si asa mai departe. Sn in trigger-ul detecteaza ca update-ul vine de la S1 si numai apeleaza S1 . Asta pentru, dupa cum sper ca stii, daca Sn se conecteaza la S1 va incerca sa enroleze o noua sesiune in tranzactia existenta, rezultind in eroarea 3910 "Transaction context in use by another session". Deci toate serverele, de la S1 la Sn sin acuma enrolate intr-o tranzactie distribuita coordonata de MSDTC de pe S1 (care a inceput-o). Fiecare server este blocat asteptind-ul pe urmatorul sa termine batch-ul. Sn ruleaza trigger-ul de update (fara sa se conecteze la S1, am explicat de ce), apoi Sn-1 poate continua si tot asa pina controlul se intoarce la S1. Acuma S1 poate termina trigger-ul, statement-ul care a facut update-ul in sfirsit poate sa se termine, si eventula tranzactia sa comita. S1 cere DTC-ului sa comita, DTC-ul face magia in doi pasi si toate serverele comit.
http://rusanu.com
|
|
-
10-06-2008, 6:37 PM |
-
fgbogdan
-
-
-
Joined on 09-27-2008
-
Timisoara
-
db_datawriter
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
toate sunt after (update, insert, delete) ... ca sa nu fie blocaje. Daca reuseste sa faca update pe serverul urmator bine - daca nu logheaza si o sa faca cand o sa fie online (cu un job probabil). NU asteapta unii dupa altii ca atunci ajung la blocaje.
www.fagadar.ro
|
|
-
10-06-2008, 6:44 PM |
-
rremus
-
-
-
Joined on 11-16-2006
-
-
sysadmin
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
fgbogdan:toate sunt after (update, insert, delete) ... ca sa nu fie blocaje. Daca reuseste sa faca update pe serverul urmator bine - daca nu logheaza si o sa faca cand o sa fie online (cu un job probabil). NU asteapta unii dupa altii ca atunci ajung la blocaje.
Am priceput, deci S1 face un update, triggerul lui S1 updateaze pe S2 dar face disable la trigger-ul de pe S2 innainte de update asa incit trigger-ul lui S2 nu se activeaza. Acuma update-ul a ajuns la S2. Cum ajunge update-ul lui S1 la S3? Ignoram pentru moment faptul ca ALTER TABLE cere un lock Sch-M pe tabela, blocind toate operatziile care cer Sch-S (cum ar fi SELECT).
http://rusanu.com
|
|
-
10-06-2008, 8:40 PM |
-
fgbogdan
-
-
-
Joined on 09-27-2008
-
Timisoara
-
db_datawriter
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
nuuuu, nu face disable, ca altfel nu poate sa mearga mai departe. Trebuie sa il lase sa "fire"-uie, Exemplul trimis de mine ste numai pentru 2 servere. Pentru varianta de "inel" trebuie sa gasesc o metoda de oprire - pe care inca nu o stiu. Eventual sa determin care e serverul pe care trebuie sa se opreasca triggerul meu (adica daca plec de pe S(N) ... triggerul sa numai "fire"-uie pe S(N-1).
www.fagadar.ro
|
|
-
10-06-2008, 9:14 PM |
-
rremus
-
-
-
Joined on 11-16-2006
-
-
sysadmin
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
Hai sa mai facem un pic de matematica.
Sa consideram ca un update se executa intr-un timp T, sa zicem intr-o suta de milisecunde. Cind faci un update pe S1, batch-ul executa update apoi asteapta executia trigger-ului. Pe S2 se executa din nou in T, apoi S2 asteapta se se execute pe S3 s.a.m.d. Pe Sn dureaza 100 ms apoi se intoarce. Deci Sn a asteptat 100ms, Sn-1 200ms, pe Sn-2 300 ms s.a.m.d. Timpul total de consumat in sistem de executarea update-ului este suma acestor timpuri, deci N(N+1)/2 * T. A nu se confunda cu durata de executie al update-ului, care este evident T*N.
In SQL Server exista o resursa foarte bine definita, anume numarul de 'worker threads'. Fiecare worker thread poate executa la un moment dat un singur batch (=request). Un worker nu poate abandona un batch pina ce nu il termina. Un bath care asteapta un raspuns de la un linked server este blocat, nu terminat, si consuma un worker. Numarul de worker threads este limitat. Hai sa consideram numarul implicit, 256 de worker threads. Cu acest numar putem determina limita absoluta, ideala, care ne spune cite write-uri putem face in sistem. Cu 3 noduri ai la dispozitie 3*256 workere, care pot executa 7680 de taskuri de cite 100 ms fiecare. Un update in topologia 'inel' consuma 6 astfel de quate de cite 100 ms (1 pe S3, 2 pe S2 si 3 pe S1). Deci in conditzii ideale potzi sa obtzii 7680/6 = 1280 update-uri in sistem intr-o secunda. Cu 5 noduri, ai la dispozitzie 12800 de 'quante' si fiecare update consuma 15, deci potzi spera la 853 de scrieri pe secunda. Cu 20 de noduri ai nevoie de 210 'quante' pentru un update, rezultind un throughput de ~244 operatii pe secunda.
Hai sa consideram topologia mesh, fiecare se conecteaza la fiecare. Un update in aceasta topologie consuma T pe S1, apoi S1 updateaza S2 (=T), apoi updateaza S3 (=T) s.am.d. Timpul total consumat pe toate nodurile este 2N-1 (S1 consuma T*N pentru ca sta sa updateze S2...SN si la asta se adauga N-1 pentru fiecare timp T consumat de S2...S3). Pe 3 noduri un update consuma 5 'quante' (3 pe S1, 1 pe S2, 1 pe S3). Deci potzi scrie 7680/5=1536 operatii, o imbunatarire cu 120% fata de topologia 'inel'. Cu 5 noduri ai nevoie de 9 'quante' si obtii 1422 operatii pe secunda, cu 166% mai bine decit in inel. Cu 20 de noduri ai nevoie de 39 de 'quante' si potzi obtzine un throughput 1313 operatii, care este cu doar 538% mai bine decit in topologia 'inel'.
Se vede de fapt ca numarul de 'worker' threads ales si durata unui update (T) sint irelevante, diferenta vine din formula de timp linear pentru mesh (2N-1) fata de timp patratic ( N(N+1)/2 ) pentru 'inel'. Asta in ciuda faptului ca timpul de 'raspuns' al fiecarui update este identic in ambele topologii (T*N). Dar intr-una din topologii (mesh) exista un singur nod care astepta pe celelate, in timp ce in 'inel' toate nodurile astepta nodurile 'de la dreapta', cu exceptia ultimului.
Asa ca revin la intrebarea originala: care exact sint avantajele toplogiei in inel?
http://rusanu.com
|
|
-
10-07-2008, 8:37 AM |
-
fgbogdan
-
-
-
Joined on 09-27-2008
-
Timisoara
-
db_datawriter
-
-
|
Re: Solutia optima pentru aplicatie distribuita.
intradevar - pus pe hartie e mai avantajos cu mesh - insa ma gandeam ca conditia de oprire ar fi mai simplu de implementat la inel. (folosind eventual o coloana in tabela in care sa fie id-ul sau numele serverului care face update-ul original).
Ca si la retele ... topologia in inel nu e mai avantajoasa - ci poate doar mai simpla pentru intelegerea umana. Vreau sa incerc inainte - si apoi o sa vad practic care imi este mai buna.
www.fagadar.ro
|
|
-
10-29-2008, 2:24 PM |
-
fgbogdan
-
-
-
Joined on 09-27-2008
-
Timisoara
-
db_datawriter
-
-
|
Varianta revizuita - cu stop (un fel de ...)
CREATE TRIGGER [TRIGGER_NAME] ON [dbo].[TBL_NAME]
FOR INSERT, UPDATE, DELETE
AS
DECLARE @strAction AS VARCHAR(10)
DECLARE @STRTABLENAME AS VARCHAR (100)
DECLARE @STRCMD AS NVARCHAR (1000), @STRCMD1 AS NVARCHAR (1000)
DECLARE @Column_Name AS VARCHAR (50), @Type_Name AS VARCHAR (50)
DECLARE @DeletedRows AS INT
DECLARE @InsertedRows AS INT
DECLARE @nIndex AS INT
DECLARE @bContinue AS bit
SET @bContinue = 0
SELECT * INTO #inserted FROM inserted
SET @InsertedRows = @@rowcount
SELECT * INTO #deleted FROM deleted
SET @DeletedRows = @@rowcount
IF @InsertedRows > 0
BEGIN
IF @DeletedRows > 0
SET @strAction = 'UPDATE'
ELSE
SET @strAction = 'INSERT'
END
ELSE
BEGIN
SET @strAction = 'DELETE'
END
-- DELETE
IF 'DELETE' = @strAction
BEGIN
-- daca nu a mai fost apelat
IF ( (SELECT trigger_nestlevel(object_ID('TRIGGER_NAME')) ) BEGIN
SET @STRCMD = ' delete from SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME where ID_NAME in (select ID_NAME from #deleted)'
EXECUTE(@STRCMD)
END
END
-- daca este insert sau update ... determin daca sa merg mai departe ...
-- si prelucrez
IF 'INSERT' = @strAction OR 'UPDATE' = @strAction
BEGIN
-- daca este insert sau update - determin care este valoarea lui SINCFIELD
DECLARE @SERVERNAME AS VARCHAR(20)
SELECT @SERVERNAME = SINCFIELD FROM #inserted
-- daca serverul din campul SINCFIELD este SRVREPL_NAME nu fac nimic
-- daca este NULL inseamna ca este prima data
-- daca e alt server ... merg mai departe
IF '['+@SERVERNAME+']' <> 'SRVREPL_NAME' OR @SERVERNAME IS NULL
BEGIN
-- setez ca o sa fac insert sau update
SET @bContinue = 1
-- daca este null ... il initializez cu numele serverului meu
IF @SERVERNAME IS NULL
BEGIN
UPDATE #inserted SET SINCFIELD = @@servername
END
END
-- daca SINCFIELD nu e NULL
IF NOT @SERVERNAME IS NULL
BEGIN
-- setez in tabela locala campul SINCFIELD pe null
UPDATE TBL_NAME SET SINCFIELD = NULL FROM TBL_NAME, #inserted WHERE TBL_NAME.ID_NAME = #inserted.ID_NAME
END
END
-- INSERT
IF 'INSERT' = @strAction AND @bContinue = 1
BEGIN
-- inserez
SET @STRCMD = ' INSERT INTO SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME select FIELDS_LIST from #inserted '
EXECUTE(@STRCMD)
END
-- UPDATE
IF 'UPDATE' = @strAction AND @bContinue = 1
BEGIN
DECLARE @ColumnID int, @Columns nvarchar(4000), @ObjectID int, @LastColumnID int
SET @ObjectID=(SELECT id FROM sysobjects WHERE name='TBL_NAME')
SET @LastColumnID=(SELECT MAX(colid) FROM syscolumns WHERE id=@ObjectID)
SET @ColumnID=1
WHILE @ColumnID IF (SUBSTRING(COLUMNS_UPDATED(),(@ColumnID - 1) / 8 + 1, 1)) &
POWER(2, (@ColumnID - 1) % 8) = POWER(2, (@ColumnID - 1) % 8)
SET @Columns = ISNULL(@Columns+',','') + COL_NAME(@ObjectID,@ColumnID) + ' = #inserted.' + COL_NAME(@ObjectID,@ColumnID) + ' '
SET @ColumnID=@ColumnID+1
END
-- trebuie sa trimit mai departe si SINCFIELD
SET @Columns = @Columns + ', SINCFIELD=#inserted.SINCFIELD '
-- trebuie sa inlocuiesc IN tabela tinta ... coloana @Column_Name
SET @STRCMD = 'UPDATE SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME SET ' + @Columns + ' FROM SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME C, #inserted WHERE C.ID_NAME = #inserted.ID_NAME'
EXECUTE(@STRCMD)
END
-- curatenie
DROP TABLE #inserted
DROP TABLE #DELETED
conditii ... fiecare tabela trebuie sa aiba campul SINCFIELD care sa accepte NULL si sa nu fie modificat din aplicatie.
ideea e ca la primul apel ea vine null si apoi trece la urmatoarele servere cu numele serverului care a initiat actiunea.
oricum pana la varianta finala care sa contina si offline mai e muuuuuuuuuuuuult ...
www.fagadar.ro
|
|
Page 2 of 2 (25 items)
2
|
|
|