raft 主备不一致时如何恢复,以及对什么场景使用两阶段,什么场景使用raft协议发表一下个人的理解
raft是用于复制的协议,解决副本问题,2pc是用于分布式事务管理协议
一、raft
3个节点raft 集群,n0(leader ),n1,n2,n0 接写入请求, n0先存储数据,再转发给从节点,大于一半节点都存,集群认可提交,发送成功。
leader 节点接收数据编号为 1,2。定义两个指针,已提交序号(commitedPosition),还有一个已收到客户端数据的序号 recivePosition。各个节点recivePosition:
n0 : 102
n1 : 100
n2 : 101
集群认为已提交序号为 101,因为 n0,n2 都已经收到并存储101这条消息,故向客户端承偌已存储成功的数据为序号为101,换句话说,序号为 102 消息就算丢失,也没关系,没有违背数据丢失的语义,这点很重要。
根据数据不能丢失的语义,通常实现者会将已提交的数据进行持久化,即刷盘到硬盘中。
容许 主备不一致,半数节点存储即成功。没有副作用,用 raft 协议集群,就不是“读写分离”架构,任意时刻,只有 leader 节点能接受读写请求,从节点只从 leader 节点同步数据。
1、n0 节点宕机,集群数据如何保证一致呢?
重新选主,n1,n2 中 n2 会被选择成主,因为它的数据更多,n1从n2处同步数据
2、那什么场景使用 raft 协议呢?
集群数据冗余,保证集群数据一致性,例如 rocketmq dledger 模式,要保证一个复制组数据冗余与一致性,
例如 es 主从分片,kafka同一个分区数据多个副本,即数据冗余场景,多副本,且不是读写分离,因为整个集群只有主节点负责读写场景。(当然 es ,kafka 的分区并不是直接使用raft协议哈)。
二、两阶段提交
实现数据的强一致性,分库分表为例
实例名 Schema 表名
T3306 oms order_01
T3307 oms order_02
一个事务中,向order_01, order_02 各新增一条。此时使用两阶段提交来保证一致性。
协调器 首先向 t3306 t3307 写入一条 PREPARE 的数据,(会写入redo日志),然后再发送commit 或 rollback,然后在 redo 日志中会写入另外一条数据,构成一个整体,都执行成功后即实现一致性。
T3306 T3307 是平等地位,接受请求,即T3306 T3307 数据本身是不相同的,独立存在,而raft协议是用在副本。