Você está na página 1de 5

horizontal scalling ou sharding:

Aumentar a Carga do sistema, mais dados, de forma horizontal corresponde a


partitionar a carga usando nós.
Vertical scalling seria aumentar a carga na mesma máquina e utilizar o Ram e o CPU
de forma eficiente.

the challenge in providing nonBlocking reads:


assumimos que o snapshot de uma transação T se chama S. É definido por um logical
timestamp ST. Dizemos que um servidor que tenha instalado um snapshot X se e só se
o
servidor já possui todas as transaçõe com snapshot menor, ou seja, aplicou todas as
modificações
referentes a todas as commited transactions com timestamp menor ou igual a X.
Assim que um servidor instale um snapshot Y, não há commmits de transacos com
snapshot Z<Y.

Aqui, o problema principal é garantir a consistencia e a atomicidade, aí o exemplo


dos gajos é bom porque ele
tem que ler ou os dois writes que uma transacao antiga fez ou nenhum deles, de
qualquer
forma tem que manter a consisstencia e a atomicidade de uma transação.

cure:
quando um cliente quer fazer uma transação, o snapshot da transaçao terá que ter no
minimo
todos os timestamps vistos até agora por C. Desta forma, o timestamp vai ser
atribuido
por um coordenador escolhido randomicamente que defenirá o timestamp entre 2
valores:
+ o timestamp mais alto que C já viu
+ o seu próprio (o do coordenador) relógio lógico.
Quando a transação prosseguir será-lhe atribuido um commit timestamp segundo um 2PC
em que todos as partições que guardem valores que T alterou vão sugerir valores
para
esse commit. Escolhe-se o valor máximo destes valores. Não pode haver commit's z<Y
para qualquer servidor
Esse timestamp será guardado nos valores associados ao que a transação escreveu.
Como
o timestamp de commit é maior que o timestamp da transação, fica guardado que para
escrever
esses valores é preciso os items que estavam em S.

wren:
usa o LST e o RST que contem o maior timestamp instalado em todas as particoes da
DC
(de forma local e de forma remota).
E usa também uma client cache para guardar o que um cliente especifico já escreveu
mas
ainda não foi escrito para todas as particoes.
Presumo que a parte de commit seja igual ao do cure porque não aborda isso.

BDT:
Usa os Lst e o RST para calcular as dependencias. à partida só usa estes dois
timestamps.

