Stateful Processing
O lab kafka-streams-state agregou payment.validated por userId num state store persistente RocksDB chamado user-payment-stats-store e publicou UserPaymentStats em user.payment.stats.
Materialization e ownership
Cada key pertence à task da partition correspondente. A aplicação não alterou a key. A consulta HTTP de application.server expôs o estado materializado da instância que era owner daquela key. O runtime registou state-update com key, contagem e total.
Changelog e restore
O store local é uma materialização acelerada, não a fonte única de recovery. Kafka Streams criou um changelog compactado para o store. Depois de apagar o estado local, a task restaurou os valores a partir do changelog; o log registou State store ... initialized from checkpoint.
RocksDB local → rápido para queries
Kafka changelog → durable para restore
input offsets → posição de processamento
Failover e standby
Com duas instâncias, as tasks foram distribuídas pelo group. Após kill -9 da instância principal, o survivor assumiu as partitions e respondeu a uma nova query sem perda observada. Uma segunda execução com num.standby.replicas=1 criou standby tasks; isso reduz o replay necessário, mas não remove o custo de recuperação nem substitui a réplica Kafka.
ALO stateful
No ensaio kafkapay-user-payment-stats-alo-state-v1, o aggregate foi aplicado novamente após um crash entre output e commit. A sequência observada para o marcador foi count=3, depois replay count=4 e count=5. O estado final foi limpo até LAG=0; o valor final não foi usado como happy path.
Métricas e limites
Foram observados runtime metrics de state store, cache, restore e consumer lag. Cache zero foi usado nas provas de crash para tornar a janela observável. Interactive Queries só respondem com ownership/metadata corretos e não são uma base de consistência externa.