Continuando com a saga de siglas, encontrei de maneira simplista a versão oposta do ACID, o BASE. Dizemos que é a versão oposta por conta de que os pontos focados por esse paradigma são totalmente diferentes do que o ACID tem como proposta, sem enrolação, vamos para as explicações.
Table of contents
O que é
Dizemos que ele é a versão oposta do ACID por conta de que o modelo do BASE é focar na disponibilidade dos dados, ou seja, em detrimento da consistência dos dados, não iremos falhar a transação feita pelo usuário e sim iremos disponibilizar algum dado inconsistente por algum tempo. Agora explicando o que cada letra significa.
B
Basically available ou basicamente disponível, tem como premissa que cada request vai receber uma response, podendo ela não estar 100% atualizada. Então decidimos retornar respostas temporárias ou dados antigos com o objetivo de sempre retornar uma informação.
S
Soft state ou Estado flexível, tem como premissa que os dados podem mudar com o tempo, mesmo sem nenhuma nova operação do usuário. Concordo, meio viagem isso, mas a ideia em si é que você em algum momento pode estar vendo uma informação X e logo depois pode estar vendo informação Y, isso acontece porque os bancos estão sincronizando as informações, um bom exemplo disso é esse que tem no artigo do site da AWS, ele diz
Por exemplo, se os usuários editarem uma publicação nas redes sociais, a alteração poderá não ser visível para outros usuários imediatamente. No entanto, mais tarde, a postagem é atualizada sozinha (refletindo a alteração mais antiga), mesmo que nenhum usuário a tenha acionado.
A ideia geral é que uma transação foi feita e, com o tempo, os nós dos bancos vão ser sincronizados com essa informação atualizada.
E
Eventual Consistency ou Consistência Eventual, isso diz que em algum ponto os dados vão estar consistentes, no geral, a propagação da atualização da informação vai ser feita de forma async, destacando aqui, não existindo garantia de quando, mas ela vai.
Na prática
Vamos ver agora na prática como funcionariam essas siglas. Primeiro, vamos utilizar o banco Cassandra via Docker por ser mais prático, então vamos criar os seguintes cenarios:
docker run -d \
--name cass1 \
--hostname cass1 \
--network cassandra-net \
-e CASSANDRA_CLUSTER_NAME=Lab \
-e CASSANDRA_SEEDS=cass1 \
-e MAX_HEAP_SIZE=512M \
-e HEAP_NEWSIZE=100M \
cassandra:5.0
docker run -d \
--name cass2 \
--hostname cass2 \
--network cassandra-net \
-e CASSANDRA_CLUSTER_NAME=Lab \
-e CASSANDRA_SEEDS=cass1 \
-e MAX_HEAP_SIZE=512M \
-e HEAP_NEWSIZE=100M \
cassandra:5.0
docker run -d \
--name cass3 \
--hostname cass3 \
--network cassandra-net \
-e CASSANDRA_CLUSTER_NAME=Lab \
-e CASSANDRA_SEEDS=cass1 \
-e MAX_HEAP_SIZE=512M \
-e HEAP_NEWSIZE=100M \
cassandra:5.0
Vamos entrar agora no cass1:
docker exec -it cass1 cqlsh
Após isso, vamos criar um Keyspace dentro:
CREATE KEYSPACE teste
WITH replication = {
'class':'SimpleStrategy',
'replication_factor':3
};
Entre nele:
USE teste;
Crie uma tabela:
CREATE TABLE contas ( id UUID PRIMARY KEY, nome TEXT, saldo INT );
Insira um dado nela:
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Fulano', 1000);
Vamos buscar o valor da tabela:
SELECT * FROM contas;
O resultado esperado:
id | nome | saldo
--------------------------------------+--------+-------
babb3e16-e2ae-4a87-8435-c0dd09897042 | Fulano | 1000
Estando tudo ok, vamos simular uma queda:
docker stop cass3
Usando o comando abaixo, vamos ter algo informando o que está UN (em pé) e DN (desligado):
docker exec -it cass1 nodetool status
Após o comando rodar, o cass3 vai estar mostrando com DN (desligado), vamos inserir agora outro dado:
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Ciclano', 1000);
Vamos ver se a informação foi salva com sucesso:
SELECT * FROM contas;
O resultado é:
id | nome | saldo
--------------------------------------+---------+-------
babb3e16-e2ae-4a87-8435-c0dd09897042 | Fulano | 1000
9461234c-9458-44aa-be0d-3310a14a0944 | Ciclano | 1000
Com isso, validamos o princípio de Basically Available, que mostra que o sistema continua aceitando operações mesmo com parte do cluster fora. Para simular o cenário do Eventual Consistency vamos desligar novamente o cass3:
docker stop cass3
Acessar o cass1:
docker exec -it cass1 cqlsh
Inserir diversos dados:
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Alice', 1000);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Bruno', 1500);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Carlos', 2000);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Daniel', 2500);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Eduardo', 3000);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Fernanda', 3500);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Gabriela', 4000);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Henrique', 4500);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'Isabela', 5000);
INSERT INTO contas (id, nome, saldo)
VALUES (uuid(), 'João', 5500);
Veja quantos dados foram inseridos:
SELECT COUNT(*) FROM contas;
O retorno esperado é:
count
-------
12
Liguem novamente o cass3:
docker start cass3
Acessem o cqlsh do cass3:
docker exec -it cass3 cqlsh
Acesse o keyspace teste:
USE teste;
Veja a quantidade de dados tem no cass3:
SELECT COUNT(*) FROM contas;
O retorno esperado é:
count
-------
12
Esse retorno valida a ideia do Eventual Consistency, pois vimos que mesmo com o cass3 desligado, após a gente ligar de novo, vemos que os dados ficaram consistentes.
Obs: Para validar o Soft State poderíamos simular usando TTL, fazendo com que registros com tempo de expiração desapareçam e mudem com a sincronização.
Conclusão
Com esse estudo conseguimos ver como funciona BASE e por que ele é considerado o "inverso" do ACID, e principalmente, quais pontos principalmente ele quer resolver, que é com relação à disponibilidade do serviço ao invés de consistência de dados.
Top comments (0)