数据复制基于PacificA
对kafka为了吞吐返回客户端的时候不保证数据已经落盘了,所以后面不管怎么复制写多少个副本都不保证数据落盘持久(全部机器一起挂还是可能会丢数据)
Then it will write the new messages to local disk. On Linux, the messages are written to the filesystem cache and there is no guarantee about when they will be written to disk. Kafka does not wait for the data to get persisted to disk—it relies on replication for message durability.
kafka以partition为单位复制数据。
一些关键的配置:
- unclean.leader.election.enable
false表示leader只会从in-sync里选leader。0.11开始默认false。非leader不保证有最新数据,也就是acks=all的请求只保证发到了in-sync里的副本,如果后面在非in-sync里选leader, 这些没复制到这个副本的数据都会丢。如果in-sync里的副本都挂了,这时只能不可用或者选择在非in-sync里选leader但可能丢一些数据。 - replication.factor
复制个数 - min.insync.replicas
表示最后要insync集合最少要有多少个副本。对于acks=all写成功就表示最少有min.insync.replicas个副本收到了msg
客户端 producer 推数据的时候可以配置acks=all, all表示leader收到后要得到全部in-sync副本的ack才返回客户端成功了。
kafka会维护一个in-sync副本集合,leader会把落后太多的副本从in-sync集合里剔除。
- kafka有没可能存在两个leader同时接受可写的情况(network partition),最后丢一部分数据?
看PacificA论文是用lease来防止同时存在两个leader的,也就是如果zero clock drift是可以防止存在这种情况的。配置都存zk, 修改配置提交zk,版本号递增。leader有可能随时被剔除,其它in-sync副本修改配置成为leader, 但原来但leader还不知道仍然接受请求(如果ack=1他写成功了就返回成功了)。为了防止这种情况,leader会给fellower请求得到一个lease, 比如5s内你保证不去选举成leader, 这样leader只要得到这个lease在一定时间内就可以放心当不会自己已经被剔除成为leader了。
https://cwiki.apache.org/confluence/display/KAFKA/KIP-101+-+Alter+Replication+Protocol+to+use+Leader+Epoch+rather+than+High+Watermark+for+Truncation
https://stackoverflow.com/questions/48825755/how-does-kafka-handle-network-partitions
https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Replication
https://cwiki.apache.org/confluence/display/KAFKA/KIP-101+-+Alter+Replication+Protocol+to+use+Leader+Epoch+rather+than+High+Watermark+for+Truncation
https://stackoverflow.com/questions/48825755/how-does-kafka-handle-network-partitions?rq=1