This is a blank Quartz installation. See the documentation for how to get started.

ee

增加一些内容

The leader decides when it is safe to apply a log entry to the state machines; such an entry is called committed. Raft guarantees that committed entries are durable and will eventually be executed by all of the available state machines. A log entry is committed once the leader that created the entry has replicated it on a majority of the servers (e.g., entry 7 in Figure 3.5). This also commits all preceding entries in the leader’s log, including entries created by previous leaders. Section 3.6 discusses some subtleties when applying this rule after leader changes, and it also shows that this definition of commitment is safe. The leader keeps track of the highest index it knows to be committed, and it includes that index in future AppendEntries RPCs (including heartbeats) so that the other servers eventually find out. Once a follower learns that a log entry is committed, it applies the entry to its local state machine (in log order).

领导者决定何时将日志条目应用于状态机;这种条目称为已提交条目。Raft算法保证已提交的条目持久存在,并最终将被所有可用的状态机执行。一旦创建该条目的领导者在大多数服务器上复制了它(例如,在图3.5中的第7个条目),该日志条目就算是已提交。这同时也会将领导者日志中所有之前的条目一并提交,包括之前领导者所创建的条目。第3.6节讨论了在领导者更替后应用该规则时的一些微妙之处,并明确了这种提交定义的安全性。领导者会追踪它已知的最高已提交索引,并将该索引包含在未来的AppendEntries RPCs中(包括心跳),以便其他服务器最终也能得知。一旦跟随者得知某个日志条目已提交,它会按照日志顺序将该条目应用于本地状态机。

 
func TestFigure82C(t *testing.T) {
	servers := 5
	cfg := make_config(t, servers, false, false)
	defer cfg.cleanup()
 
	cfg.begin("Test (2C): Figure 8")
 
	cfg.one(rand.Int(), 1, true)
 
	nup := servers
	for iters := 0; iters < 1000; iters++ {
		leader := -1
		for i := 0; i < servers; i++ {
			if cfg.rafts[i] != nil {
				_, _, ok := cfg.rafts[i].Start(rand.Int())
				if ok {
					leader = i
				}
			}
		}
 
		if (rand.Int() % 1000) < 100 {
			ms := rand.Int63() % (int64(RaftElectionTimeout/time.Millisecond) / 2)
			time.Sleep(time.Duration(ms) * time.Millisecond)
		} else {
			ms := (rand.Int63() % 13)
			time.Sleep(time.Duration(ms) * time.Millisecond)
		}
 
		if leader != -1 {
			cfg.crash1(leader)
			nup -= 1
		}
 
		if nup < 3 {
			s := rand.Int() % servers
			if cfg.rafts[s] == nil {
				cfg.start1(s, cfg.applier)
				cfg.connect(s)
				nup += 1
			}
		}
	}
 
	for i := 0; i < servers; i++ {
		if cfg.rafts[i] == nil {
			cfg.start1(i, cfg.applier)
			cfg.connect(i)
		}
	}
 
	cfg.one(rand.Int(), servers, true)
 
	cfg.end()
}
 
 
  • something
  • 这个列表
  • 这是列表 2
    • 这是子列表
    • 这也是子列表