【raft】学习四:重要接口学习 Storage和Node

8 篇文章 2 订阅

前言

在前面的三次学习中,我们学习了一些重要的数据结构,今天主要探讨一下重要的接口,这些接口使得整个raft得以健康地运行。

Node

Node接口承载了应用层与raft协议层的桥梁这个角色,相互传递消息和命令。

// Node represents a node in a raft cluster.
type Node interface {
	// Tick 主要传递应用层的心跳和选举给raft协议层
	Tick()
	// Campaign 致使节点状态转换到候选状态并开始竞选成为领导者
	Campaign(ctx context.Context) error
	// Propose 上传用户的数据给raft协议层,这个接口可以接收额外的消息错误消息 
	//if wait {
	//	pm.result = make(chan error, 1)
	//}
	Propose(ctx context.Context, data []byte) error
	// ProposeConfChange proposes a configuration change. Like any proposal, the
	// configuration change may be dropped with or without an error being
	// returned. In particular, configuration changes are dropped unless the
	// leader has certainty that there is no prior unapplied configuration
	// change in its log.
	//
	// The method accepts either a pb.ConfChange (deprecated) or pb.ConfChangeV2
	// message. The latter allows arbitrary configuration changes via joint
	// consensus, notably including replacing a voter. Passing a ConfChangeV2
	// message is only allowed if all Nodes participating in the cluster run a
	// version of this library aware of the V2 API. See pb.ConfChangeV2 for
	// usage details and semantics.
	ProposeConfChange(ctx context.Context, cc pb.ConfChangeI) error

	// Step 上报消息给状态机,通过context返回错误
	Step(ctx context.Context, msg pb.Message) error

	// Ready 返回当前的状态信息给应用层
	Ready() <-chan Ready

	// Advance 通知该节点的raft,应用层已经保存了上一个Ready,可以返回下一个ready内容了。
	Advance()
	// ApplyConfChange applies a config change (previously passed to
	// ProposeConfChange) to the node. This must be called whenever a config
	// change is observed in Ready.CommittedEntries, except when the app decides
	// to reject the configuration change (i.e. treats it as a noop instead), in
	// which case it must not be called.
	//
	// Returns an opaque non-nil ConfState protobuf which must be recorded in
	// snapshots.
	ApplyConfChange(cc pb.ConfChangeI) *pb.ConfState

	// TransferLeadership 切主,由lead切为transferee 
	TransferLeadership(ctx context.Context, lead, transferee uint64)

	// ReadIndex request a read state. The read state will be set in the ready.
	// Read state has a read index. Once the application advances further than the read
	// index, any linearizable read requests issued before the read request can be
	// processed safely. The read state will have the same rctx attached.
	// Note that request can be lost without notice, therefore it is user's job
	// to ensure read index retries.
	ReadIndex(ctx context.Context, rctx []byte) error

	// Status 返回当前raft的状态
	Status() Status
	// ReportUnreachable 报告当前给与的节点不可达
	ReportUnreachable(id uint64)
	// ReportSnapshot 报告当前的发送的快照信息,谁发送谁接受,成功还是失败,失败原因。
	// reports the status of the sent snapshot. The id is the raft ID of the follower
	// who is meant to receive the snapshot, and the status is SnapshotFinish or SnapshotFailure.
	// Calling ReportSnapshot with SnapshotFinish is a no-op. But, any failure in applying a
	// snapshot (for e.g., while streaming it from leader to follower), should be reported to the
	// leader with SnapshotFailure. When leader sends a snapshot to a follower, it pauses any raft
	// log probes until the follower can apply the snapshot and advance its state. If the follower
	// can't do that, for e.g., due to a crash, it could end up in a limbo, never getting any
	// updates from the leader. Therefore, it is crucial that the application ensures that any
	// failure in snapshot sending is caught and reported back to the leader; so it can resume raft
	// log probing in the follower.
	ReportSnapshot(id uint64, status SnapshotStatus)
	// Stop 停止当前节点
	Stop()
}

Storage

代表Raft日志底层存储模块,保存持久化的数据,它提供了持久化日志相关的接口操作,如果有一个接口方法错误,这个raft实例将无法操作和拒绝参与选举,应用负责清理和恢复这个状态。

// Storage is an interface that may be implemented by the application to retrieve log entries from storage.

type Storage interface {
	// TODO(tbg): split this into two interfaces, LogStorage and StateStorage.

	// InitialState 返回持久化的HardState和ConfState信息。
	InitialState() (pb.HardState, pb.ConfState, error)
	
	// Entries 返回日志片段,包括lo,不包括high.
	Entries(lo, hi, maxSize uint64) ([]pb.Entry, error)
	// Term 返回一条日志记录的任期,这条日志必须在[FirstIndex()-1, LastIndex()]. 
	Term(i uint64) (uint64, error)
	// LastIndex 返回日志记录中的最后一条记录的index
	LastIndex() (uint64, error)
	
	// FirstIndex 返回日志记录中的第一条日志;
	FirstIndex() (uint64, error)
	// Snapshot 返回最近的快照,如果快照临时不可用,应该返回 ErrSnapshotTemporarilyUnavailable, 从而raft知道状态机能够知道Storage 需要一些时间来准备快照,并稍后调用
	Snapshot() (pb.Snapshot, error)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值