Resumo
Eu criei um cenário com 3 nós onde 1 nó está fora de sincronia com outros nós e quando me conecto a esse nó, vejo que ele está recuperando dados que não deveria porque está lendo os dados de outro nó (I acredito que o nó ao qual estou conectado usando um driver é o nó coordenador).
Não sei o que estou perdendo e por que Cassandra
exatamente estou fazendo isso?
Passos:
- Crie um cluster de 3 nós com configurações padrão e sem autenticação, usando docker e cassandra versão 4.1.5 e usando
CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch
docker run --name cass1 -d -p 19001:9042 --network=casscluster -e CASSANDRA_CLUSTER_NAME=chat -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack1 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_SEEDS="cass1,cass2" -e CASSANDRA_LISTEN_ADDRESS="cass1" -e CASSANDRA_BROADCAST_ADDRESS="cass1" cassandra:4.1.5
docker run --name cass2 -d -p 19002:9042 --network=casscluster -e CASSANDRA_CLUSTER_NAME=chat -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack1 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_SEEDS="cass1,cass2" -e CASSANDRA_LISTEN_ADDRESS="cass2" -e CASSANDRA_BROADCAST_ADDRESS="cass2" cassandra:4.1.5
docker run --name cass3 -d -p 19003:9042 --network=casscluster -e CASSANDRA_CLUSTER_NAME=chat -e CASSANDRA_DC=dc1 -e CASSANDRA_RACK=rack1 -e CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch -e CASSANDRA_SEEDS="cass1,cass2" -e CASSANDRA_LISTEN_ADDRESS="cass3" -e CASSANDRA_BROADCAST_ADDRESS="cass3" cassandra:4.1.5
- Em cada nó, desabilitou a transferência sugerida de yml e nós reiniciados (verificou cada nó para
nodetool statushandoff
ter certeza dehinted_hand_off
que está desabilitado)
nodetool statushandoff
Hinted handoff is not running
- Crie um keyspace com fator de replicação de 3.
create keyspace testak WITH REPLICATION = {
'class' : 'NetworkTopologyStrategy',
'dc1' : 3
};
- Criar tabela e também desabilitar
speculative_retry
(para que ela não leia de outros nós caso a consulta demore muito)
create table testak.mooz
(
userid int,
chatid int,
name text,
primary key (userid, chatid)
);
alter table testak.mooz with speculative_retry = 'none';
- Pare o nó 3
- Inserir no nó 1
insert into testak.mooz (userid, chatid) values (1, 1);
insert into testak.mooz (userid, chatid) values (2, 1);
insert into testak.mooz (userid, chatid) values (3, 1);
insert into testak.mooz (userid, chatid) values (4, 1);
insert into testak.mooz (userid, chatid) values (5, 1);
insert into testak.mooz (userid, chatid) values (6, 1);
insert into testak.mooz (userid, chatid) values (7, 1);
insert into testak.mooz (userid, chatid) values (8, 1);
insert into testak.mooz (userid, chatid) values (9, 1);
insert into testak.mooz (userid, chatid) values (10, 1);
- Iniciar nó 3
- Use cqlsh externo para conectar-se ao nó 3
docker run --name cqlsh --rm -it --network=casscluster nuvo/docker-cqlsh cqlsh cass3 9042 --cqlversion=3.4.6
- Definir consistência um
CONSISTENCY ONE
- Rastreamento ativado
TRACING ON
- Selecione 1 linha
select * from testak.mooz where userid = 1 and chatid = 1;
Como o fator de replicação é 3 e eu tenho 3 nós, espero que todos os nós assumam que possuem todos os dados e não precisam consultar os dados de outro nó, mas ao emitir a consulta várias vezes, vejo que às vezes as solicitações vai para outros nós e realmente recupera dados que não deveria porque o nó 3 tem inconsistência e não possui os dados reais do registro.
Aqui está uma captura de tela mostrando que está recuperando dados de outro nó.
Nota: Na maioria das vezes (~90%) ele não lê dados de outro nó.
Atualizar
Mais tarde eu configurei o nível de log usando nodetool setlogginglevel org.apache.cassandra ALL
e olhei debug.log
, e aqui está o log quando cassandra decide ler dados de outro nó:
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,109 CoordinatorWarnings.java:49 - CoordinatorTrackWarnings.init()
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,110 Dispatcher.java:164 - Received: QUERY select * from testak.mooz where userid = 1 and chatid = 1; [pageSize = 100] at consistency ONE, v=4/v4
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,110 QueryProcessor.java:251 - Process SelectStatement[aggregationSpecFactory=<null>,bindVariables=[],isReversed=false,limit=<null>,..(truncated long log line)
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,111 ReadCallback.java:90 - Blockfor is 1; setting up requests to org.apache.cassandra.locator.ReplicaPlan$SharedForTokenRead@74da23a8
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,111 MessagingService.java:401 - cass3/172.20.0.4:7000 sending READ_REQ to 2781@/172.20.0.3:7000
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,111 AbstractReadExecutor.java:226 - Decided not to speculate as 9223372036854775807 > 5000000
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,122 CoordinatorWarnings.java:80 - CoordinatorTrackWarnings.done() with state {}
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,122 CoordinatorWarnings.java:61 - CoordinatorTrackWarnings.reset()
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:01,122 Dispatcher.java:214 - Responding: ROWS [userid(testak, mooz), org.apache.cassandra.db.marshal.Int32Type][chatid(testak, mooz), org.apache.cassandra.db.marshal.Int32Type][name(testak, mooz), org.apache.cassandra.db.marshal.UTF8Type]
| 1 | 1 | null
---, v=4/v4
Mas quando os dados são lidos do próprio nó, em vez da linha with sending READ_REQ
, vejo esta linha:
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:49,248 EndpointMessagingVersions.java:67 - Assuming current protocol version for cass3/172.20.0.4:7000
TRACE [Native-Transport-Requests-1] 2024-07-18 08:47:49,248 AbstractReadExecutor.java:158 - reading data locally
Atualização2
Executando nodetool getendpoints testak mooz 1
em cass3:
172.20.0.3
172.20.0.4
172.20.0.2
nodetool status testak
:
Datacenter: dc1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 172.20.0.3 227.48 KiB 16 100.0% 2a4a84a4-1894-488a-8661-680cf818384b rack1
UN 172.20.0.4 232.56 KiB 16 100.0% 9ed9d3f6-13e0-424f-bf52-1bd359d8a26e rack1
UN 172.20.0.2 281.54 KiB 16 100.0% 68de8980-ab63-4745-85b1-6b98636ea9af rack1
nodetool describecluster
:
Cluster Information:
Name: chat
Snitch: org.apache.cassandra.locator.GossipingPropertyFileSnitch
DynamicEndPointSnitch: enabled
Partitioner: org.apache.cassandra.dht.Murmur3Partitioner
Schema versions:
629e0d12-c942-3eeb-bce3-5616a291ae90: [172.20.0.4, 172.20.0.2, 172.20.0.3]
Stats for all nodes:
Live: 3
Joining: 0
Moving: 0
Leaving: 0
Unreachable: 0
Data Centers:
dc1 #Nodes: 3 #Down: 0
Database versions:
4.1.5: [172.20.0.4:7000, 172.20.0.2:7000, 172.20.0.3:7000]
Keyspaces:
system_auth -> Replication class: SimpleStrategy {replication_factor=1}
testak -> Replication class: NetworkTopologyStrategy {dc1=3}
system_distributed -> Replication class: SimpleStrategy {replication_factor=3}
system_traces -> Replication class: SimpleStrategy {replication_factor=2}
system_schema -> Replication class: LocalStrategy {}
system -> Replication class: LocalStrategy {}