Bist:
esta merda é o protocolo responsavel por calcular o LST e o Rst.
Todas as particoes vao saber o LST e o RST para o seu DC local.
Elas mandam umas para as outras os seus valores maximos de remote e local
(periodicamente e depois pronto
deve ser usado consensu presumo eu.

HlC:
juncao de physical clocks com logical cloks.
Será o máximo entre o physical clock e o (logical_clok + 1), assim o clock dele
avança
mesmo sem receber eventos/transaçoes o que faz com que o cliente possa dar prune na
sua
cache uma vez que os timestamps já vistos dessa particao estao a aumentar.

availability:
está sempre disponivel. Mesmo que uma Dc remota vá abaixo o que pode impedir o RST
de
ser o correto, ele simplesmente atribui esse RST à transação o que faz com que ela
possa
andar para a frente e mesmo assim proceder à transação. Em caso de read vai ler uma
versão
antiga, em caso dee write deposi terá o seu commit time. Simplesmente no caso do
write
ele acha que precisa de os items que estavam em rst.

metadados
item
+ k (key)
+ v (value)
+ ut (timestamp commit)
+ rdt (remote dependecy time)
+ idt (id transacao que o criou)
+ st (source replica do item)

client
+ idc (current transaction)
+ lst (local timestamp)
+ rst (remote timestamp)
+ hwtc (commit time of last update transaction)
+ WSc (write's client set)
+ RSc (read's client set)
+ WCc (client side cache)

servers
+ n (partition id)
+ m (local DC id)
+ Clock mn (monotonically increasing physical clock)
+ HLC mn (local clock value, hybrid clock)
+ VV mn (vector de HLC's com M entradas, local snapshot installed nesse server)
+ lst mn (local DC lst)
+ rst mn (Local DC rst)
+ prepared transactions (ja propos commit mas ainda nao recebeu valor)
+ commited transactions (ja propos e ja recebeu valor)

operacoes
START
Cliente inicia a transacao ao conectar-se a um coordinator partition.
O cliente manda também o lst e o rst, cujo coordinator, se for caso disso
atualiza os seus próprios valores de lst e rst, para que o cliente
possa ter acesso a dados tão frescos como já viu até agora.
O coordinator gera então o snapshot visivel para T (o seu timestamp). O lst
fica
igual ao que já tinha. O rst ficará igual ao min(rst, lst-1). O rst
obrigatoriamente tem que ser mais baixinho que o lst para que a versao
sempre mais fresca para o cliente vá ver seja a que ele vai escrever mas ainda não
escreveu e pode
ler na sua client cache.
Depois de definir o snapshot visivel. O Coordinator também
gera um identificador único para a transação, aquele que o item guarda.
Coloca T numa private Data structure sua.
Apos receber o reply c atualiza o lst e o rst e retira da
cache qualquer versao com timestamp menor que lst. É garantido ao
cliente que ele pode fazer isto, uma vez que o servidor garantiu que
se houver uma X.ct > lst então a versão que ele vai ler é da cache e
não uma possível remota.

READ
O cliente fornece a serie de keys que quer ler.
Para cada key, para ler, o cliente vai procurar na write-set, read-set
e depois na client cache, por esta ordem. Se um item correspondente a k
é encontrado então é adicionado à série de items para retornar,
assegurando assim o read-your-own-writes e repeatable-reads.
(ele vai ver a read-set porque se já leu um valor de k então vai ler
exatamente o mesmo agora)
Reads que nao possam ser served locally sao enviadas em paralelo
para as particoes correspondentes em conjunto com o snapshot.
Ao receber um read um server atualiza o seu rst e lst se forem
mais pequenos que os do cliente. O server retorna ao cliente, para cadda
k, a versao, dentro do snapshot, mais alta que tiver. Este valor vai
para a read-set.

WRITE
O cliente localmente da buffer dos writes para o seu write-set WSc.
Se uma k que tá a ser escrita já lá estiver então é atualizada, cc
então é inserida.

COMMIT
O cliente manda um commit request para o coordinator com o conteudo
da WSc, o id da transação e o timestamp do commit da sua ultima
transação.
O coordinator vai contactar todos os servidores que estejam
envolvidos com essa data (os cohorts) e manda-lhe o respetivo pedido
de commit.
As particoes (cohorts) vao atualizar os seus HLCs, propor o
commit timestamp e adicionar a transacao a pending list. Para refletir
causalidade os proposed timestamps sao maiores que o timestamp do
pedido e também que o seu hwtc (last transaction commited timestamp)
O coordinator depois escolhe o valor mais alto para tal.
Manda o bicho para todas as partições, limpa o contexto atual. Envia
o commit timestamp para o cliente

APPLYING AND REPLICATING TRANSACTIONS


Periodicamente, os servers vao aplicar as alteracoes provenientes
das transações commited de forma crescente em relacao ao commit time.
O servidor vai aplicar as modificacoes das transacoes que tiverem
um timestamp menor do que qualquer pending transaction (as pending
transactions dao nos um lower bound das transacoes futuras).
Após aplicar as transacoees, o servidor atualiza o seu local
version clock e replilca as transaçoes para as outras DCs.
Quando há mais que uma transação com o mesmo commit time,
as alterações são aplicadas e só após aplicar a última é que é atualizado
o local version clock e as alterações são agrupadas e enviadas numa
única replication message.
Se um servidor não der commit a uma transação por um espaço de
tempo então manda um heartbeat com o current HLC as suas replicas
colegas, assegurando o progresso do RST.

BiST
Periodicamente, as particoes dentro de uma DC trocam os seus version
vectors. O lst é computado como o minimo das local entries. O rst é
computado com o minimo das remotes. As particoes dentro de uma DC
são organizadas em árvore para reduzir os custos de comunicação.

Garbage Collection
periodicamente as particoes dentro de uma Dc trocam o snapshot (visivel
a uma transacao ativa) mais antigo. É calculado o minimo destes valores
para determinar o snapshot mais antigo que ainda é Necessário.
Todas as partições vão fazer um scan as suas keys mantendo
apenas as versoes >= que este timestamp mais antigo, tudo o resto pode
ser eliminado. Porque já não é utilizado para fazer uma transação.

Correctness
Snapshots são causais
Para começar uma transação o cliente dá piggy-back ao seu freshest
snapshot que já viu, para garantir a monoticidade do snapshot visto
por c.
Os commit timestamps refletem a causalidade e o BiST mantem
um lower bound do snapshot instalado por cada particao numa DC.
Se uma chave X está dentro do snapshot de uma transação, então
as suas dependências também estarão, porque:
+ as dependências geradas na mesma DC onde X foi criado tem um
timestamp menor que X
+ dependências geradas numa Remote DC também têm timestamp menor que
o de X.
On top of do spanshot dado pelo coordinator, o cliente aplica
os writes que não estão no snapshot. Estes writes não podem depender
em items criados por outros clientes que estão fora do snapshot visivel
por c. (pode alterar o resultado mas não depender)

Writes são atómicos


Items que forem escritos por uma transacao tem o mesmo commit timestamp
e Rst.
Se uma transação tiver escrito X e Y e houver um snapshot que
contenha X (ou seja, o timestamp da transacao seja maior que o de X)
então também contem Y.

como é que ao meter rst = lst -1 garante que não há versão nenhuma maior do
outro lado?
Eu acho que não garante, apenas faz com que ele leia a que vai escrever e não
a outra.

Você também pode gostar